PHP字符串解析特性
PHP会将在URL或正文中的查询字符串转换为内部的$_GET
或$_POST
的关联数组。在PHP解析查询字符串的过程中,会将某些字符删除或者用下划线代替,了解这个过程中的具体解析方式有助于我们正确输入查询字符串。
解析方式
这里参考“白帽子黑客坤哥”这位师傅的图片,简洁干净,通俗易懂。
附上链接:
https://blog.csdn.net/2401_84466359/article/details/13925965
在查询字符串头部,空格和“+”会被删除。
在查询字符串中段,空格、“+”、“.”、“[”、“_”,都会被解析为下划线_
在查询字符串末段,空格被删除。
相关CTF题目[NewStarCTF 2023 R!C!E!]
源代码
解题思路
- 以POST方式传递两个参数,第一个参数password是MD5值前缀为“c4d038”的字符串,这里利用脚本爆破后得知为114514
- 第二个参数e_v.a.l用于传递代码,让eval()执行,以此达到执行系统命令的目的。这里我们构造该参数的值为
e_v.a.l = echo `tac /fla\g`
如何构造不是本文重点,不在此赘述。
上传请求后我们发现界面没有变化,原因是 e_v.a.l 中段的“.”被解析为下划线,导致传递的参数名错误。此时我们将参数改为 e[v.a.l 这样中段的“[”被解析为下划线_,而后面的“.”不会被解析,输入正确,得到flag.
所以payload为:
password=114514&e[v.a.l=echo `tac /fla\g`;
我还测试了用加号、点、空格等替换这个下划线,都没有成功,可见这个特性确实比较“特”。