也是面试提及过

漏洞描述

HTTP报文的结构:状态行和首部中的每行以CRLF结束,首部与主体之间由一空行分隔。或者理解为首部最后一个字段有两个CRLF,首部和主体由两个CRLF分隔。

CRLF注入漏洞,是因为Web应用没有对用户输入做严格验证,导致攻击者可以输入一些恶意字符。攻击者一旦向请求行或首部中的字段注入恶意的CRLF,就能注入一些首部字段或报文主体,并在响应中输出,所以又称为HTTP响应拆分漏洞(HTTP Response Splitting)

CRLF指的是回车符(CR,ASCII 13,\r,%0d)和换行符(LF,ASCII 10,\n,%10),操作系统就是根据这个标识来进行换行的,用户在键盘上输入回车键输出这个字符,只不过windows和linux系统采用的标识不一样

  1. Windows:使用CRLF表示行的结束
  2. Linux/Unix:使用LF表示行的结束
  3. MacOS:早期使用CR表示,现在好像也用LF表示行的结束
  4. 所以同一文件在不同操作系统中打开,内容格式可能会出现差异,这是行结束符不一致导致的。

在HTTP规范中,行应该使用CRLF来结束。首部与主体由两个CRLF分隔,浏览器根据这两个CRLF来获取HTTP内容并显示。

在HTTP当中HTTP的Header和Body之间就是用两个crlf进行分隔的,如果能控制HTTP消息头中的字符,注入一些恶意的换行,这样就能注入一些会话cookie和html代码,所以CRLF injection 又叫做 HTTP response Splitting,简称HRS。

CRLF漏洞可以造成Cookie会话固定反射型XSS(可过waf)的危害
注入XSS的利用方式:连续使用两次%0d%oa就会造成header和body之间的分离,就可以在其中插入xss代码形成反射型xss漏洞。

原理分析

CRLF注入漏洞的本质和XSS有点相似,攻击者将恶意数据发送给易受攻击的Web应用程序,Web应用程序将恶意数据输出在HTTP响应头中。(XSS一般输出在主体中) 所以CRLF注入漏洞的检测也和XSS漏洞的检测差不多。通过修改HTTP参数或URL,注入恶意的CRLF,查看构造的恶意数据是否在响应头中输出。

HRS漏洞存在的前提是 :

url当中输入的字符会影响到文件,比如在重定位当中可以尝试使用%0d%0a作为crlf.

一般网站会在HTTP头中加上Location: http://baidu.com的方式来进行302跳转,所以我们能控制的内容就是Location:后面的XXX网址,对这个地址进行污染。
假设服务端(PHP)的处理方式:

  1. if($_COOKIE("security_level") == 1)
  2. {
  3. header("Location: ". $_GET['url']);
  4. exit;
  5. }

代码意思是说当条件满足时,将请求包中的url参数值拼接到Location字符串中,并设置成响应头发送给客户端。
此时服务器端接收到的url参数值是我们修改后的:
http://baidu.com/xxx%0a%0dSet-Cookie:crlf=true
在url参数值拼接到Location字符串中,设置成响应头后,响应包此时应该是下图这样的:

image.png
%0d和%0a分别是CR和LF的URL编码。HTTP规范中,行以CRLF结束。所以当检测到%0d%0a后,就认为Location首部字段这行结束了,Set-Cookie就会被认为是下一行,如下图所示。
image.png
而我们构造的Set-Cookie字符在HTTP中是一个设置Cookie的首部字段,这个时候就会将crlf=true设置成Cookie。

在url参数值拼接到Location字符串中,设置成响应头后,响应头就会看到:
Set-Cookie:crlf=true

  1. 找到输入点,构造恶意的CRLF字符

测试

CRLF注入漏洞的检测也和XSS漏洞的检测差不多。通过修改HTTP参数或URL,注入恶意的CRLF,查看构造的恶意数据是否在响应头中输出。
主要是在看到有重定向或者跳转的地方,可以在跳转的地址添加?url=http://baidu.com/xxx%0a%0dSet-Cookie: test123=123测试一下,通过查看响应包的数据查看结果。

  1. GET /index.php?c=rpzy&a=query&type=all&value=123&datatype=json&r=X1MU6E86%0a%0dSet-Cookie: test123=123 HTTP/1.1
  2. Host: www.xxxxyou.net

如果利用成功的话,响应包会出现一行Set-Cookie: test123=123 数据。

漏洞修复

过滤 \r 、\n 之类的行结束符,避免输入的数据污染其他 HTTP 首部字段。