ryancblack/webgoat

HTTP splitting attack is demonstrated on a code not vulnerable to splitting

Opened this issue · 32 comments

HTTP splitting attack in WebGoat is demonstrated on a code, which is actually 
not vulnerable to HTTP splitting itself (at least not in common today's 
browsers). This makes it confusing to the students.

After all right input leads to marking the test as completed, but without 
possibility to actually see the issue happening, it makes it really hard for 
newbies to understand the problem. It is not possible to see the splitted 
output using any recommended tools (WebScarab, Burpsuite, Wireshark ...)

This would be equivalent of starting teaching SQL Injection on example of Blind 
SQL Injection - for first touch it would be difficult to understand what is 
happening.

I would say using the redirection as first touch example is bit unfortunate as 
it is bringing another complexity and students are not sure on what to focus 
first - the POST? The redirected GET? Bunch of other files downloaded. I would 
recommend to demonstrate it first on some straight-forward header field - for 
example Content-Language. Something like:
<?php
        header("Content-Language: ".$_GET['language']);
        echo "<html>Entered value was language=" . $_GET["language"] . "</html>";
?>



What steps will reproduce the problem?
1. Start webgoat
2. start lesson for http splitting
3. enter language as: en%0d%0a%0d%0aHTTP/1.1+200+OK

Expected response from the server:
HTTP/1.1 302 Moved Temporarily

Server: Apache-Coyote/1.1

Location: http://localhost:8080/webgoat/attack?Screen=79&menu=100&language=en

HTTP/1.1 200 OK
Content-Type: text/html;charset=ISO-8859-1

Content-Length: 0

Date: Mon, 18 Apr 2011 23:41:16 GMT


Instead you see:
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: 
http://localhost:8080/webgoat/attack?Screen=79&menu=100&language=en%0d%0a%0d%0aH
TTP/1.1+200+OK
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Mon, 18 Apr 2011 23:41:16 GMT


Tested with webgoat 5.3 R1 on Fedora Linux 14.

From many discussions on the internet I can see that this one is causing a lot 
of discussions and confusion. As a result people copy paste existing solution 
instead of trying and constructing one themselves:
https://lists.owasp.org/pipermail/owasp-webgoat/2007-November/000437.html
https://lists.owasp.org/pipermail/owasp-cincinnati/2008-July/000091.html
https://lists.owasp.org/pipermail/owasp-webgoat/2007-September/000433.html
https://lists.owasp.org/pipermail/owasp-webgoat/2008-April/000473.html

Good examples what the lesson should demonstrate:
http://projects.webappsec.org/w/page/13246931/HTTP-Response-Splitting
http://www.packetstormsecurity.org/papers/general/whitepaper_httpresponse.pdf

Original issue reported on code.google.com by michal.a...@gmail.com on 19 Apr 2011 at 1:36

Original comment by mayhe...@gmail.com on 19 Apr 2011 at 2:12

  • Changed state: Accepted
I believe the issue you are seeing is because you are entering the string 
required to exploit on a Windows platform not a Linux platform.

Linux uses only LF, not CR/LF so remove all %0d from your string and just use 
LF %0a.

Incidentally, this is mentioned in the Solution on the HTTP Splitting page.

HTH

Original comment by marc@4armed.com on 2 Jun 2011 at 11:04

same problem on windows platform.

Original comment by sunil86...@gmail.com on 4 Aug 2011 at 7:44

The issue is not that I would not pass the test. 
Test happily accepts my request (en%0d%0a%0d%0aHTTP/1.1+200+OK) and the 
training is marked as solved. 

The issue is you need to understand in advance what you are doing and why. It 
would be better to try and see in the response the real result of HTTP 
splitting attack/vulnerability. 

The page itself is not vulnerable to HTTP splitting, it will just test you know 
what HTTP splitting is and how to exploit it.

As I said difficulty to learn and understand the concepts of HTTP Splitting on 
such example test is equivalent of trying to learn what is SQL injection on a 
page which is vulnerable only to Blind SQL Injection.

Best regards
Michal Ambroz

Original comment by michal.a...@gmail.com on 4 Aug 2011 at 12:27

