payload中有一个很关键的地方 num 前面有一个空格,因为题中存在 WAF,对 num 的值进行了校验,直接传 payload,会返回这啥?算不来,于是利用php字符串解析特性绕过 WAF,此时 WAF 检测到的变量名为%20num,不为 num,不进行校验,但php存储的变量名为 num
利用PHP的字符串解析特性PHP将查询字符串(在URL或正文中)转换为内部$_GET或的关联数组$_POST的过程中会将某些字符删除或用下划线代替
如果一个 IDS/IPS 或 WAF 中有一条规则是当 news_id 参数的值是一个非数字的值则拦截,那么我们就可以用以下语句绕过
%20news[id%00 // 这个变量名的值实际存储在 $_GET["news_id"] 中parse_str()通常被自动应用于 get 、post 请求和 cookie 中,对 URL 传递入的查询字符串进行解析
通过如下 fuzz 了解parse_str()如何处理特殊字符
foreach(["{chr}foo_bar", "foo{chr}bar", "foo_bar{chr}"] as $k => $arg) { for($i=0;$i<=255;$i++) { parse_str(str_replace("{chr}",chr($i),$arg),$o); if(isset($o["foo_bar"])) { echo $arg." -> ".bin2hex(chr($i))." (".chr($i).")\n"; } // bin2hex 将字符转为16进制数 } echo "\n"; } {chr}foo_bar -> 20 ( ) {chr}foo_bar -> 26 (&) {chr}foo_bar -> 2b (+) foo{chr}bar -> 20 ( ) foo{chr}bar -> 2b (+) foo{chr}bar -> 2e (.) foo{chr}bar -> 5b ([) foo{chr}bar -> 5f (_) foo_bar{chr} -> 00 () foo_bar{chr} -> 26 (&) foo_bar{chr} -> 3d (=)