Miscellaneous bug fixes
divide by zero, inaccurate discount and totals, reflection of user input git-svn-id: http://webgoat.googlecode.com/svn/trunk/webgoat@273 4033779f-a91e-0410-96ef-6bf7bf53c507
This commit is contained in:
@ -0,0 +1,297 @@
|
||||
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 javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.ecs.*;
|
||||
import org.apache.ecs.html.*;
|
||||
import org.owasp.webgoat.session.ECSFactory;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
*
|
||||
* This file is part of WebGoat, an Open Web Application Security Project
|
||||
* utility. For details, please see http://www.owasp.org/
|
||||
*
|
||||
* Copyright (c) 2002 - 2007 Bruce Mayhew
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
* Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Getting Source ==============
|
||||
*
|
||||
* Source for this application is maintained at code.google.com, a repository
|
||||
* for free software projects.
|
||||
*
|
||||
* For details, please see http://code.google.com/p/webgoat/
|
||||
*
|
||||
* @author Sherif Koussa <a href="http://www.macadamian.com">Macadamian Technologies.</a>
|
||||
* @created September 30, 2006
|
||||
*/
|
||||
|
||||
public class HttpSplitting extends SequentialLessonAdapter
|
||||
{
|
||||
|
||||
private final static String LANGUAGE = "language";
|
||||
|
||||
private final static String REDIRECT = "fromRedirect";
|
||||
|
||||
private static String STAGE = "stage";
|
||||
|
||||
private final static IMG MAC_LOGO = new IMG("images/logos/macadamian.gif").setAlt(
|
||||
"Macadamian Technologies").setBorder(0).setHspace(0).setVspace(0);
|
||||
|
||||
/**
|
||||
* Description of the Method
|
||||
*
|
||||
* @param s Current WebSession
|
||||
*/
|
||||
public void handleRequest(WebSession s)
|
||||
{
|
||||
//Setting a special action to be able to submit to redirect.jsp
|
||||
Form form = new Form("/WebGoat/lessons/General/redirect.jsp?"
|
||||
+ "Screen=" + String.valueOf(getScreenId()) + "&menu="
|
||||
+ getDefaultCategory().getRanking().toString(), Form.POST)
|
||||
.setName("form").setEncType("");
|
||||
|
||||
form.addElement(createContent(s));
|
||||
|
||||
setContent(form);
|
||||
}
|
||||
|
||||
|
||||
protected Element doHTTPSplitting(WebSession s)
|
||||
{
|
||||
ElementContainer ec = new ElementContainer();
|
||||
String lang = null;
|
||||
|
||||
try
|
||||
{
|
||||
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", "");
|
||||
|
||||
if (lang.length() != 0 && fromRedirect.length() != 0)
|
||||
{
|
||||
//Split by the line separator line.separator is platform independant
|
||||
String lineSep = System.getProperty("line.separator");
|
||||
String[] arrTokens = lang.toString().toUpperCase().split(
|
||||
lineSep);
|
||||
|
||||
//Check if the user ended the first request and wrote the second malacious reply
|
||||
|
||||
if (Arrays.binarySearch(arrTokens, "CONTENT-LENGTH: 0") >= 0
|
||||
&& Arrays.binarySearch(arrTokens, "HTTP/1.1 200 OK") >= 0)
|
||||
{
|
||||
HttpServletResponse res = s.getResponse();
|
||||
res.setContentType("text/html");
|
||||
PrintWriter out = new PrintWriter(res.getOutputStream());
|
||||
String message = lang.substring(lang.indexOf("<html>"));
|
||||
|
||||
out.print(message);
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
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;
|
||||
|
||||
if (getLessonTracker(s).getStage() == 1)
|
||||
{
|
||||
ec.addElement(new H3("Stage 1: HTTP Splitting:<br><br>"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ec.addElement(new H3("Stage 2: Cache Poisoning:<br><br>"));
|
||||
}
|
||||
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
|
||||
{
|
||||
s
|
||||
.setMessage("Now that you have successfully performed an HTTP Splitting, now try to poison"
|
||||
+ " the victim's cache. 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ec.addElement(new P().addElement(ex.getMessage()));
|
||||
}
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
||||
protected Category getDefaultCategory()
|
||||
{
|
||||
return Category.GENERAL;
|
||||
}
|
||||
|
||||
|
||||
protected List<String> getHints(WebSession s)
|
||||
{
|
||||
|
||||
List<String> hints = new ArrayList<String>();
|
||||
hints.add("Enter a language for the system to search by.");
|
||||
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: language=?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>Insert undesireable content here</html>");
|
||||
hints
|
||||
.add("Cache Poisoning starts with including 'Last-Modified' header in the hijacked page and setting it to a future date.");
|
||||
hints
|
||||
.add("Try language=?foobar%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aLast-Modified:%20Mon,%2027%20Oct%202003%2014:50:18%20GMT%0d%0aContent-Length:%2047%0d%0a%0d%0a<html>Insert undesireable content here</html>");
|
||||
hints
|
||||
.add("'Last-Modified' header forces the browser to send a 'If-Modified-Since' header. Some cache servers will take the bait and keep serving the hijacked page");
|
||||
hints
|
||||
.add("Try to intercept the reply and add HTTP/1.1 304 Not Modified0d%0aDate:%20Mon,%2027%20Oct%202030%2014:50:18%20GMT");
|
||||
return hints;
|
||||
|
||||
}
|
||||
|
||||
private final static Integer DEFAULT_RANKING = new Integer(20);
|
||||
|
||||
|
||||
protected Integer getDefaultRanking()
|
||||
{
|
||||
return DEFAULT_RANKING;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the title attribute of the HelloScreen object
|
||||
*
|
||||
* @return The title value
|
||||
*/
|
||||
public String getTitle()
|
||||
{
|
||||
return ("HTTP Splitting");
|
||||
}
|
||||
|
||||
|
||||
public Element getCredits()
|
||||
{
|
||||
return super.getCustomCredits("Created by Sherif Koussa ", MAC_LOGO);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user