基于HTTP协议特性绕过WAF的技巧

前言

提前声明,本文内容虽然主要针对的是 SQL WAF 的绕过演示,但由于是基于在 HTTP 协议层面绕过 Waf,因此所述技巧具有较高的通用性,所以理论上可以用于平时渗透时的方方面面,比如命令执行,代码注入,SQL注入等测试。

关于 Bypass WAF 先前已经写过两篇相关的文章可结合阅读:

  1. WAF绕过技术基础:渗透测试-浅析WAF绕过
  2. WAF绕过进阶HPP:Bypass WAF-HTTP参数污染漏洞挖掘

本文将介绍基于 HTTP 协议特性进行 SQL 注入过程的 WAF 绕过,主要包含以下几种技巧:

  1. pipline 隧道传输绕过;
  2. chunked 分块传输绕过;
  3. Content-Type 协议未覆盖绕过;
  4. 协议未覆盖+分块传输组合拳绕过;
  5. 分块传输使用注释混淆对抗WAF检测;
  6. 协议未覆盖绕过进阶——fliename 混淆伪装绕过。

以上技巧的本质原理都是给服务器发送经过基于 HTTP 协议特殊处理后的 Payload 数据包,使得 WAF 无法识别出带有脏数据的 Payload,但 Apache、Tomcat 等 Web 容器和 Mysql、Sqlserver 等数据库能正常解析其内容,如下图所示:
在这里插入图片描述

在此强烈推荐读者可学习下 B 站漏洞银行平台 1337G 大佬的一起分享视频(2倍播放速度食用更香):漏洞银行丨一般人我不告诉的WAF绕过新姿势-1337G丨咖面74期

WAF绕过

WAF演示环境

本机 Win10、Xampp、某狗Web应用防火墙最新版。

1、为方便演示,存在 sql 注入的脚本中使用$_REQUEST["id"]来接收 get 或者 post 提交的数据。WAF 配置为拦截 url 和 post 的 and or 注入,如图所示:
在这里插入图片描述2、部署完WAF后,发送 get 请求或利用 hackbar 插件发送 post 请求时,含有脏数据的 payload 将被拦截,如图所示:
在这里插入图片描述

隧道传输绕过

原理】HTTP 协议是由 TCP 协议封装而来,当浏览器发起一个 HTTP 请求时,浏览器先和服务器建立起连接 TCP 连接,然后发送 HTTP 数据包(即我们用burpsuite 截获的数据),其中包含了一个 Connection 字段,一般值为 close,Apache 等 WEB 容器根据这个字段决定是保持该 TCP 连接或是断开。当发送的内容太大,超过一个 HTTP 包容量,需要分多次发送时,值会变成 keep-alive,即本次发起的 HTTP 请求所建立的 TCP 连接不断开,直到所发送内容结束 Connection 为 close 为止。
在这里插入图片描述

1、在使用隧道传输之前,需要关闭 burp 中 Repeater 模块的 Content-Length 自动更新,如图所示,点击取消勾选 Repeater 下拉选项中的 update Content-Length 功能(这一步至关重要):
在这里插入图片描述
2、burp 通过 post 请求提 id=1 and 1=1,显示被 WAF 拦截,如图所示:
在这里插入图片描述3、利用隧道传输,同时发送两个数据包,将两个数据包提交的内容依次设置为id=1id=1 and 1=1,再将数据包的 Content-Length 的值依次设置为其字符长度即 4 和 12,最后将Connection 字段值设为 keep-alive。提交后如图所示,会返回两个响应包,分别对应两个请求:
在这里插入图片描述
小结

  1. 从结果上看,两个数据包都能到达服务器,第一个正常数据包返回了正确内容,第二个包含有效载荷的数据包被某狗 WAF 拦截(此处无法绕过),但是在面对其他 WAF 时有可能可以绕过。
  2. 无论如何这仍是一种可学习了解的绕过方法,且可以和接下来的方法进行组合使用绕过。

分块传输绕过

原理】如果在 HTTP 头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,post 请求报文中的数据部分需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的,也不包括分块数据结尾的,且最后需要用0独占一行表示结束(同时末尾需要以两个换行结束)。

1、首先开启上个实验中已关闭的 content-length 自动更新。给 post 请求包加入Transfer-Encoding: chunked请求头后,将数据部分id=1 and 1=1进行分块传输,成功绕过 WAF,如图所示:
在这里插入图片描述2、进一步将上图数据包的id=1 and 1=1改为id=1 and 1=2,分块传输发送 payload,服务器没有返回数据,说明 payload 生效:
在这里插入图片描述小结】分块传输绕过需要注意以下几点:

  1. 分块编码传输需要将关键字and,or,select ,union等关键字拆开编码,不然仍然会被waf拦截。
  2. 编码过程中长度需包括空格的长度。
  3. 最后用0表示编码结束,并在0后空两行表示数据包结束,不然点击提交按钮后会看到一直处于waiting状态。

协议未覆盖绕过

原理】HTTP头里的Content-Type请求头一般有application/x-www-form-urlencoded,multipart/form-data,text/plain三种,其中multipart/form-data表示数据被编码为一条消息,页上的每个控件对应消息中的一个部分。当 WAF 没有规则匹配该协议传输的数据时则可被绕过。

