【安全漏洞】浅谈 Bypass Waf (基础 - 实战)
前言-基础篇
在了解 Bypass Waf 之前,我们应该首先了解一些前置知识:
1.Waf 是什么
2.Waf 的类型
3.Waf 的工作原理
1. Waf 是什么
Waf 全称为 Web Application FireWall(Web 应用防火墙);顾名思义 Waf 原理与日常使用防火墙相似,但主要注重在 Web 页面中存在的对应安全问题。
2.Waf 的类型
WAF 分为非嵌入型 WAF 和嵌入型 WAF。
非嵌入型是指硬 WAF、云 WAF、软 WAF 之类。
嵌入型是指 web 容器模块类型 WAF、代码层 WAF。
3.Waf 的工作原理
不论是什么类型的 Waf,工作的方式几乎差不多。首先,从用户体验上出发,用户的目的是部署 Waf 从而解决对应的 WEB 安全问题;所以对于 Waf 开发来说,需要了解的就是:哪些位置可能会引发安全漏洞、如何判断攻击者利用攻击触发了漏洞。
回顾一下 TOP 10 的安全漏洞,我们可以得到一个结论,Web 漏洞产生的位置基本都为:
1.HTTP 头部字段
2.GET、POST 提交的内容
3.上传的文件
所以,我们也可以逆推得到 Waf 构建及工作的原理大致为:
1.构建各种漏洞利用的攻击特征库
2.对漏洞产生位置的内容进行搜集
3.将搜集的内容在特征库中进行匹配,查看是否存在攻击特征并作出相应
更详细的工作流程如下图所示:
建立特征库的流程:
判断恶意攻击流程:
绕 Waf 实战
了解完 Waf 是怎么拦截对应的流量之后,我们就明白了绕 Waf 的最终目标是绕过特征库检测(即绕过正则匹配)。
那如何绕过正则匹配呢?
主要的方式就两种:
1. 通过 Fuzz 脚本构造大量 Payload 进行尝试
2. 通过人为手工探测 Waf 编写规则。
第一种方式比较暴力,且针对初学者并不是很友好,因为需要很多之前师傅们绕 Waf 的 Payload 作为前置知识。
基本思路大致是:对绕过的方法进行搜集构造一些经常绕 Waf 的字符串,并且利用脚本在漏洞点构造语句+绕 Waf 字符串+垃圾字符等 Payload,通过跑大量 Payload 的方式爆开可以绕 Waf 的 Payload。
很好,所以我们介绍第二种方法。
相关资料获取可私信回复“资料”
前置知识:由于 Waf 需要尽量满足客户需求,Waf 的匹配规则通常会匹配的很详细进而减少误报。
以某安全厂商的 Waf 产品的规则为例:
那我们就可以通过手工一步步探测 Waf 的过滤规则是什么,从而进行绕过。
【领取文档】
如何进行手工探测 Waf 的过滤规则-实战篇
以下测试均为授权渗透测试:
探测规则 1
在页面发现一处富文本编辑器,并且该内容提交后会显示在对应页面上,这里第一个想到的就是 XSS 了。
先整个最简单的 XSS 的 Payload 试试,抓包看现象:
发现输入的标签会被 HTML 实体化编码,所以每次构造 Payload 时需要解 HTML 实体。
从回包的状态码 403 和 Server 值可以判断是被 Waf 拦截了。
那么这时如果我们想要绕 Waf 的话,就要去思考它对应的正则匹配的规则可能存在的情况了:
1.匹配 script
2.匹配 alert
3.匹配<.*?>
4.匹配<script>
5.匹配<script>.*?alert.*?</script>
注:.*?表示非贪婪比配,可以匹配任意字符,直到下一个字符出现为止。例如:<.*?>可以匹配<符号开头、后面可以有任意字符直到匹配到>为止。
大致推出比较有可能的就是这集中情况,那我们就可以进行一一验证:
script
alert
<(.*?)>
<script>
可以发现,拦截的关键字为<script>,则第五种情况无需测试,因为构造的字符串存在<script>,一定会被规则匹配中。那么该规则过滤了<script>标签,我们就可以思考通过其他标签构造 XSS,例如<img>等。
探测规则 2
既然可以构造 img 标签,那也拿 img 的 XSS Payload 浅测一下:
好了,又被拦了。首先大致能排除<img src=xxx>的问题,出于稳健的心理浅测一下:
说明构造的 Payload 里面被拦截的特征为:onerror=alert(123)。
那就再简单猜测一下对应的 Waf 规则吧:
1.匹配 onerror=
2.匹配 alert(.*?)
3.匹配 on.*?=alert(.*?)
4.匹配 on.*?=.*?alert(.*?)
一一验证:
onerror=
拦了 onerror=应该也拦了其他的 on 事件,简单尝试一下:
那 on 事件几乎就是无了,得思考思考怎么绕。
alert(.*?)
看来也被拦截了,那只能试试换 prompt(123)或 alert`123`
均已失败告终...所以下面两个 on.*?=.*?alert(.*?)和 on.*?=alert(.*?)也无需测试都会被 Waf 拦截。
alert 最简单的绕过方式就是换函数了,但是常用的弹窗函数都被禁用了,貌似已经有点困难了;但是突发奇想:研发是否会不会只过滤了常见的弹窗函数,拿 document.location.href=xxx 试试:
没拦截这个函数呀,所以并不是所有函数都被拦了,而是常用的 alert()、prompt()、confirm()被拦截了。
所以要么换函数,要么强行绕 alert 函数(我喜欢硬刚,就冲 alert 了!)
我发现貌似这样判断 alert 是否被过滤不太严谨,应该重新判断一次:
故试了试如下 Payload:
意外发现竟然没有拦截?所以前面 alert(.*?)判断的匹配规则不对,匹配中的应该为 alert(123),前面可能有内容才会匹配
xxalert 没有拦截,那说明过滤的应该是特殊符号,这时上波 Fuzz 爆破一下,发现只有:和是被拦截的,也就是说,不能使用:alert(123)和 alert(123)
探测规则 3
先总结一下前面两波手工探测的成果:1.过滤了<script>等标签 2.过滤了 onerror 事件 3.过滤了:alert(123)及 alert(123)在这里,第一个规则我们可以使用<img>或者<a>,比较好绕过;第二个规则再加上对<script>标签的限制比较难绕过,但仍然可以尝试使用 href=javascript:xxxx 伪协议绕过;但如果在第二个规则内构造伪协议,则 Payload 应该为:<a href=javasciprt:alert(123)>,这样的话会匹配中第三个规则:alert(123),所以思路应该还是要换函数:
这样就可以执行 JS 代码了,但是没什么用...所以还是要想办法弹窗,但是又必须要绕过:alert(123)等。
灵机一动,Payload 就来了!alert()函数是 JS BOM 的函数,为了调用方便被简写成 alert(),而正规的调用方法为 window.alert()。那这样 Payload 就有了:
<a href=javascript:window.alert(123)>test</a>
页面点击链接看现象:
以上漏洞已报送至对应厂商。
评论