文章插图
前言我们知道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.将某些字符转换为下划线(包括空格)
User inputDecoded PHPvariable name%20foo_bar%00foo_barfoo_barfoo%20bar%00foo barfoo_barfoo%5bbarfoo[barfoo_bar
通过以下这个示例,你可以更直观的看到parser_str函数如何处理字符串:
文章插图
<?phpforeach(["{chr}foo_bar","foo{chr}bar","foo_bar{chr}"] as $k => $arg) {for($i=0;$i<=255;$i++) {echo "33[999D33[Kr";echo "[".$arg."] check ".bin2hex(chr($i))."";parse_str(str_replace("{chr}",chr($i),$arg)."=bla",$o);/* yes... I've added a sleep time on each loop just forthe scenic effect like that movie with unrealisticbrute-force where the password are obtainedone byte at a time (∩`-´)⊃━☆?.*???*/usleep(5000);if(isset($o["foo_bar"])) {echo"33[999D33[Kr";echo $arg." -> ".bin2hex(chr($i))." (".chr($i).")n";}}echo"33[999D33[Kr";echo"n";}
文章插图
parse_str函数通常被自动应用于get、post请求和cookie中 。
如果你的Web服务器接受带有特殊字符的参数名,那么也会发生类似的情况 。
如上代码所示,我进行了多次循环,枚举了参数名三个位置的0到255之间的所有字符,看看解析函数到底是如何处理这些特殊字符的 。
结果如下:
1.[1st]foo_bar
2.foo[2nd]bar
3.foo_bar[3rd]
文章插图
文章插图
在上述方案中,foo%20bar和foo+bar等效,均解析为foo bar 。
Surica
也许你也听过这款软件,Suricata是一个“开源、成熟、快速、强大的网络威胁检测引擎”,它的引擎能够进行实时入侵检测(IDS)、入侵防御系统(IPS)、网络安全监控(NSM)和离线流量包处理 。
在Suricata中你可以自定义一个HTTP流量的检测规则 。假设你有这样一个规则:
alert http any any -> $HOME_NET any (msg: "Block SQLi"; flow:established,to_server;content: "POST"; http_method;pcre: "/news_id=[^0-9]+/Pi";sid:1234567;)
简单来说,上述规则会检查news_id的值是否是数字 。那么根据上述知识,我们可以很容易的绕过防御,如下所示:/?news[id=1%22+AND+1=1--'/?news%5bid=1%22+AND+1=1--'/?news_id%00=1%22+AND+1=1--'
通过在google和Github上进行搜索,我发现有很多关于Suricata规则可以通过替换下划线或插入空字符来绕过 。一个真实的例子:https://github.com/OISF/suricata-update/blob/7797d6ab0c00051ce4be5ee7ee4120e81f1138b4/tests/emerging-current_events.rules#L805
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"ET CURRENT_EVENTS Sakura exploit kit exploit download request /view.php"; flow:established,to_server; content:"/view.php?i="; http_uri; fast_pattern:only; pcre:"//view.php?i=d&key=[0-9a-f]{32}$/U"; classtype:trojan-activity; sid:2015678; rev:2;)
上述规则可以通过以下方式绕过:/view.php?i%00=1&%20key=d3b07384d113edec49eaa6238ad5ff00
当然,这条规则交换参数位置即可绕过,比如:/view.php?key=d3b07384d113edec49eaa6238ad5ff00&i=1
WAF(ModSecurity)
此外,PHP查询字符串的解析特性也可用以绕过WAF 。
想象一下,它的规则类似于SecRule !ARGS:news_id "@rx ^[0-9]+$" "block",这显然可以通过相同的手段绕过 。
推荐阅读
- 王彬,每件根艺 茶台都是独无二的
- Dubbo框架的一些很好用的点,80%程序员还不知道
- WordPress建站的那些坑,别再踩了
- C 语言和 C++、C# 的区别在什么地方?
- 一些长时间GC停顿问题的排查及解决办法
- Google收录排名网页的四个过程
- 大学|大专生抢走名校高材生的机会,引来围观网友愤怒质疑:你配吗?
- 客厅挂灰色的窗帘好吗,客厅适合什么材质的窗帘
- 阳台花园装修设计技巧
- 电饭煲内胆的价格清单