1、首先将 HTTP 请求头部Content-Type改为multipart/form-data; boundary=69 ,然后设置分割符内的Content-Dispositionname 为要传参数的名称,数据部分则放在分割结束符上一行:
在这里插入图片描述由于是正常数据提交,所以从图中可知数据是能被 Apache 容器正确解析的,但尝试提交1 and 1=1也会被某狗 WAF 拦截,但如果其他 WAF 没有规则拦截这种方式提交的数据包,那么同样能绕过。

注意】实际上,上述将 POST 请求中传递的数据由application/x-www-form-urlencoded格式转换为文件上传包格式multipart/form-data时,BurpSuite 已提供右键选择change body encoding一键转换的功能,无需手动转换。

2、一般绕 WAF 往往需要多种方式结合使用,在上图所示实例中只需将数据部分1 and 1=1用一个小数点”.”当作连接符即1.and 1=1就可以起到绕过作用。当然这只是用小数点当连接符所起的作用而已,如下图所示:
在这里插入图片描述

组合拳方式绕过

下面进一步尝试使用 分块编码+协议未覆盖组合绕过。

1、在协议未覆盖的数据包请求头中加入Transfer-Encoding: chunked ,然后将数据部分全部进行分块编码,同样可以过 WAF,如图所示(数据部分为1 and 1=1):
在这里插入图片描述2、上面的数据包需要注意标红圈出来的部分:第2、3、7、8块。

2块,即格式声明部分,需满足:
长度值 空行 Content-Disposition: name="id" 空行
这种形式,且长度值要将两个空行的长度计算在内(空行长度为2)。

第3块,即数据开始部分,需满足:
长度值 空行 数据
这种形式,且需将空行计算在内。

第7块,即分割边界结束部分,需满足:
长度值 空行 分割结束符 空行
这种形式,且计算空行长度在内。

第8块,即传输数据的末尾部分,需满足
0 空行 空行
这种形式。如果不同时满足这四块的形式要求,payload将不会生效。

分块传输的混淆

一些比较好的 WAF(如Imperva,360等),已经对传输编码的分块传输做了处理,可以把分块组合成完整的 HTTP 数据包,这时直接使用常规的分块传输方法尝试绕过的话,会被 WAF 直接识别并阻断。

但是几乎所有可以识别传输编码数据包的 WAF,都没有处理分块数据包中长度标识处的注释,导致在分块数据包中加入注释的话,WAF 就识别不出这个数据包了。

1、我们先在使用了 Imperva 的应用防火墙的网站测试常规的分块传输数据包,将被 WAF 拦截:
在这里插入图片描述2、接着我们在分块传输数据包中长度标识处的注释加入注释符,发现可以成功绕过 WAF:
在这里插入图片描述

Filename混淆绕过

以上环境并未演示到另外一种基于 HTTP 协议特性绕过 WAF 的方法(实际上是基于 “协议未覆盖绕过” 方法,属于它的升级改造版)—— filename 文件名混淆绕过。下面直接看漏洞银行大佬在视频中的实战利用演示。

1、大佬在视频中演示的已部署 WAF 的网站为:
在这里插入图片描述2、直接传入带有脏数据的 payload,将被拦截:
在这里插入图片描述3、先顺便演示下隧道传输成功绕过 WAF:
在这里插入图片描述4、同时分块传输也可以绕过 WAF:
在这里插入图片描述最后步入正题,使用 filename 文件名混淆绕过的方法。

5、首先将原始的带有脏数据的 payload 转换成文件上传包格式的协议:multipart/form-data,如下图所示:
在这里插入图片描述自动转换结果如下:
在这里插入图片描述
6、删除掉转换后末尾的空行,直接尝试发送 payload,发现被拦截了:
在这里插入图片描述7、接着我们在 name="a” 后面添加 filename="123.jpg”,将 Payload 伪装成图片的格式进行发送,发现 WAF 不拦截,但是此时 Payload 也会因为被当作图片而不被解析:
在这里插入图片描述
8、为了让 Payload 能够顺利解析,可以在 fliename="123.jpg"的等号前面添加空格,让 fliename 文件名无法解析,从而使得 payload 即参数 a=1 union select…… 可被服务器解析执行,最终达到绕过 WAF 同时执行 pqyload 注入的目的:
在这里插入图片描述9、另外此处也可以在 filename 前方添加双引号,也可以实现上述执行 payload 的目的:
在这里插入图片描述以上就是利用 filename 混淆绕过 WAF 的方法,也是成功率极高的一种绕过方式,它属于 “协议未覆盖绕过” 的一种演变和提升。

总结

  1. GIthub上提供了一款 BurpSuite 插件可帮助我们快速将数据包进行分块编码,地址为:Chunked coding converter v0.2.1
  2. 以上是在 HTTP 协议层面绕过 WAF,因为比较通用,所以理论上可以用于平时渗透时的方方面面,如命令执行,代码注入,SQL注入等测试。
  3. 虽然以上演示环境(不含最后 filename 混淆绕过部分)中只有分块编码真正做到了绕过某狗,但其他两种方法在其他 WAF 绕过中可能仍然可用,而且可与其他绕过方法结合使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tr0e

分享不易,望多鼓励~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值