531 lines
18 KiB
Java
531 lines
18 KiB
Java
|
|
package org.owasp.webgoat.lessons;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import org.apache.ecs.Element;
|
|
import org.apache.ecs.ElementContainer;
|
|
import org.apache.ecs.StringElement;
|
|
import org.apache.ecs.html.IMG;
|
|
import org.apache.ecs.html.Input;
|
|
import org.apache.ecs.html.TD;
|
|
import org.apache.ecs.html.TR;
|
|
import org.apache.ecs.html.Table;
|
|
import org.apache.ecs.xhtml.br;
|
|
import org.owasp.webgoat.session.ECSFactory;
|
|
import org.owasp.webgoat.session.ParameterNotFoundException;
|
|
import org.owasp.webgoat.session.ValidationException;
|
|
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 - 20014 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 https://github.com/WebGoat/WebGoat, a repository for free software
|
|
* projects.
|
|
*
|
|
* For details, please see http://webgoat.github.io
|
|
*
|
|
* @author Yiannis Pavlosoglou <a href="http://code.google.com/p/webgoat">WebGoat</a>
|
|
* @created December 05, 2009
|
|
*/
|
|
public class OffByOne extends LessonAdapter
|
|
{
|
|
private final static String[] price_plans = { "$1.99 - 1 hour ", "$5.99 - 12 hours", "$9.99 - 24 hours"};
|
|
|
|
private final static String ROOM_NUMBER = "room_no";
|
|
|
|
private final static String FIRST_NAME = "first_name";
|
|
|
|
private final static String LAST_NAME = "last_name";
|
|
|
|
private final static String PRICE_PLAN = "price_plan";
|
|
|
|
private final static IMG LOGO = new IMG("images/logos/seleucus.png").setAlt("Seleucus Ltd")
|
|
.setBorder(0).setHspace(0).setVspace(0);
|
|
|
|
/**
|
|
* <p>The main method for creating content, implemented
|
|
* from the the LessonAdapter class.</p>
|
|
*
|
|
* <p>This particular "Off-by-One" lesson belonging in
|
|
* the category of "Buffer Overflows" carries three
|
|
* steps.</p>
|
|
*
|
|
* @param s
|
|
* WebSession
|
|
* @return Description of the Return Value
|
|
*/
|
|
protected Element createContent(WebSession s)
|
|
{
|
|
ElementContainer ec = new ElementContainer();
|
|
|
|
try
|
|
{
|
|
if(isFirstStep(s))
|
|
{
|
|
ec.addElement(makeFirstStep(s));
|
|
}
|
|
else
|
|
{
|
|
if (isSecondStep(s))
|
|
{
|
|
ec.addElement(makeSecondStep(s));
|
|
}
|
|
else
|
|
{
|
|
ec.addElement(makeThirdStep(s));
|
|
}
|
|
}
|
|
} catch (Exception e)
|
|
{
|
|
s.setMessage("Error generating " + this.getClass().getName());
|
|
e.printStackTrace();
|
|
}
|
|
|
|
return (ec);
|
|
}
|
|
|
|
/**
|
|
* <p>Returns the Buffer Overflow category for this
|
|
* lesson.</p>
|
|
*
|
|
* @return The category value
|
|
*/
|
|
protected Category getDefaultCategory()
|
|
{
|
|
return Category.BUFFER_OVERFLOW;
|
|
}
|
|
|
|
/**
|
|
* <p>Returns the hints as a List of Strings
|
|
* for this lesson.</p>
|
|
*
|
|
* @return The hints values
|
|
*/
|
|
public List<String> getHints(WebSession s)
|
|
{
|
|
List<String> hints = new ArrayList<String>();
|
|
hints.add("While registering for Internet usage, see where else your details are used during the registration process.");
|
|
hints.add("See which fields during the registration process, allow for really long input to be submitted.");
|
|
hints.add("Check for hidden form fields during registration");
|
|
hints.add("Typically, web-based buffer overflows occur just above the value of 2 to the power of a number. E.g. 1024 + 1, 2048 + 1, 4096 + 1");
|
|
hints.add("Overflow the room number field with 4096+1 characters and look for hidden fields");
|
|
hints.add("Enter the VIP name in the first and last name fields");
|
|
return hints;
|
|
}
|
|
|
|
/**
|
|
* <p>Get the default ranking within the "Buffer
|
|
* Overflow" category.</p>
|
|
*
|
|
* <p>Currently ranked to be the first lesson in
|
|
* this category.</p>
|
|
*
|
|
* @return The value of 5 as an Integer Object
|
|
*/
|
|
protected Integer getDefaultRanking()
|
|
{
|
|
return new Integer(5);
|
|
}
|
|
|
|
/**
|
|
* <p>Gets the title attribute for this lesson.</p>
|
|
*
|
|
* @return "Off-by-One Overflows"
|
|
*/
|
|
public String getTitle()
|
|
{
|
|
return ("Off-by-One Overflows");
|
|
}
|
|
|
|
/**
|
|
* yada, yada...
|
|
*/
|
|
public Element getCredits()
|
|
{
|
|
return super.getCustomCredits("Created by Yiannis Pavlosoglou ", LOGO);
|
|
}
|
|
|
|
/**
|
|
* <p>Based on the parameters currently with values, this method
|
|
* returns true if we are in the first step of this lesson.</p>
|
|
*
|
|
* @param s
|
|
* @return true if we are in the first step of the lesson.
|
|
*/
|
|
protected boolean isFirstStep(WebSession s)
|
|
{
|
|
String room = s.getParser().getRawParameter(ROOM_NUMBER, "");
|
|
String name = s.getParser().getRawParameter(FIRST_NAME, "");
|
|
String last = s.getParser().getRawParameter(LAST_NAME, "");
|
|
|
|
return (room.isEmpty() && name.isEmpty() && last.isEmpty() );
|
|
}
|
|
|
|
/**
|
|
* <p>Based on the parameters currently with values, this method
|
|
* returns true if we are in the second step of this lesson.</p>
|
|
*
|
|
* @param s
|
|
* @return true if we are in the second step of the lesson
|
|
*/
|
|
protected boolean isSecondStep(WebSession s)
|
|
{
|
|
String price = s.getParser().getRawParameter(PRICE_PLAN, "");
|
|
|
|
return price.isEmpty();
|
|
}
|
|
|
|
/**
|
|
* <p>Method for constructing the first step and returning it as
|
|
* an Element.</p>
|
|
*
|
|
* @param s
|
|
* @return The Element that is the first step.
|
|
*/
|
|
private Element makeFirstStep(WebSession s)
|
|
{
|
|
ElementContainer ec = new ElementContainer();
|
|
String param = "";
|
|
|
|
// Header
|
|
ec.addElement(new StringElement("In order to access the Internet, you need to provide us the following information:"));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
ec.addElement(new StringElement("Step 1/2"));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
|
|
ec.addElement(new StringElement("Ensure that your first and last names are entered exactly as they appear in the hotel's registration system."));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
|
|
// Table
|
|
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
|
|
|
|
if (s.isColor())
|
|
{
|
|
t.setBorder(1);
|
|
}
|
|
|
|
// First Name
|
|
try {
|
|
param = s.getParser().getStrictAlphaParameter(FIRST_NAME, 25);
|
|
} catch (ParameterNotFoundException e) {
|
|
param = "";
|
|
} catch (ValidationException e) {
|
|
param = "";
|
|
}
|
|
Input input = new Input(Input.TEXT, FIRST_NAME, param);
|
|
|
|
TR tr = new TR();
|
|
tr.addElement(new TD().addElement("First Name: "));
|
|
tr.addElement(new TD().addElement(input));
|
|
tr.addElement(new TD().addElement("*"));
|
|
t.addElement(tr);
|
|
tr = new TR();
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
t.addElement(tr);
|
|
|
|
// Last Name
|
|
try {
|
|
param = s.getParser().getStrictAlphaParameter(LAST_NAME, 25);
|
|
} catch (ParameterNotFoundException e) {
|
|
param = "";
|
|
} catch (ValidationException e) {
|
|
param = "";
|
|
}
|
|
input = new Input(Input.TEXT, LAST_NAME, param);
|
|
|
|
tr = new TR();
|
|
tr.addElement(new TD().addElement("Last Name: "));
|
|
tr.addElement(new TD().addElement(input));
|
|
tr.addElement(new TD().addElement("*"));
|
|
t.addElement(tr);
|
|
tr = new TR();
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
t.addElement(tr);
|
|
|
|
// Room Number
|
|
try {
|
|
param = s.getParser().getStrictAlphaParameter(ROOM_NUMBER, 25);
|
|
} catch (ParameterNotFoundException e) {
|
|
param = "";
|
|
} catch (ValidationException e) {
|
|
param = "";
|
|
}
|
|
input = new Input(Input.TEXT, ROOM_NUMBER, param);
|
|
|
|
tr = new TR();
|
|
tr.addElement(new TD().addElement("Room Number: "));
|
|
tr.addElement(new TD().addElement(input));
|
|
tr.addElement(new TD().addElement("*"));
|
|
t.addElement(tr);
|
|
tr = new TR();
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
t.addElement(tr);
|
|
|
|
// Submit
|
|
tr = new TR();
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(ECSFactory.makeButton("Submit")));
|
|
tr.addElement(new TD().addElement(" "));
|
|
t.addElement(tr);
|
|
|
|
ec.addElement(t);
|
|
|
|
// Footer
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
ec.addElement(new StringElement("* The above fields are required for login."));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
|
|
|
|
return ec;
|
|
}
|
|
|
|
/**
|
|
* <p>Method for constructing the second step and returning it as
|
|
* an Element.</p>
|
|
*
|
|
* @param s
|
|
* @return The Element that is the second step.
|
|
*/
|
|
private Element makeSecondStep(WebSession s)
|
|
{
|
|
ElementContainer ec = new ElementContainer();
|
|
String param = "";
|
|
|
|
// Header
|
|
ec.addElement(new StringElement("Please select from the following available price plans:"));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
ec.addElement(new StringElement("Step 2/2"));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
|
|
ec.addElement(new StringElement("Ensure that your selection matches the hours of usage, as no refunds are given for this service."));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
|
|
// Table
|
|
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
|
|
|
|
if (s.isColor())
|
|
{
|
|
t.setBorder(1);
|
|
}
|
|
|
|
|
|
// First Empty Row
|
|
TR tr = new TR();
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
t.addElement(tr);
|
|
|
|
// Price Plans
|
|
tr = new TR();
|
|
tr.addElement(new TD().addElement("Available Price Plans:"));
|
|
tr.addElement(new TD().addElement(ECSFactory.makePulldown(PRICE_PLAN, price_plans, price_plans[2], 1)));
|
|
tr.addElement(new TD().addElement(" "));
|
|
t.addElement(tr);
|
|
|
|
// Submit
|
|
tr = new TR();
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(ECSFactory.makeButton("Accept Terms")));
|
|
tr.addElement(new TD().addElement(" "));
|
|
t.addElement(tr);
|
|
|
|
ec.addElement(t);
|
|
ec.addElement("\r\n");
|
|
|
|
// Hidden Form Fields
|
|
param = s.getParser().getStringParameter(LAST_NAME, "");
|
|
Input input = new Input(Input.HIDDEN, LAST_NAME, param);
|
|
ec.addElement(input);
|
|
ec.addElement("\r\n");
|
|
|
|
param = s.getParser().getStringParameter(FIRST_NAME, "");
|
|
input = new Input(Input.HIDDEN, FIRST_NAME, param);
|
|
ec.addElement(input);
|
|
ec.addElement("\r\n");
|
|
|
|
param = s.getParser().getStringParameter(ROOM_NUMBER, "");
|
|
input = new Input(Input.HIDDEN, ROOM_NUMBER, param);
|
|
ec.addElement(input);
|
|
ec.addElement("\r\n");
|
|
|
|
|
|
// Footer
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
ec.addElement(new StringElement("By Clicking on the above you accept the terms and conditions."));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
|
|
|
|
return ec;
|
|
}
|
|
|
|
/**
|
|
* <p>Method for constructing the third step and returning it as
|
|
* an Element.</p>
|
|
*
|
|
* @param s
|
|
* @return The Element that is the third step.
|
|
*/
|
|
private Element makeThirdStep(WebSession s)
|
|
{
|
|
ElementContainer ec = new ElementContainer();
|
|
String param1 = "";
|
|
String param2 = "";
|
|
String param3 = "";
|
|
|
|
// Header
|
|
ec.addElement(new StringElement("You have now completed the 2 step process and have access to the Internet"));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
ec.addElement(new StringElement("Process complete"));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
|
|
ec.addElement(new StringElement("Your connection will remain active for the time allocated for starting now."));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
|
|
// Table
|
|
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("90%").setAlign("center");
|
|
|
|
if (s.isColor())
|
|
{
|
|
t.setBorder(1);
|
|
}
|
|
|
|
|
|
// First Empty Row
|
|
TR tr = new TR();
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
t.addElement(tr);
|
|
|
|
// Price Plans
|
|
tr = new TR();
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
t.addElement(tr);
|
|
|
|
// Submit
|
|
tr = new TR();
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
tr.addElement(new TD().addElement(" "));
|
|
t.addElement(tr);
|
|
|
|
ec.addElement(t);
|
|
ec.addElement("\r\n");
|
|
|
|
// Hidden Form Fields
|
|
param1 = s.getParser().getStringParameter(LAST_NAME, "");
|
|
Input input = new Input(Input.HIDDEN, "a", param1);
|
|
ec.addElement(input);
|
|
ec.addElement("\r\n");
|
|
|
|
param2 = s.getParser().getStringParameter(FIRST_NAME, "");
|
|
input = new Input(Input.HIDDEN, "b", param2);
|
|
ec.addElement(input);
|
|
ec.addElement("\r\n");
|
|
|
|
param3 = s.getParser().getStringParameter(ROOM_NUMBER, "");
|
|
input = new Input(Input.HIDDEN, "c", param3);
|
|
ec.addElement(input);
|
|
ec.addElement("\r\n");
|
|
|
|
// And finally the check...
|
|
if(param3.length() > 4096)
|
|
{
|
|
ec.addElement(new Input(Input.hidden, "d", "Johnathan"));
|
|
ec.addElement("\r\n");
|
|
ec.addElement(new Input(Input.hidden, "e", "Ravern"));
|
|
ec.addElement("\r\n");
|
|
ec.addElement(new Input(Input.hidden, "f", "4321"));
|
|
ec.addElement("\r\n");
|
|
|
|
ec.addElement(new Input(Input.hidden, "g", "John"));
|
|
ec.addElement("\r\n");
|
|
ec.addElement(new Input(Input.hidden, "h", "Smith"));
|
|
ec.addElement("\r\n");
|
|
ec.addElement(new Input(Input.hidden, "i", "56"));
|
|
ec.addElement("\r\n");
|
|
|
|
ec.addElement(new Input(Input.hidden, "j", "Ana"));
|
|
ec.addElement("\r\n");
|
|
ec.addElement(new Input(Input.hidden, "k", "Arneta"));
|
|
ec.addElement("\r\n");
|
|
ec.addElement(new Input(Input.hidden, "l", "78"));
|
|
ec.addElement("\r\n");
|
|
|
|
ec.addElement(new Input(Input.hidden, "m", "Lewis"));
|
|
ec.addElement("\r\n");
|
|
ec.addElement(new Input(Input.hidden, "n", "Hamilton"));
|
|
ec.addElement("\r\n");
|
|
ec.addElement(new Input(Input.hidden, "o", "9901"));
|
|
ec.addElement("\r\n");
|
|
|
|
s.setMessage("To complete the lesson, restart lesson and enter VIP first/last name");
|
|
|
|
}
|
|
if (("Johnathan".equalsIgnoreCase(param2) || "John".equalsIgnoreCase(param2)
|
|
|| "Ana".equalsIgnoreCase(param2) ||"Lewis".equalsIgnoreCase(param2))
|
|
&& ("Ravern".equalsIgnoreCase(param1) || "Smith".equalsIgnoreCase(param1)
|
|
|| "Arneta".equalsIgnoreCase(param1) ||"Hamilton".equalsIgnoreCase(param1)))
|
|
{
|
|
// :)
|
|
// Allows for mixed VIP names, but that's not really the point
|
|
makeSuccess(s);
|
|
}
|
|
|
|
// Footer
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
ec.addElement(new StringElement("We would like to thank you for your payment."));
|
|
ec.addElement(new br());
|
|
ec.addElement(new br());
|
|
|
|
return ec;
|
|
}
|
|
|
|
|
|
}
|