Recently I have came across with a new method of attacking web application which is called HTTP Response Splitting, aka CRLF Injection. (Well, it might not be a really new kind of attacking vector, still it is considered new to me) This kind of vulnerability is generally carried out in web applications by injecting malicious or unexpected characters in user input which is then used for a 302 Redirect, in the Location or Set-Cookie header. Failure of the application to properly sanitizing the input would cause further damages such as Cross Site Scripting (XSS), Cross User Defacement (this is a form of temporary defacement), Web Cache Poisoning, Browser Cache Poisoning, and so on.
A good web application should be smart enough to reject illegal user input specifically like CR (Carriage Return, also given by %0d or \r) and LF (Line Feed, also given by %0a or \n) characters. These characters not only give attackers control of the remaining headers and body of the response the application intends to send, but also allows them to create additional responses entirely under their control.
Now talking about CR and LF. HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all protocol elements except the entity-body. That is as per HTTP standard, headers are separated by on CRLF and the response’s headers are separated from its body by two. Therefore, the failure to remove CRs and LFs allows the attacker to set arbitrary headers, take control of the body, or break the response into two or more separate responses (hence the name).
Now let’s move on to demonstrate how to launch an HTTP Response Splitting attack. Normally we will make use of those webpages that allows URL redirection, for instance Language redirection. Think you should ever come across with those sites that asking you to make language selection before you proceed to the further inner webpages. That’s our babes! Instead of choosing languages such as English, we send a value, which makes use of URL-encoded CRLF sequences to terminate the current response, and shape an additional one:
/redir_lang.php?lang=foobar%0d%0aContent-Length:%200%0d%0a
%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html
%0d%0aContent-Length:%2019%0d%0a
%0d%0a%3Chtml%3EHacked%3C/html%3E (all in one line)
This results following headers being sent to the web server:
HTTP/1.1 302 Moved Temporarily
Date: Mon, 10 Dec 2007 20:00:20 GMT
Location: http://victim/redir_lang.php?lang=foobar
Content-Length: 0HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 19<html>Hacked</html>
The target would believe that the first request is matched to the first response:
HTTP/1.1 302 Moved Temporarily
Date: Mon, 10 Dec 2007 20:00:20 GMT
Location: http://victim/redir_lang.php?lang=foobar
Content-Length: 0
And the second request (to /anything.html) is matched to the second response:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 19<html>Hacked</html>
Okay, for the conclusion, to make life easier, here’s my silly yet KISS methodology:
For redirection response splitting:
- Locate a redirect on the site. You can find them by manual inspection.
- See what kind of redirect it is by slowing it down with burp proxy with all server responses turned on (turn off the text bullet).
- If it’s a META it’s not vulnerable (may be to XSS but not to response splitting). Same with JavaScript redirection. If it’s 301, 302 or 304, chances are it’s vulnerable.
- Next replace the “http://victim….” with “%0d%0a[www.whatever]….” and hit the redirection again. If you see that it’s changed the output from the %0d%0a to an actual CR/LF there is a very high probability that it’s vulnerable.
- Lastly try a full header injection with something like %0d%0aContent-Type:%20text/html%0d%0a…
Powered by ScribeFire.