Added Cache Poisining lesson as a staged lesson to HTTP Splitting lesson.

git-svn-id: http://webgoat.googlecode.com/svn/trunk@40 4033779f-a91e-0410-96ef-6bf7bf53c507
This commit is contained in:
sherif.fathy 2006-12-23 00:24:47 +00:00
parent 9f76aeb38f
commit 7acbacbe61
2 changed files with 129 additions and 38 deletions

View File

@ -1,6 +1,8 @@
package org.owasp.webgoat.lessons;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import org.apache.ecs.*;
@ -22,6 +24,8 @@ import org.owasp.webgoat.session.WebSession;
public class HttpSplitting extends LessonAdapter {
private final static String LANGUAGE = "language";
private final static String REDIRECT = "fromRedirect";
private static String STAGE = "stage";
/**
* Description of the Method
@ -41,35 +45,19 @@ public class HttpSplitting extends LessonAdapter {
setContent(form);
}
protected Element createContent(WebSession s)
protected Element doHTTPSplitting(WebSession s)
{
ElementContainer ec = new ElementContainer();
String lang = null;
try
{
//add the text
ec.addElement( new StringElement( "Search by country : " ) );
lang = URLDecoder.decode(s.getParser().getRawParameter( LANGUAGE, "" )) ;
//add the search by field
Input input = new Input( Input.TEXT, LANGUAGE, lang.toString() );
ec.addElement( input );
Element b = ECSFactory.makeButton( "Search!" );
ec.addElement( b );
}
catch (Exception e)
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
ec.addElement(createAttackEnvironment(s));
lang = URLDecoder.decode(s.getParser().getRawParameter( LANGUAGE, "" ), "UTF-8") ;
//Check if we are coming from the redirect page
String fromRedirect = s.getParser().getStringParameter ( "fromRedirect" , "");
String fromRedirect = s.getParser().getStringParameter ( "fromRedirect" , "");
if ( lang.length() != 0 && fromRedirect.length() != 0 )
{
//Split by the line separator line.separator is platform independant
@ -81,26 +69,117 @@ public class HttpSplitting extends LessonAdapter {
if (Arrays.binarySearch(arrTokens, "CONTENT-LENGTH: 0") >= 0 &&
Arrays.binarySearch(arrTokens, "HTTP/1.1 200 OK") >= 0 )
{
try
{
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
out.print(lang.substring(lang.indexOf("HTTP/1.1")));
out.flush();
out.close();
//we gotta set it manually here so that we don't throw an exception
getLessonTracker(s).setCompleted(true);
}
catch(Exception e)
{
e.printStackTrace();
}
makeSuccess( s );
PrintWriter out = new PrintWriter(s.getResponse().getOutputStream());
out.print(lang.substring(lang.indexOf("HTTP/1.1")));
out.flush();
out.close();
//we gotta set it manually here so that we don't throw an exception
getLessonTracker(s).setCompleted(true);
//makeSuccess( s );
getLessonTracker(s).setStage(2);
StringBuffer msg = new StringBuffer();
msg.append("Good Job! ");
msg.append("This lesson has detected your successfull attack, ");
msg.append("time to elevate your attack to a higher level. ");
msg.append("Try again and add Last-Modified header, intercept");
msg.append("the reply and replace it with a 304 reply.");
s.setMessage(msg.toString());
}
}
}
catch (Exception e)
{
s.setMessage( "Error generating " + this.getClass().getName() );
e.printStackTrace();
}
return ( ec );
}
protected Element createContent(WebSession s)
{
return super.createStagedContent(s);
}
protected Element doStage1( WebSession s ) throws Exception
{
return doHTTPSplitting( s );
}
protected Element doStage2( WebSession s ) throws Exception
{
return doCachePoisining( s);
}
protected Element createAttackEnvironment(WebSession s ) throws Exception
{
ElementContainer ec = new ElementContainer();
String lang = null;
ec.addElement( new StringElement( "Search by country : " ) );
lang = URLDecoder.decode(s.getParser().getRawParameter( LANGUAGE, "" ), "UTF-8") ;
//add the search by field
Input input = new Input( Input.TEXT, LANGUAGE, lang.toString() );
ec.addElement( input );
Element b = ECSFactory.makeButton( "Search!" );
ec.addElement( b );
return ec;
}
protected Element doCachePoisining( WebSession s ) throws Exception
{
ElementContainer ec = new ElementContainer();
try
{
ec.addElement("Now that you have successfully performed an HTTP Splitting, now try to poison" +
" the victim's cache using. Type 'restart' in the input field if you wish to " +
" to return to the HTTP Splitting lesson.<br><br>");
if ( s.getParser().getRawParameter( LANGUAGE, "YOUR_NAME" ).equals("restart"))
{
getLessonTracker(s).getLessonProperties().setProperty(STAGE,"1");
return( doHTTPSplitting(s));
}
ec.addElement(createAttackEnvironment(s));
String lang = URLDecoder.decode(s.getParser().getRawParameter( LANGUAGE, "" ), "UTF-8") ;
String fromRedirect = s.getParser().getStringParameter ( REDIRECT , "");
if ( lang.length() != 0 && fromRedirect.length() != 0 )
{
String lineSep = System.getProperty("line.separator");
String dateStr = lang.substring(lang.indexOf("Last-Modified:") + "Last-Modified:".length(),
lang.indexOf(lineSep, lang.indexOf("Last-Modified:") ));
if (dateStr.length() != 0 )
{
Calendar cal = Calendar.getInstance();
DateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
if (sdf.parse(dateStr.trim()).after(cal.getTime()))
{
makeSuccess(s);
getLessonTracker(s).setStage(2);
}
}
}
}
catch (Exception ex)
{
ec.addElement( new P().addElement( ex.getMessage() ) );
}
return ec;
}
protected Category getDefaultCategory()
{
return AbstractLesson.GENERAL;
@ -113,7 +192,7 @@ public class HttpSplitting extends LessonAdapter {
hints.add( "Use CR (%0d) and LF (%0a) for a new line" );
hints.add( "The Content-Length: 0 will tell the server that the first request is over." );
hints.add( "A 200 OK message looks like this: HTTP/1.1 200 OK" );
hints.add( "Try French%0d%0aContent-Length: 0%0d%0aHTTP/1.1 200 OK" );
hints.add( "Try language=?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<html>hahahahaha</html>" );
return hints;
}

View File

@ -13,7 +13,18 @@ The attacker passes malacious code to the web server together with normal input.
A victim application will not be checking for 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
but also allows them to create additional responses entirely under their control.<br>
The effect of an HTTP Splitting attack is maximized when accompanied with a Cache Poisining. The goal of<br>
Cache Poisining attack is to poison the cache of the victim by fooling the cache to believe that the page<br>
hijacked using the HTTP splitting is a good one and it is indeed the server's copy.<br>
The attack happens using the HTTP Splitting attack plus adding the <b>Last-Modified:</b> header and setting it<br>
to a future date. This will force the browser to send <b>If-Modified-Since</b> request header, which gives the attacker<br>
the chance to intercept the server's reply and replace it with a '304 Not Modified' reply. A sample of a 304 response is:<br>
HTTP/1.1 304 Not Modified
Date: Fri, 30 Dec 2005 17:32:47 GMT
</div>
<p><b>General Goal(s):</b> </p>
<!-- Start Instructions -->
@ -22,4 +33,5 @@ but also allows them to create additional responses entirely under their control
* You should be able to use the CR (%0d) and LF (%0a) to exploit the attack.<br>
* Your excercise should be to force the server to send a 200 OK. <br>
* If the screen changed as an effect to your attack, just go back to the homepage where you will find the lesson completed if you successfully exploited the attack.
<!-- Stop Instructions -->