本题的考点是php的字符串解析特性
首先了解下这个概念:
这是别人对PHP字符串解析漏洞的理解,
我们知道PHP将查询字符串(在URL或正文中)转换为内部$_GET或的关联数组$_POST。例如:/?foo=bar变成Array([foo] => “bar”)。值得注意的是,查询字符串在解析的过程中会将某些字符删除或用下划线代替。例如,/?%20news[id%00=42会转换为Array([news_id] => 42)。如果一个IDS/IPS或WAF中有一条规则是当news_id参数的值是一个非数字的值则拦截,那么我们就可以用以下语句绕过:
/news.php?%20news[id%00=42"+AND+1=0–
上述PHP语句的参数%20news[id%00的值将存储到$_GET[“news_id”]中。
HP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:
1.删除空白符
2.将某些字符转换为下划线(包括空格)
首先根据源码的提示打开另一页面
两份源码都指向要绕过这个WAF(Web Application Firewall web应用防护系统)我有看到一句话说题目是php写的,WAF绕过也一定是PHP写的
那我们用到上面那个知识点构造
在num前添加%20绕过对num的检测
使用scandir()函数+chr()函数绕过代码执行
/calc.php?%20num=var_dump(scandir(chr(47)))
scandir("/")中的 / 被过滤掉了,因此我们使用chr(47)绕过这个过滤
为什么要在num前加一个空格?waf不允许num变量传递字母,可以在num前加个空格,这样waf就找不到num这个变量了,因为现在的变量叫“ num”,而不是“num”。但php在解析的时候,会先把空格给去掉,这样我们的代码还能正常运行,还上传了非法字符。
看到了个flag,利用file_get_contents()进行读取
/calc.php? num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))读取,原本括号中的内容用char()转ascii再进行拼接。
由此得到flag