Loading... ### ⚙️ **一、攻击原理(漏洞本质)** CRLF(Carriage Return Line Feed)漏洞又称**HTTP响应拆分(HTTP Response Splitting)**,核心是通过注入特殊字符控制HTTP响应结构: - **CR(`%0d`, `\r`)**:回车符,光标移至行首 - **LF(`%0a`, `\n`)**:换行符,光标移至下一行HTTP协议要求头部以 `\r\n`分隔,头部与正文以 `\r\n\r\n`分隔。当攻击者控制响应头输入并注入CRLF时,可篡改响应包结构,实现: - 添加恶意响应头(如 `Set-Cookie`) - 分割响应包注入XSS代码 - 构造虚假响应体(如劫持页面) ```mermaid sequenceDiagram attacker->>server: 发送含%0d%0a的恶意请求 server->>server: 未过滤CRLF字符 server->>victim: 响应被拆分的HTTP包 victim->>attacker: 执行恶意操作(如会话劫持) ``` --- ### 🛠️ **二、产生根源(漏洞成因)** | **漏洞类型** | **技术原因** | **典型案例** | | ------------------------ | --------------------------------------------------------- | ------------------------------------------------------------------------ | | **配置不当** | Nginx错误使用 `$uri`(解码后路径)代替 `$request_uri` | 跳转配置:`return 302 https://$host$uri;` → 注入 `%0d%0a`可篡改响应 | | **编码过滤缺失** | 未过滤用户输入中的 `\r`, `\n`等控制符 | Twitter漏洞:UTF-8编码 `%E5%98%8A`→解码为 `%0A`绕过过滤 | | **Header函数误用** | PHP的 `header()`函数直接拼接用户输入 | `header("Location: " . $_GET['url']);` → 参数含CRLF可拆分响应 | --- ### ⚔️ **三、利用手法(攻击场景与绕过技巧)** #### **1. 基础攻击场景** - **会话固定**:`http://victim.com/%0d%0aSet-Cookie:JSPSESSID=attacker_session` → 强制用户使用攻击者预设Session - **反射型XSS**: `http://victim.com/%0d%0a%0d%0a<script>alert(1)</script>` → 注入脚本执行 #### **2. 高级绕过技巧** | **防御措施** | **绕过方法** | | ---------------------- | ----------------------------------------------------------------------------------------------------------- | | **基础字符过滤** | 双重编码:`%0d → %250d` → 服务端二次解码 | | **Referer检查** | 利用 `<meta>`跳转清空Referer:`<meta http-equiv="refresh" content="0; url=http://victim.com/%0d%0a..."` | | **HTTPS限制** | 构造HTTPS→HTTP跳转使Referer为空 | #### **3. 组合漏洞利用链** ```mermaid graph LR A[CRLF注入] --> B[注入Set-Cookie头] A --> C[注入XSS代码] B --> D[会话劫持] C --> E[窃取用户数据] ``` **案例**:Shopify的 `/last_shop`接口未过滤参数,注入 `%0d%0a`可覆盖响应体实现页面篡改 --- ### 🛡️ **四、防御方案(纵深防御体系)** #### **1. 输入处理层** - **严格过滤**:删除用户输入中的 `%0d`, `%0a`, `\r`, `\n`等字符 - **统一编码**:对输出到HTTP头的值进行URL编码(如 `encodeURIComponent()`) #### **2. 代码/配置层** | **组件** | **正确做法** | **错误示例** | | --------------- | ----------------------------------------------- | --------------------------------------------- | | **Nginx** | 使用 `$request_uri`(未解码原始URI) | `return 302 https://$host$uri;` → 易被注入 | | **PHP** | 用 `header()`前校验参数:`if (preg_match('/\r | \n/', $url)) die();` | | **Java** | 使用 `response.encodeRedirectURL(url)` | 手动拼接Location头 | #### **3. 安全加固层** - **响应头防护**: - 添加 `Content-Security-Policy`限制脚本执行 - 设置 `X-XSS-Protection: 1; mode=block` - **Cookie安全**: - 启用 `SameSite=Strict` - 标记 `HttpOnly`和 `Secure` #### **4. 防御措施对比** | **方案** | **安全性** | **兼容性** | **实施成本** | | -------------------------- | ---------------- | ---------------- | ------------------ | | **输入过滤** | ★★★☆☆ | ★★★★★ | 低 | | **使用$request_uri** | ★★★★★ | ★★★★☆ | 低 | | **CSP策略** | ★★★★☆ | ★★★☆☆ | 中 | --- ### 🔍 **五、渗透测试验证方法** #### **1. 手工检测** 1. **定位注入点**:寻找设置Header的接口(如重定向、Cookie) 2. **发送测试Payload**: ```http GET /redirect?url=http://test/%0d%0aX-Injected:%20true HTTP/1.1 Host: victim.com ``` 3. **验证响应**:检查是否出现 `X-Injected: true`头 #### **2. 工具化扫描** - **Burp Suite**: - 使用 `Decoder`模块编码CRLF - `Intruder`批量测试参数 - **OWASP ZAP**:`Active Scan`规则库包含CRLF检测 #### **3. 绕过技巧验证** ```python # Python双重编码PoC import requests url = "http://victim.com/redirect?url=" + requests.utils.quote("http://evil.com%250d%250aSet-Cookie:test=1") response = requests.get(url) print("Set-Cookie in headers?" , "test=1" in response.headers) ``` --- ### 💎 **总结与最佳实践** CRLF漏洞本质是**输入输出链缺乏边界控制**,根治需结合: 1. **输入净化** → 过滤CRLF字符 2. **安全编码** → 使用安全API(如 `$request_uri`) 3. **输出编码** → Header值强制URL编码 4. **纵深防御** → CSP + SameSite Cookie > **血泪教训**:Twitter因UTF-8解码漏洞导致CRLF注入(CVE-2015-9247),攻击者注入 `Set-Cookie`劫持会话。修复方案:**双重过滤**(解码前检查 `%0a`,解码后二次验证)。 **权威参考**: - [OWASP CRLF防御指南](https://cheatsheetseries.owasp.org/cheatsheets/CRLF_Injection_Prevention_Cheat_Sheet.html) - [Nginx官方:$request_uri与$uri区别](https://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_uri) 通过**输入过滤+安全配置+输出编码**三重防护,可彻底杜绝CRLF攻击链,确保HTTP响应结构完整性。 最后修改:2025 年 06 月 05 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