0x00 前言

HTTP请求走私漏洞(HTTP Request Smuggling)是发生在协议层的一种攻击,最早于2005年就被发现并提出。漏洞发生的主要原因是不同的服务器,对于RFC标准的具体实现不一而导致的。

0x01 漏洞原理

HTTP 1.1协议相对于1.0主要引入了两个新的特性: Keep-Alivepipline

1、Keep-Alive特性具体是指在HTTP请求头中,添加一个参数

Connection: Keep-Alive

告诉服务器在收到这个请求后不要关闭连接,后面再次发起请求时,继续使用这个TCP连接。

2、pipline特性是指在一次TCP连接中,可以连续不断地发送多个http请求,而不必等待服务器响应。服务器会根据顺序进行处理。

有了这两个特性之后,HTTP 1.1相对于 HTTP 1.0来说,传输效率更高,如今HTTP 1.1也应用最为广泛。


在RFC 2616中规定,一个完整的数据包中需要在请求头部分包含"Content-Length"或者"Transfer-Encoding"来对数据包的长度进行说明。

1、Content-Length: 指明数据包的内容长度,一个字符长度为1,回车(\r\n)长度为2。如:

HTTP请求走私1.png

这个数据包的请求长度为10:

HTTP请求走私2.png

2、Transfer-Encoding: 当值为chunked时,服务器在读取到

0\r\n\r\n

后就会认为该请求已经结束。

而之后的内容会存在于服务器的缓存中,和下一个请求一起发送给服务器。

HTTP请求走私漏洞的核心就在于前端和后端对于请求的长度判断不一而引起的。

如当前端使用Content-Length来判断,而后端使用Transfer-Encoding:chunked来判断时,我们构造一个请求如:

HTTP请求走私3.png

前端认为请求长度为6,会将所有内容转发给后端,而后端读到"0\r\n\r\n"后就认为请求已经结束,因此最后一个"G"就会留到缓存服务器中,被拼接到下一个请求的开始,如

HTTP请求走私4.png

这样当下一个正常用户发起请求时,就会返回错误,因为服务器并不认得"GPOST"是什么请求方式。

这就是一个简单的HTTP请求走私攻击的例子。

上面这个例子中,前端使用Content-Length判断,后端使用Transfer-Encoding:chunked判断,因此属于CL-TE类型,与之对应的还有TE-CLTE-TE

0x02 漏洞复现

利用工具:Burpsuite

需要在Repeater中关闭更新Content-Length

HTTP请求走私5.png

以CL-TE为例 : 靶场地址

正常访问:

HTTP请求走私6.png

开启抓包,将请求改为POST方式

构造请求

HTTP请求走私7.png

放包。当下一个用户访问这个页面时

HTTP请求走私8.png

0x03 扩展

根据以上原理,我们可以更改下一个正常访问用户的请求内容,包括Cookie信息等。因此可以扩展出危害更大的攻击,如获取服务器敏感信息、获取用户登录信息、能交互的反射型XSS等。

0x04 缓解措施

对于前端,对所有请求进行规范化,避免模糊请求。

对于后端,拒绝掉一切模糊请求。