CRLF漏洞

0x00 简介

在文本处理中, CR, LF, CR/LF是不同操作系统上使用的换行符.Dos和windows采用回车+换行CR/LF表示下一行,而UNIX/Linux采用换行符LF表示下一行,苹果机(MAC OS系统)则采用回车符CR表示下一行.CR用符号’r’表示, 十进制ASCII代码是13, 十六进制代码为0x0D; LF使用’n’符号表示, ASCII代码是10, 十六制为0x0A.所以Windows平台上换行在文本文件中是使用 0d 0a 两个字节表示, 而UNIX和苹果平台上换行则是使用0a或0d一个字节表示.

0x01 原理

我们都知道,HTTP协议是依靠两个CRLF,即\r\n来分割HTTP头部及响应体。基于这个认知,可以推出,HRS问题是由于服务端程序没有过滤掉头部中的特殊字符%0D%0A,直接输出到了返回的数据中,导致错误的解析。而在日常开发中,最常见的莫过于有以下的两种功能(1)URL跳转(2)Cookie的设置中出现。

一旦我们能够控制http头,通过注入一些CRLF这样就可以控制header和body的分割线,这样我们就可以向body或是header中注入些东西了。所以CRLF Injection又叫HTTP Response Splitting,简称HRS。

0x02 危害

如果目标网页存在响应头部CRLF注入,在HTTP响应头注入回车换行符,就可以注入头部:
X-XSS-Protection: 0

HTTP header的定义就是基于这样的"Key: Value"的结构,用CRLF命令表示一行的结尾。
"Location:"头用来表示重定向的URL地址,
"Set-Cookie:"头用来设置cookies。
如果用户的输入经过验证,其中存在CRLF的字符就可以被用来达到欺骗的目的。

0x03 实例

测试代码:
index.php

<?php 
/*
*@博客:http://byd.dropsec.xyz/
*@Author:w2n1ck
*/
echo '<pre>';
print_r(file("http://www.site1.com/api?test=$test"/images/test.png)); 
echo '</pre>';
?> 

如果攻击者这样发送:

index.php?test=test%20HTTP /1.0%0D%0AHost%3A%20www.site2.com%0D%0AUser-Agent%3A%20joy_nick/0.0%0D%0AReferer%3A%20http%3A%2F%2Fwww.test.org%2F%0D%0ACookie%3A%20user%3Djoy_nick%0D%0A%0D%0AHTTP/1.0%0D%0AHost%3A%20http%3A%2F%2Fwww.SITE1.com%0D%0AUser-Agent%3A%20PHP/4.1.2

(必须在一行上)

这个 HTTP 请求将被发送给 www.site1.com:

GET /api?test=test HTTP/1.0 
Host: www.site2.com
User-Agent: joy_nick/0.0 
Referer: http://www.test.org/ 
Cookie: user=joy_nick

HTTP/1.0 
Host: www.site1.st 
User-Agent: PHP/4.1.2

你可以看到,真实的PHP头信息被正确发送,但被服务器忽略了,因为在它们指向的报头结束之前我们发送两个CRLF。

利用此缺陷,攻击者能够任意添加用户代理(user-agent),referers 和 cookies。如果站点1和站点2是同一台服务器上的虚拟主机,即使index.php有限制,攻击者也能绕过其限制非法访问站点2。

还有一个xss的能够轻松绕过filter的XSS,如果我们输入:

http://www.xxx.com%0d%0a%0d%0a%3Csvg%2fonload%3dprompt%281%29%3E

HTTP/1.1 200 ok
Date: XXX
Content-Type: text/html
Content-Length: 154
Connection: close

<svg/onload=prompt(1)>

从而形成XSS漏洞

0x04 防御

  1. 您需要限制用户输入CR(0x13)和LF(为0x10)或正确编码的输出,以防止自定义HTTP标头注射。
  2. 通过在PHP脚本中嵌入如下指令,确保所有这种类型的URL变量在使用时已被清空:

$var = preg_replace(’///s+/’, ’, $var);

  1. 如果你的脚本不需要访问URLs,建议在php.ini中关闭allow_url_fopen
大爷,赏个铜板呗!