[SWPU2019]Web4
buu上的一分题,说实话这个难度我是不相信它只有一分的
题解
打开是一个登录框,简单测试发现添加单引号会出现一个PHP的报错,而不是MySQL的报错,存在注入点,但不可使用报错注入
测了半天,感觉有关键词屏蔽,但是无论如何返回值就三种,登录成功,登录失败,PHP报错。那想直接查询回显也没机会了,只能盲注,并且登录成功啥也不给呜呜呜。
简单测一下发现select,sleep,or,逗号,大小于号,井号还有些七七八八的盲注需要的东西都给禁用了,但是另一个注释符–还能用,最主要的是回显根本没有帮助,完全不知道后台到底在干什么。
后来拿到源码之后看见了超级过滤select|information|insert|union|ascii|,|like|outfile|join|<|>|and|substr|#|or|\|\||sleep|benchmark|if|&&
最后看wp说是堆叠注入,并且使用预处理将语句变为16进制表示,直接绕过超级过滤
MySQL堆叠注入预处理
思路是输入分号后返回的是登录失败而不是PHP报错,判断能够执行堆叠注入
预处理可以使转换为16进制的MySQL语句被执行1';set @a=0x{0}prepare payload from @a;execute payload--
a的内容用常规时间盲注脚本跑就可以了
注意这里数据是用json格式提交的,记得把数据转换一下json格式
贴一个常见payloadselect if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{0},1))={1},sleep(3),1)
一直注到最后会看见一个叫赵总想要一个女朋友的zip,下载下来就是源码
代码审计
index.php里面指明了Common文件夹里面的内容,只有fun.php有实际内容,写明了对r参数的解析
$r = explode('/', $_REQUEST['r']);
list($controller,$action) = $r;
$controller = "{$controller}Controller";
$action = "action{$action}";
........
$data = call_user_func(array((new $controller), $action));
就是前面半边是controller,后半边是action,如果存在对应的controller和action就调用对应的controller类下的action方法
接下来看controller类,登录类毫无作用,就是返回之前注入时的写死的回显
在basecontroller类中发现函数loadView
public function loadView($viewName ='', $viewData = [])
{
$this->viewPath = BASE_PATH . "/View/{$viewName}.php";
if(file_exists($this->viewPath))
{
extract($viewData);
include $this->viewPath;
}
}
有一句include $this->viewPath;
,且viewPath似乎可控,继续看看。可惜看完了所有loadView函数的调用,它的$viewPath
都是写死的,但是这里还有一句extract($viewData);
如果$viewData
可控,也可以进行变量覆盖
在UserController中发现actionIndex()
函数
public function actionIndex()
{
$listData = $_REQUEST;
$this->loadView('userIndex',$listData);
}
其中的$listData
完全可控,本来想直接覆盖$this->viewPath,后来想起来怎么可能覆盖类的私有成员变量,只得作罢。
那就只能看看我们老老实实包含的页面有什么东西了,userIndex.php就实现了一个功能,返回一个文件的base64编码,而文件路径$img_file刚好可以通过$_REQUEST来覆盖,这样一来我们就能直接获得flag.php的base64编码,获取flag了。
userIndex.php
if(!isset($img_file))
{
$img_file = '/../favicon.ico';
}
$img_dir = dirname(__FILE__) . $img_file;
$img_base64 = imgToBase64($img_dir);
echo '<img src="' . $img_base64 . '">';
小坑点
dirname(__FILE__)
返回的是该文件的目录位置,所以是/var/www/html/View,并且目录没有一个斜杠结尾。所以最后试了半天r=../flag.php
没有回显,又想不出来到底哪错了。。。
感觉吧第二个点引导的东西很直接,也不难,但是开局那个SQL注入的回显真的是恶心死人了,太难了呜呜呜