This is not a defect. Although some modern browsers are not vulnerable to this 
issues, there still some browsers which still are. If we agree that browsers 
are not vulnerable anymore then there is no need for this issue to exist. 
However, the issue still shows correctly what the techniques are of the attack, 
the video needs to be modified to reflect that though.

Original comment by sherif.fathy on 26 Apr 2012 at 5:34

  • Changed state: Fixed
Hello,
I am sorry you get me wrong.

I am not saying browsers are not vulnerable.
What I am saying is that the page is not vulnerable - please make it vulnerable 
so students can try and learn.

Best regards
Michal Ambroz

Original comment by michal.a...@gmail.com on 14 Jun 2012 at 1:37

Original comment by mayhe...@gmail.com on 14 Jun 2012 at 5:53

  • Changed state: Investigate
I think what the original bug reporter is getting at is that you don't actually 
ever see the injected content show up when you succeed part 1 of this lesson.

However in the yehg.net video walkthrough of this lesson (and other videos on 
youtube), they do get the page with the injected content from the split 
response appearing in their browser.

See:
http://yehg.net/lab/pr0js/training/view/owasp/webgoat/WebGoat_Simulation_General
/
http://www.youtube.com/watch?v=YbjPw9Wv_JY

Those videos show WebGoat 5.1 and 5.3 respectively.

The last Hint for part 1 of this lesson provides the full string to split the 
HTTP response. That string from the Hint sets the response's actual content as:

<html>Hacked!</html>

but when you use that string from the last Hint of part 1 of the lesson you 
never actually see a blank page with the text 'Hacked!' appear in your browser. 
 All you see is the red font success message appear on the WebGoat lesson page, 
and it moves you on to Cache Poisoning part.

This occurs for me with WebGoat 5.4 running on Tomcat 7 on Xubuntu using 
Firefox 13.0.1

(Don't know if this is related or not, but on my Linux setup, the lesson only 
succeeds using %0D%0A(but with the issue described above, no injected content 
shown).  Using %0A, the Linux LF, doesn't succeed the lesson on a Linux 
machine. This kinda makes sense though cause I believe the HTTP specifications 
requires that all platforms use CRLF so it shouldn't matter whether you're on 
Linux or Windows.)

Original comment by phil.gr...@gmail.com on 27 Jun 2012 at 12:07

Agree with the comments above. I am new to WebGoat and just wasted hours trying 
to have "Hacked" page to display in the HTTP Splitting lesson in vain until I 
came across this post. 

Now I know that it just won't... So don't bother if it doesn't work... 

p.s. also noticed another bug. Was getting 404 error message by the WebScarab 
until I phyisicall went to 
/webapps/WebGoat/images/menu_images and duplicated image 1x1.gif to be also 
1x1_open.gif

Hope this saves hours of trying for others. :)  

Original comment by muskystr...@gmail.com on 30 Jun 2012 at 9:15

[deleted comment]
[deleted comment]
Hi folks,

The location-header is indeed not vulnerable to HTTP Splitting.
To see the "Hacked" webpage, just enter the following URI:

http://127.0.0.1:8080/webgoat/attack?Screen=3&menu=100&fromRedirect=yes&language
=foobar%0AContent-Length:%200%0A%0AHTTP/1.1%20200%20OK%0AContent-Type:%20text/ht
ml%0AContent-Length:%2025%0A%0A%3Chtml%3EHacked%20J%3C/html%3E

Why don't you see this page when you do the POST request?

Because you have to URL-encode the following string:

foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type
:%20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0a<html>Hacked J</html>

When you are on Linux, then replace %0d%0a with %0a before you encode it!

After URL-encoding:

foobar%250aContent-Length%3A%25200%250a%250aHTTP%2F1.1%2520200%2520OK%250aConten
t-Type%3A%2520text%2Fhtml%250aContent-Length%3A%252025%250a%250a%3Chtml%3EHacked
%20J%3C%2Fhtml%3E


Should work!

Regards

Malik Mesellem
MME

Original comment by itsecga...@gmail.com on 13 Jul 2012 at 2:25

Original comment by mayhe...@gmail.com on 16 Jul 2012 at 12:40

  • Changed state: Accepted
the Hacked page does now show in my computer, webgoat is 5.4 , OS is Win7, 
Tomcat 7 is using Firefox 15.0.1


It appears that the hijacked page showed some time, but not I didn't redo that 
. 

