背景介绍
首先什么是 HTTP 请求走私?Portswigger 网站其实对 HTTP 请求走私进行过非常详细的说明:
https://portswigger.net/web-security/request-smuggling
简而言之,HTTP 请求走私源于前端和后端服务器之间关于消息正文大小的分歧,而这种分歧可能会被滥用,从而干扰 Web 应用程序处理从用户收到请求的方式。
这通常是通过将指定消息长度的两种方法(“Content-Length【CL】”和“Transfer-Encoding【TE】”标头)添加到某一请求来触发。
TE:CL请求走私
由于 HTTP 标头规范,请求走私漏洞的检测可能会比较麻烦,然而Portswigger 开发了一款出色的工具http-request-smuggler可以帮助我们提高检测过程。
在下面的例子中,当工具检测到前端使用了“Transfer-Encoding”标头,而后端将使用了“Content-Length”标头,就会提示“TE:CL Request Smuggling”。为了确认是否存在该漏洞,我们进行手动请求:
在上图中,可以看到前端接收了我们的请求并默认为“Transfer-Encoding”标头(黄色突出显示),因此,前端读取直到“X”字符前的所有内容,并将请求转发到后端服务器。
使用“Content-Length”标头的后端服务器会尝试读入 6 个字节的数据,但只收到 5 个字节,因为前端会忽略了“Transfer-Encoding”指定的最后一个“X”字符。
当后端服务器等待最后一个数据字节到达时,这会导致明显的延迟并最终导致超时,这种延迟证实了不同步的存在,从而能够让我们开展后续各种请求走私攻击。
CL:TE请求走私
与TE:CL漏洞刚好相反,CL:TE漏洞则是前端服务器使用Content-Length标头,后端服务器使用Transfer-Encoding标头。
TE:CL漏洞利用
一旦确认了存在TE:CL漏洞,我们可以如下面图 2 中所示,发送请求:
后端再次使用“Content-Length”标头读取到请求,标头在字符“74”之后停止,但是,走私的“GET /404 HTTP/1.1”仍保留在请求队列中,此时后端将其视为新请求的开始。
这个“新”请求的“Content-Length”长度为 15(比指定的请求正文“x=y 0”要长),因此会导致后端继续等待剩余字节。
所以如果攻击者时机恰当,并且受害者恰好在走私请求后不久发送了请求,那么他们的请求将被后端读入作为走私请求的剩余字节。
实战及案例
安装
首先安装工具,Turbo Intruder 和 HTTP Request Smuggler 简直是绝配。
使用
在 Target 找到你要测试的目标站点,点击右键,选择 HTTP Request Smuggler 工具:
然后就是静静地在Issue窗口等待检测结果了。
一旦有提示‘蹦出来’,那么就可以将相应的请求发送至Repeater中进行确认了。
当然,你可以利用 Turbo Intruder 配合相应的脚本来实现更为强悍的漏洞利用。
案例
比如Hackerone上的某个案例(https://hackerone.com/reports/498052) ,白帽子利用 Turbo Intruder 以及 Collaborator 成功实现用户Token窃取,并最终获得$3000赏金奖励:
再比如:["独家揭秘:请求走私高级利用,利用组合链获取用户内部敏感数据!"](https://gugesay.com/archives/1984 ""独家揭秘:请求走私高级利用,利用组合链获取用户内部敏感数据!"")
如何防范
可参考 Portswigger 网站上的建议:
- 使用 HTTP/2 协议 ,(如有可能,禁用 HTTP 降级)。 HTTP/2 使用了强大的机制来确定请求的长度,并且在端到端使用时,本质上可以防止请求走私。如果无法避免 HTTP 降级,确保根据 HTTP/1.1 规范验证重写的请求,例如,拒绝标头中包含换行符、标头名称中包含冒号以及请求方法中包含空格的请求
- 当前端服务器接收规范不明确的请求时,使后端服务器拒绝任何不明确的请求,并在该过程中关闭 TCP 连接
- 永远不要假设请求没有正文,这是CL.0和客户端不同步漏洞的根本原因
- 如果处理请求时触发服务器异常,则默认丢弃连接
- 如果流量通过转发代理路由,尽可能确保启用上游 HTTP/2