本文内容:
某站发现的一个 CRLF
漏洞以及一些利用思考
前言
最近真的是太忙了,实习要学习JS安全
和浏览器漏洞挖掘之类的
但我二进制不是很好,所以还在狂补二进制知识,对于一个Web
狗的感觉太酸爽了
而且学校安排的实习无聊且浪费时间,写着Java Spring
和前端开发,但这明明是我不需要的-_-
今晚抽空测了一下熟悉的某站,发现了一个很少有人听说和利用的漏洞,就想放松一下,记录一下这个漏洞和实例,复习我久违的Web
o(╥﹏╥)o
CRLF漏洞简介
在 HTTP
的 Header
当中,状态行和首部中的每行以CRLF结束,首部与主体之间由一空行分隔
或者理解为首部最后一个字段有两个CRLF,首部和主体由两个CRLF分隔。
CRLF注入漏洞,是因为Web应用没有对用户输入做严格验证,导致攻击者可以输入一些恶意字符。攻击者一旦向请求行或首部中的字段注入恶意的CRLF,就能注入一些首部字段或报文主体,并在响应中输出,所以又称为HTTP响应拆分漏洞(HTTP Response Splitting)。
CRLF 指的是回车符(CR,ASCII 13,\r,%0d) 和换行符(LF,ASCII 10,\n,%0a)。
在HTTP规范中,行应该使用CRLF来结束。首部与主体由两个CRLF分隔,浏览器根据这两个CRLF来获取HTTP内容并显示
POST / HTTP/1.1 |
再看看他的十六进制表示
可知他的 POST
请求当中头部和消息体是通过两个\r\n
进行分隔的
头部之间是通过一个\r\n
进行分隔的
知道 HTTP
数据包是这么构成的就可以了,接下来讲一下实际的挖掘方法
例子
一般而言,CRLF
漏洞多见于可控HTTP
头部的属性,这里举个最常见的例子,302重定向
如果说,一个URL
想要对重定向到一个新的地址,他可能会把参数放到GET
请求中的query
部位,或者放到POST
数据当中,很明显这两个点是很容易控制的,比如:
http://xxx.xxx.com?goto=www.baidu.com
其中如果进行跳转的话,则会在302跳转包中新增一个字段
Location: www.baidu.com
如果此时程序员没有对跳转的地址进行过滤的话,就很有可能让我们实现插入CRLF
从而实现头部注入,从而实现下面几个点的漏洞,这里拿一个真实的站点做演示
会话固定漏洞
如果我们在原跳转地址后面写上%0d%0a
进行换行,插入自定义的字段Set-cookie:JSPSESSID%3DA2u13
,然后经过解码之后,会在302跳转中看到我们的插入的Set-cookie
已经生效了
但下面还有个原本的Set-cookie
怎么办呢,办法是把他通过两个CRLF
挤到body
当中,但是又因为是GET
请求,所以被挤下去的头部也会被服务器忽略,从而实现了会话固定
对于POST
请求而言,原理一致,只要能让服务器解析原本的POST
即可
XSS漏洞
由于我这个站是只能接受GET
请求,对于POST
请求会忽略消息体,所以我们用一个例子来展示一下
同样是http://xxx.xxx.com?goto=www.baidu.com
如果此时我们使用两个CRLF
来划开消息头部和消息体
http://xxx.xxx.com?goto=www.baidu.com%0d%0aX-XSS-Protection%3A%200%0d%0a%0d%0a%3Cimg%20src%3D%23%20onerror%3Dalert(1)%3B%20%2F%3E
此时就会产生这种情况
HTTP/1.1 302 Moved Temporarily |
是不是我们插入的XSS
语句进入了消息体当中?
而且插入了X-XSS-Protection: 0
,对于一部分浏览器会关闭XSS-filter
,就可以利用
但是这种利用还是有些鸡肋的,毕竟302跳转是没有POST
消息体的
所以说,只要是能找到一个POST
请求,并且头部可控无CRLF
过滤时,就可以用来打XSS
绕过CSP
如果说你很幸运,发现可控的头部正好位于Content-Security-Policy
的上方
那么就可以利用上面的采用两个CRLF
把CSP
挤到消息体当中,从而使CSP
失效
如果CSP
下面有部分需要数据不能被挤到消息体当中时,可以提前把数据写到可控头部字段值中
不过这也是一个假想,毕竟这种站太少了,如果能遇到的话,可以利用CRLF
漏洞完美绕过CSP
的防护
修复措施
很简单,把传入头部字段的所有数据都过滤\r和\n
即可