what I enter is 
"foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Typ
e:%20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0a<html>Hacked J</html>", 
copied from the lesson's Solution. 

Original comment by rmn...@gmail.com on 11 Oct 2012 at 7:16

[deleted comment]
It doesn't show on mine either. Tried many times with various combinations, no 
joy.
I'm on Win XP, Firefox 15.0.1 and Webgoat 5.4

Original comment by jeremy...@gmail.com on 19 Oct 2012 at 8:07

[deleted comment]
I ran into the same problem. To look into whats really happening I ran 
Wireshark. What I found was the %0d and %0a I entered into the browser were not 
really converted to their ascii values. ie %0d still showed up as the three 
ascii characters %,0 and d. While the delimiters set by the browser showed up 
as single ascii characters with corresponding values of 0d or 0a. 
Now I being new to security, don't know how is it supposed to be. Is the 
browser too smart not to convert %0d to a single character or is it that the 
server is not HTTP splitting friendly! Please shed some light on this.

-Bear with my ignorance. I am learning.

Original comment by malikash...@gmail.com on 30 Oct 2012 at 1:57

Re: 18
Hello Malikash,
yes what you see in the wireshark is exactly the problem I am reporting here 
and you understand the HTTP splitting right.

For code vulnerable to HTTP splitting you expect that you send some attribute 
filled with url encoded new-lines (%0d%0a) and the vulnerable code will return 
it back injected to the response urldecoded form (=as ascii new-line and 
carriage return = two binary bytes with value of 0d and 0a).

In our example you would expect that new-lines (%0d%0a) filled to the attribute 
"language" will at some point be visible as ascii new-lines, but this is 
actually not happening.

Best regards
Michal Ambroz

Original comment by michal.a...@gmail.com on 1 Nov 2012 at 2:12

Hello all,

Any updates on this issue? I'm still having the same problem, the "hacked page" 
doesn't appear...

Using Win7/Firefox 10.0.12/Webgoat 5.4

Regards,
Pedro

Original comment by pedro.a....@gmail.com on 17 Jan 2013 at 12:20

Hi All,

I have been trying the same issue and hence i used the following string using 
Ubuntu/Firefox WTE/Webgoat 5.3

1.Http Splitting>>
foobar
Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 25

<html>Hacked by sunny</html>

*Used PHP charset encoder by yehg
foobar%0AContent-Length%3A%200%0A%0AHTTP%2F1.1%20200%20OK%0AContent-Type%3A%20te
xt%2Fhtml%0AContent-Length%3A%2025%0A%0A%3Chtml%3EHacked%20by%20sunny%3C%2Fhtml%
3E%0A

2. Chache poising
foobar
Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Mon, 27 Oct 2030 14:50:18 GMT
Content-Length: 47

<html>Hacked by sunny</html>

Yehg:-
foobar%0AContent-Length%3A%200%0A%0AHTTP%2F1.1%20200%20OK%0AContent-Type%3A%20te
xt%2Fhtml%0ALast-Modified%3A%20Mon%2C%2027%20Oct%202030%2014%3A50%3A18%20GMT%0AC
ontent-Length%3A%2047%0A%0A%3Chtml%3EHacked%20by%20sunny%3C%2Fhtml%3E

I hope it will help someone looking for answer.
Remeber,When you are using windows,replace %0a with %0d%0a before you encode it!


Original comment by sunnycho...@gmail.com on 3 Mar 2013 at 12:13

This string work to me in 5.3 but dont work in 5.4:

%0aContent-Length: 0%0a%0aHTTP/1.1 200 OK%0aContent-Type: 
text/html%0aLast-Modified:%0a%0a<html>TESTE</html>

What is the problem?

Original comment by Mint...@gmail.com on 29 Jun 2013 at 12:13

can this splitting method use to bypass proxy firewall ?

Original comment by unam...@gmail.com on 9 Oct 2013 at 5:19

Same behavior observed here...

Works as expected in 5.3 RC1 but not in 5.4.
In 5.3, I get redirected to the "hacked by yehg" message just like in the video.
In 5.4, we get a successful message with the green check...but not the expected 
redirection.
Very confusing for a newbie...What's could be the reason?

Original comment by midobenn...@gmail.com on 23 Oct 2013 at 3:18

