通过HTTP参数污染绕过WAF拦截
注:本文思路已经很古老了,且之前t00ls多有讨论,但是图片中对各系统环境的测试搜集很全,因此转来t00ls。
译:pnig0s_小P
上个星期我被邀请组队去参加一个由CSAW组织的CTF夺旗比赛.因为老婆孩子的缘故,我只能挑一个与Web漏洞利用相关的题目,名字叫做”HorceForce”.这道题价值300点。这道题大概的背景是,你拥有一个低权限的帐号并需要找到方法来获得管理员权限。
当然,有很多种方法来介绍如何通过这关,但我想分享下我的通关经验。
当把一些单引号作为参数值发送之后返回了MySQL的典型报错信息“MySQL SQL Error Message”,因此可以轻易发现这里存在一个SQL注入漏洞。
然后,正如你了解的,我们通常会进行如下尝试:
http://128.238.66.217/horse.php?id=7 or 1 IN (select current_user)
然后我得到了一个错误信息,类似“请停止攻击该网站“这样的内容。
在我尝试了很多绕过SQLi filter的方法之后,我意识到在网站背后配置了一个WAF来阻止任意包含“select”或“union”等在利用SQL注入时常用的SQL查询关键字。通过这样的黑盒测试可以猜测出WAF使用了类似下面这样的正则:
/^.*select.*$/ or /^.*union.*$/
这意味着,提交任意带有SQL注入企图的字符串,如blablaSELECTblabla或像/*!union*/这样的绕过方式都会触发WAF拦截的错误信息。
在进行了一些研究之后,我发现通过HTTP参数污染的方式能够使攻击者绕过WAF的拦截。
那么,究竟要如何实现呢?
我们假设有一个通过GET方式提交的参数“id”,你可以重复构造这个参数并以下面的形式发送出去:
?id=value1&id=value2
然后,依你使用的框架不同(PHP,Java,ASP.NET,etc),参数字符串会以不同的方式进行解析,在我们实验的场景下Apache/PHP,如果你可以多次注入同一个参数值,只有最后一个参数值会被框架解析,但是你猜怎么着?只有第一个参数会经过WAF的分析和过滤!
这意味着,通过注入: id=7&id=[SQLi]
WAF的网络层会解析 id=7 <-合法
PHP应用层会解析 id=[SQLi] <-注入语句成功执行
因此,这是一个典型的例子,你注入的东西在网络层和应用层被区别对待了。
下面是一张表格,列举了不同的框架当多次接受同一个参数时的不同表现。像ASP.NET,如果它接受到两个参数值,它会拼接两个相同参数的值,因此你可以将被过滤的关键词拆分到两个参数中进行攻击从而绕过WAF,当然这个主题已经超过这篇文章讨论的范围了。
接下来,我们尝试注入一些SQL语句:
128.238.66.217/horse.php?id=0&id=7%20union%20select%201,2,3,current_user
你能注意到,所有的注入利用语句都写到了第二个参数值的位置,这将不会被WAF解析。
我得到了第一次正确的返回结果:
csaw_chal1@localhost
接下来就是常规的MySQL注入过程,这里不再赘述,这篇文章主要在于讲解一种新的绕过WAF的方式,Thx for reading!
评论15次
学xi了!!
参数污染,这词谁发明的啊,好鸡巴高端的样子啊
是不是要存在 HTTP参数污染,才可以使用此方法绕过?
合并 第一个被过滤了 但是后面依然还有一个 id=1 id=2 id=12 合并了参数 和CGI的不同有所改变 id=1 id=2 id=2 id=1 直接忽略了 有些WAF 一个参数不会过滤2次 所以就酱紫了 过安全狗注入 id=%00.&id=xxx 遇到BT 的 WAF 还是一样悲剧 这个只是技巧而已 t00ls 应该一起都讨论过 2010年吧或是09年? WAF 厂商不可能没想到 毕竟还是老东西 虽然说起来很NB的样子 其实也差不多
涨知识了啊,好久不来就看到好东西,安逸
这个好,以前搞站被这蛋疼的东西搞得死去活来的,现在总算有方法了,感谢楼主分享!
这个提法 的id 应该在 页面中 <?request?> 如果没有 这个参数 应该是无用的 因为可能没有返回值
涨姿势了
变量覆盖
学xi啦,遇到了试试这方法。
good!
第一个参数提交注入不合法,第二个参数就合法了,有点不理解
谢谢分享 学xi了
学到知识了
不错哦 第一次了解到这样的绕过手法支持下