[deleted comment]
I'd recommend either fixing this problem or removing this lesson entirely as it 
is the first attack lesson and continuous failure will seriously discourage 
students.

I've wasted hours on this!

Please increase the priority and resolve this one way or the other.

(FYI Hosted: WG 5.4, Tomcat 7.0, Debian 7.1  Attacked via: FireFox 
25.0.1/Windows and IceWeasel 22.0/Linux)

Original comment by jb...@godswind.org on 30 Nov 2013 at 4:50

Hey michal.ambroz@gmail.com,
I get what you are saying, even if no one else seems to get the issue.

To others,
Guys, the problem I and Michal faced is not that we are not getting the Hacked 
page. Its also not that we do not understand how the attack is working.

The thing is that once I submit the malformed URL, my computer sends this 
request to the server. The response that the server must return TWO header 
fields. And then when I send the second request, the second response should 
match up and the fake page must be shown.

Instead, when I send the first request, that entire malformed URL is used in 
the next redirect URL; and in the first response from the server, I do NOT see 
TWO headers. I just see 1 header (the 302 response header). Now when the 
browser sends the second response (containing the malformed URL), in the 
server's response I get back the "New " headers which were supposed to show up 
in the first response.

Now what it actually means is that (I am guessing this), that the attack is not 
actually happening. It is an IMITATED attack. The server is responding with 
only 1 header. But it should respond with two headers.

Note: By the way, I also tried to make a separate web page to make this attack 
work. But I am not able to. As already discussed, the browsers are smart enough 
not to encode %0a and so these letters are taken in their literal form and not 
as a line feed. So my best guess is that, modern browsers are just not 
susceptible to this attack.

Original comment by rahul300...@gmail.com on 18 Dec 2013 at 5:24

The solution for  HTTP SPLITTING part two (Stage 2: Cache Poisoning:) is not 
working..I followed the video of the solution. HHEELLPP!

Original comment by alexa4...@gmail.com on 29 Jan 2014 at 5:49

Hi everybody,

I am experiencing the same issue here. I am using WebGoat 5.4, Tomcat 7, 
Firefox 26 and Kali Linux 1.06. I am new on web app security and I don't know 
if I am going to a wrong conclusion, but here it goes:

First, I provided the following malformed string: 

foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type
:%20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0a<html>Hacked J</html>

The Post reuest end up like this:

POST /WebGoat/lessons/General/redirect.jsp?Screen=611&menu=100 HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:22.0) Gecko/20100101 
Firefox/22.0 Iceweasel/22.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: 
http://localhost/WebGoat/attack?Screen=611&menu=100&fromRedirect=yes&language=fo
obar%20Content-Length:%200%20%20HTTP/1.1%20200%20OK%20Content-Type:%20text/html%
20Content-Length:%2047%20%20%3Chtml%3EHacked%20J%3C/html%3E
Cookie: JSESSIONID=B1DC79F1618F8CCEA22FDCAC21E5E3D4
Authorization: Basic Z3Vlc3Q6Z3Vlc3Q=
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 236

language=foobar%250d%250aContent-Length%3A%25200%250d%250a%250d%250aHTTP%2F1.1%2
520200%2520OK%250d%250aContent-Type%3A%2520text%2Fhtml%250d%250aContent-Length%3
A%252047%250d%250a%250d%250a%3Chtml%3EHacked+J%3C%2Fhtml%3E&SUBMIT=Search%21

As we can see, firefox URL encoded the malformed string. The response I get for 
this request is as following:

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: 
http://localhost/WebGoat/attack?Screen=611&menu=100&fromRedirect=yes&language=fo
obar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%
20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0a<html>Hacked J</html>
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Thu, 30 Jan 2014 16:19:53 GMT

For me, it seems like the server url decoded the string, so the %0d%0a is 
interpreted as a string and not as a CR and LF. In order to bypass the 
browser's protection, I intercepted the post request with burp proxy and 
changed the body inserting the original malformed String. The new body of the 
post request becomes the following:

language=foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aCon
tent-Type:%20text/html%0d%0aContent-Length:%2047%0d%0a%0d%0a<html>Hacked 
J</html>&SUBMIT=Search%21

For this request, I've got the following response:

HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
Location: 
http://localhost/WebGoat/attack?Screen=611&menu=100&fromRedirect=yes&language=fo
obar  Content-Length: 0    HTTP/1.1 200 OK  Content-Type: text/html  
Content-Length: 47    <html>Hacked J</html>
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Thu, 30 Jan 2014 16:25:17 GMT

Now it seems that the server have sanitized the malformed string replacing the 
sequence %0d%0a with a space. I have also tried to substitute the sequence 
%0d%0a with just %0a in the malformed string, but the result was the same.

In addition to these testes, I have a question about the attack itself. When 
the malformed string is sent to the server, it is supposed to reply with a 
response that, in fact, represents two responses. The first response replies 
the original post request and the second response should reply a second 
request. Although the attack needs two requests, the attacker just sent one to 
the server. My question is, the second request that supposed to be answered by 
response controlled by the attacker is the Get request generated by the 
redirection?

Best Regards. 

Original comment by igorcomp...@gmail.com on 30 Jan 2014 at 4:35

Hey guys, I am writing again because I kept investigating the splitting attack 
on the webgoat 5.4. To understand better what was happening I decided to 
analyse the java source code. For my surprise, I found this function:

 74      protected Element doHTTPSplitting(WebSession s)
 75      {
 76          ElementContainer ec = new ElementContainer();
 77          String lang = null;
 78  
 79          try
 80          {
 81              ec.addElement(createAttackEnvironment(s));
 82              lang = URLDecoder.decode(s.getParser().getRawParameter(LANGUAGE, ""), "UTF-8");
 83  
 84              // Check if we are coming from the redirect page
 85              String fromRedirect = s.getParser().getStringParameter("fromRedirect", "");
 86  
 87              if (lang.length() != 0 && fromRedirect.length() != 0)
 88              {
 89                  
 90      
 91                  String[] arrTokens = lang.toString().toUpperCase().split("\r\n");
 92  
 93                  // Check if the user ended the first request and wrote the second malicious reply
 94                  if (arrTokens.length > 1)
 95                  {
 96                      HttpServletResponse res = s.getResponse();
 97                      res.setContentType("text/html");
 98  
 99                      StringBuffer msg = new StringBuffer();
100  
101                      msg.append("Good Job! ");
102                      msg.append("This lesson has detected your successful 
attack, ");
103                      msg.append("time to elevate your attack to a higher 
level. ");
104                      msg.append("Try again and add Last-Modified header, 
intercept");
105                      msg.append("the reply and replace it with a 304 
reply.");
106  
107                      s.setMessage(msg.toString());
108                      getLessonTracker(s).setStage(2);
109  
110  
111                      //makeSuccess(s);
112  
113                  }
114              }
115          } catch (Exception e)
116          {
117              s.setMessage("Error generating " + this.getClass().getName());
118              e.printStackTrace();
119          }
120          return (ec);
121      }

First, in the line 82 the function URL decodes the malformed string we have 
sent. This is necessary because the browser URL encodes the value of the lang 
parameter. Next, in the line 91, the resulting string is then splitted based on 
the sequence "\r\n". Based on the test in the line 94, we can understand the 
following points:

1 - No matter if we use linux or windows, to pass on the test we always have to 
build a malformed string using the sequence %0d%0a. If we replace %0d%0a by 
only %0a, then the split function in line 91 will result in just one component. 
Consequently, the test of line 94 will fail.

2 - To pass on the test we just need to provide any string based on the 
following pattern: %0d%0a"Any String" where "Any String" can be replaced by any 
string we like.

I lost precious hours of my life trying to see an attack that, in fact, is not 
happening at all. I believe that this should be warned to the users in order to 
save them some hours and frustration.

Original comment by igorcomp...@gmail.com on 30 Jan 2014 at 7:58

Wasted 3 hours today on this.

Original comment by iprintcl...@gmail.com on 28 Jun 2014 at 7:09

Same issue here, trying it on Windows Server 2012 with Chrome 36.0.1985.125. 

Wasted a lot of time, thinking about why I couldn't get this working. 

As a newbie trying to learn web security, this is a very discouraging and 
frustrating lesson 1. 

As others have said, this should be fixed so that the hacked page is actually 
shown, or atleast the user should be warned about this. 

Original comment by bahr.da...@gmail.com on 26 Jul 2014 at 3:41