package org.owasp.webgoat.lessons;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement;
import org.apache.ecs.html.A;
import org.apache.ecs.html.B;
import org.apache.ecs.html.Div;
import org.apache.ecs.html.Form;
import org.apache.ecs.html.H2;
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.html.TextArea;
import org.apache.ecs.xhtml.style;
import org.owasp.webgoat.session.DatabaseUtilities;
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 Reto Lippuner, Marcel Wirth
* @created April 8, 2008
*/
public class SessionFixation extends SequentialLessonAdapter
{
private final String mailTo = "jane.plane@owasp.org";
private final String mailFrom = "admin@webgoatfinancial.com";
private final String mailTitel = "Check your account";
private final String MAILCONTENTNAME = "mailContent";
private final static String USER = "user3";
private final static String PASSWORD = "pass3";
private final static String LOGGEDIN = "loggedin3";
private final static String LOGGEDINUSER = "loggedInUser3";
private final static Random random = new Random(System.currentTimeMillis());
private String sid = "";
/**
* Creates Staged WebContent
*
* @param s
*/
protected Element createContent(WebSession s)
{
if(sid.equals("") && getLessonTracker(s).getStage() > 2 )
{
getLessonTracker(s).setStage(1);
}
String sid = s.getParser().getStringParameter("SID","");
if (!sid.equals(""))
{
this.sid = sid;
}
if(!s.getParser().getStringParameter("Restart", "").equals(""))
{
s.add(LOGGEDIN, "false");
s.add("SID","");
this.sid = "";
}
if (getLessonTracker(s).getStage() == 3)
{
s.add("SID", sid);
if (!sid.equals(""))
{
s.add("SID", sid);
}
else
{
String randomSid = randomSIDGenerator();
s.add("SID", randomSid);
this.sid = randomSid;
System.out.println("RANDOMSID " + randomSid);
}
String name = s.getParser().getStringParameter(USER, "");
String password = s.getParser().getStringParameter(PASSWORD, "");
if(correctLogin(name, password, s))
{
getLessonTracker(s).setStage(4);
sid="";
s.add(LOGGEDIN, "true");
s.add(LOGGEDINUSER, name);
s.setMessage("You completed stage 3!");
}
}
if(getLessonTracker(s).getStage() == 4)
{
if (sid.equals("NOVALIDSESSION"))
{
System.out.println("STAGE 5");
getLessonTracker(s).setStage(5);
}
}
if (getLessonTracker(s).getStage() == 2)
{
if (!sid.equals(""))
{
s.add("SID", sid);
getLessonTracker(s).setStage(3);
s.setMessage("You completed stage 2!");
}
}
String mailContent = s.getParser().getRawParameter(MAILCONTENTNAME, "");
if (!mailContent.equals(""))
{
s.add(MAILCONTENTNAME, mailContent);
}
if ((mailContent.contains("&SID=") || mailContent.contains("?SID=")) && getLessonTracker(s).getStage() == 1)
{
getLessonTracker(s).setStage(2);
s.setMessage("You completed stage 1!");
}
return super.createStagedContent(s);
}
/**
* Gets the category attribute of the RoleBasedAccessControl object
*
* @return The category value
*/
protected ElementContainer doStage1(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec.addElement(createStage1Content(s));
return ec;
}
@Override
protected Element doStage2(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement(createStage2Content(s));
return ec;
}
private Element createStage2Content(WebSession s)
{
ElementContainer ec = new ElementContainer();
String mailHeader = "Mail From: admin@webgoatfinancial.com
";
String mailContent = (String) s.get(MAILCONTENTNAME);
//Reset Lesson if server was shut down
if(mailContent == null)
{
getLessonTracker(s).setStage(1);
return createStage1Content(s);
}
ec.addElement(mailHeader + mailContent);
return ec;
}
@Override
protected Element doStage3(WebSession s) throws Exception
{
return createStage3Content(s);
}
@Override
protected Element doStage4(WebSession s) throws Exception
{
return createStage4Content(s);
}
@Override
protected Element doStage5(WebSession s) throws Exception
{
System.out.println("Doing stage 5");
return createStage5Content(s);
}
private Element createStage5Content(WebSession s)
{
return createMainLoginContent(s);
}
private Element createStage3Content(WebSession s)
{
return createMainLoginContent(s);
}
private Element createStage4Content(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec.addElement("
Jane has logged into her account. Go and grab her session!" +
" Use Following link to reach the login screen of the bank:
" +
" Goat Hills Financial
");
return ec;
//return createMainLoginContent(s);
}
private Element createStage1Content(WebSession s)
{
String link = getLink();
String mailText = "Dear MS. Plane
"
+ "During the last week we had a few problems with our database. "
+ "A lot of people complained that there account details are wrong. "
+ "That is why we kindly ask you to use following link to verify your "
+ "data:
Goat Hills Financial
"
+ "We are sorry for the caused inconvenience and thank you for your cooparation.
"
+ "Your Goat Hills Financial Team
";
ElementContainer ec = new ElementContainer();
Table table = new Table();
TR tr1 = new TR();
TD td1 = new TD();
TD td2 = new TD();
TR tr2 = new TR();
TD td3 = new TD();
TD td4 = new TD();
TR tr3 = new TR();
TD td5 = new TD();
TD td6 = new TD();
TR tr4 = new TR();
TD td7 = new TD();
td7.addAttribute("colspan", 2);
TR tr5 = new TR();
TD td8 = new TD();
td8.addAttribute("colspan", 2);
td8.addAttribute("align", "center");
table.addElement(tr1);
table.addElement(tr2);
table.addElement(tr3);
table.addElement(tr4);
table.addElement(tr5);
tr1.addElement(td1);
tr1.addElement(td2);
tr2.addElement(td3);
tr2.addElement(td4);
tr3.addElement(td5);
tr3.addElement(td6);
tr4.addElement(td7);
tr5.addElement(td8);
ec.addElement(table);
B b = new B();
b.addElement("Mail To: ");
td1.addElement(b);
td2.addElement(mailTo);
b = new B();
b.addElement("Mail From: ");
td3.addElement(b);
td4.addElement(mailFrom);
b = new B();
b.addElement("Title: ");
td5.addElement(b);
Input titleField = new Input();
titleField.setValue(mailTitel);
titleField.addAttribute("size", 30);
td6.addElement(titleField);
TextArea mailContent = new TextArea();
mailContent.addAttribute("cols", 67);
mailContent.addAttribute("rows", 8);
mailContent.addElement(mailText);
mailContent.setName(MAILCONTENTNAME);
td7.addElement(mailContent);
td8.addElement(new Input(Input.SUBMIT, "SendMail", "Send Mail"));
return ec;
}
/**
* Creation of the main content
*
* @param s
* @return Element
*/
protected Element createMainLoginContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{
style sty = new style();
sty
.addElement("#lesson_wrapper {height: 435px;width: "
+ "500px;}#lesson_header {background-image: "
+ "url(lessons/DBSQLInjection/images/lesson1_header.jpg);width:"
+ " 490px;padding-right: 10px;padding-top: 60px;background-repeat: no-repeat;}.lesson_workspace "
+ "{background-image: url(lessons/DBSQLInjection/images/lesson1_workspace.jpg);width: 489px;height: "
+ "325px;padding-left: 10px;padding-top: 10px;background-repeat: no-repeat;} "
+ ".lesson_text {height: 240px;width: 460px;padding-top: 5px;} "
+ "#lesson_buttons_bottom {height: 20px;width: 460px;} "
+ "#lesson_b_b_left {width: 300px;float: left;} "
+ "#lesson_b_b_right input {width: 100px;float: right;} "
+ ".lesson_title_box {height: 20px;width: 420px;padding-left: 30px;} "
+ ".lesson_workspace { } "
+ ".lesson_txt_10 {font-family: Arial, Helvetica, sans-serif;font-size: 10px;} "
+ ".lesson_text_db {color: #0066FF} "
+ "#lesson_login {background-image: url(lessons/DBSQLInjection/images/lesson1_loginWindow.jpg);height: "
+ "124px;width: 311px;background-repeat: no-repeat;padding-top: 30px;margin-left: 80px;margin-top:"
+ " 50px;text-align: center;} #lesson_login_txt {font-family: Arial, Helvetica, sans-serif;font-size: "
+ "12px;text-align: center;} #lesson_search {background-image: "
+ "url(lessons/DBSQLInjection/images/lesson1_SearchWindow.jpg);height: 124px;width: 311px;background-repeat: "
+ "no-repeat;padding-top: 30px;margin-left: 80px;margin-top: 50px;text-align: center;}");
ec.addElement(sty);
Div wrapperDiv = new Div();
wrapperDiv.setID("lesson_wrapper");
Div headerDiv = new Div();
headerDiv.setID("lesson_header");
Div workspaceDiv = new Div();
workspaceDiv.setClass("lesson_workspace");
wrapperDiv.addElement(headerDiv);
wrapperDiv.addElement(workspaceDiv);
ec.addElement(wrapperDiv);
workspaceDiv.addElement(createWorkspaceContent(s));
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
/**
* Creation of the content of the workspace
*
* @param s
* @return Element
*/
private Element createWorkspaceContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String name = s.getParser().getStringParameter(USER, "");
String password = s.getParser().getStringParameter(PASSWORD, "");
try
{
// Logout Button is pressed
if (s.getParser().getRawParameter("logout", "").equals("true"))
{
s.add(LOGGEDIN, "false");
s.add("SID","");
this.sid = "";
}
if (correctLogin(name, password, s))
{
s.add(LOGGEDINUSER, name);
s.add(LOGGEDIN, "true");
createSuccessfulLoginContent(s, ec);
}
else if (sid.equals(s.get("SID")) && s.get(LOGGEDIN).equals("true"))
{
makeSuccess(s);
createSuccessfulLoginContent(s, ec);
}
else
{
if((name+password).equals(""))
{
createLogInContent(ec, "");
}
else
{
createLogInContent(ec, "Login Failed! Make sure user name and password is correct!");
}
}
} catch (Exception e)
{
if((name+password).equals(""))
{
createLogInContent(ec, "");
}
else
{
createLogInContent(ec, "Login Failed! Make sure user name and password is correct!");
}
}
return ec;
}
/**
* See if the password and corresponding user is valid
*
* @param userName
* @param password
* @param s
* @return true if the password was correct
*/
private boolean correctLogin(String userName, String password, WebSession s)
{
Connection connection = null;
try
{
connection = DatabaseUtilities.getConnection(s);
String query = "SELECT * FROM user_data_tan WHERE first_name = ? AND password = ?";
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
prepStatement.setString(1, userName);
prepStatement.setString(2, password);
ResultSet results = prepStatement.executeQuery();
if ((results != null) && (results.first() == true)) {
return true;
}
} catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (connection != null)
{
connection.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
return false;
}
/**
* Create content for logging in
*
* @param ec
*/
private void createLogInContent(ElementContainer ec, String errorMessage)
{
Div loginDiv = new Div();
loginDiv.setID("lesson_login");
Table table = new Table();
// table.setStyle(tableStyle);
table.addAttribute("align='center'", 0);
TR tr1 = new TR();
TD td1 = new TD();
TD td2 = new TD();
td1.addElement(new StringElement("Enter your name: "));
td2.addElement(new Input(Input.TEXT, USER));
tr1.addElement(td1);
tr1.addElement(td2);
TR tr2 = new TR();
TD td3 = new TD();
TD td4 = new TD();
td3.addElement(new StringElement("Enter your password: "));
td4.addElement(new Input(Input.PASSWORD, PASSWORD));
tr2.addElement(td3);
tr2.addElement(td4);
TR tr3 = new TR();
TD td5 = new TD();
td5.setColSpan(2);
td5.setAlign("center");
td5.addElement(new Input(Input.SUBMIT, "Submit", "Login"));
tr3.addElement(td5);
table.addElement(tr1);
table.addElement(tr2);
table.addElement(tr3);
loginDiv.addElement(table);
ec.addElement(loginDiv);
H2 errorTag = new H2(errorMessage);
errorTag.addAttribute("align", "center");
errorTag.addAttribute("class", "info");
ec.addElement(errorTag);
}
/**
* Create content after a successful login
*
* @param s
* @param ec
*/
private void createSuccessfulLoginContent(WebSession s, ElementContainer ec)
{
String userDataStyle = "margin-top:50px;";
Div userDataDiv = new Div();
userDataDiv.setStyle(userDataStyle);
userDataDiv.addAttribute("align", "center");
Table table = new Table();
table.addAttribute("cellspacing", 10);
table.addAttribute("cellpadding", 5);
table.addAttribute("align", "center");
TR tr1 = new TR();
TR tr2 = new TR();
TR tr3 = new TR();
TR tr4 = new TR();
tr1.addElement(new TD("Firstname:"));
tr1.addElement(new TD(getLoggedInUser(s)));
try
{
ResultSet results = getUser(getLoggedInUser(s), s);
results.first();
tr2.addElement(new TD("Lastname:"));
tr2.addElement(new TD(results.getString("last_name")));
tr3.addElement(new TD("Credit Card Type:"));
tr3.addElement(new TD(results.getString("cc_type")));
tr4.addElement(new TD("Credit Card Number:"));
tr4.addElement(new TD(results.getString("cc_number")));
}
catch (Exception e)
{
e.printStackTrace();
}
table.addElement(tr1);
table.addElement(tr2);
table.addElement(tr3);
table.addElement(tr4);
userDataDiv.addElement(table);
ec.addElement(userDataDiv);
ec.addElement(createLogoutLink());
}
/**
* Create a link for logging out
*
* @return Element
*/
private Element createLogoutLink()
{
A logoutLink = new A();
logoutLink.addAttribute("href", getLink() + "&logout=true");
logoutLink.addElement("Logout");
String logoutStyle = "margin-right:50px; mrgin-top:30px";
Div logoutDiv = new Div();
logoutDiv.addAttribute("align", "right");
logoutDiv.addElement(logoutLink);
logoutDiv.setStyle(logoutStyle);
return logoutDiv;
}
/**
* Get a user by its name
*
* @param user
* @param s
* @return ResultSet containing the user
*/
private ResultSet getUser(String user, WebSession s)
{
Connection connection = null;
try
{
connection = DatabaseUtilities.getConnection(s);
String query = "SELECT * FROM user_data_tan WHERE first_name = ? ";
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
prepStatement.setString(1, user);
ResultSet results = prepStatement.executeQuery();
return results;
} catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (connection != null)
{
connection.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
return null;
}
/**
* Get the logged in user
*
* @param s
* @return the logged in user
*/
private String getLoggedInUser(WebSession s)
{
try
{
String user = (String) s.get(LOGGEDINUSER);
return user;
} catch (Exception e)
{
return "";
}
}
/**
* Get the category
*
* @return the category
*/
protected Category getDefaultCategory()
{
return Category.SESSION_MANAGEMENT;
}
/**
* Gets the hints attribute of the RoleBasedAccessControl object
*
* @return The hints value
*/
public List getHints(WebSession s)
{
List hints = new ArrayList();
hints.add("Stage 1: Where is the link in the mail?");
hints.add("Stage 1: Add a SID to the link");
hints.add("Stage 1: A SID could looke something like this: SID=Whatever");
hints.add("Stage 1: Alter the link in the mail to: href=" + getLink() + "&SID=Whatever");
hints.add("Stage 2: Click on the link!");
hints.add("Stage 3: Log in as Jane with user name jane and password tarzan.");
hints.add("Stage 4: Click on the link provided");
hints.add("Stage 4: What is your actual SID?");
hints.add("Stage 4: Change the SID (NOVALIDSESSION) to the choosen one in the mail");
return hints;
}
/**
* Get the instructions for the user
*/
public String getInstructions(WebSession s)
{
int stage = getLessonTracker(s).getStage();
if (stage > 4)
{
stage = 4;
}
String instructions = "STAGE " +stage+": ";
if(stage == 1)
{
instructions += "You are Hacker Joe and " +
"you want to steal the session from Jane. " +
"That is why you have to send a phishing mail " +
"to her. The mail is already prepared. Only " +
"thing missing is a Session ID (SID) in the Link. Alter " +
"the link to include a SID.
You are: Hacker Joe";
}
else if (stage == 2)
{
instructions += "Now you are the victim Jane who received the mail you see. " +
"If you point on the link with your mouse you will see that there is a SID included." +
"Click on it to see what happens.
You are: Victim Jane ";
}
else if (stage == 3)
{
instructions += "As the bank kindly asked to verfy your data you have to log in to see if your details are " +
"correct ;). Your user name is Jane and your password is tarzan.
You are: Victim Jane ";
}
else if (stage == 4)
{
instructions += "It is time to steal the session now. Use following link to reach Goat Hills " +
"Financial.
You are: Hacker Joe ";
}
return (instructions);
}
private final static Integer DEFAULT_RANKING = new Integer(222);
/**
* Get the ranking for the hirarchy of lessons
*/
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Get the title of the Lesson
*/
public String getTitle()
{
return ("Session Fixation");
}
@Override
public void handleRequest(WebSession s)
{
Form form = new Form();
form.addElement(createContent(s));
form.setAction(getFormAction());
form.setMethod(Form.POST);
form.setName("form");
form.setEncType("");
setContent(form);
}
@Override
public String getLink()
{
if(sid.equals(""))
{
return super.getLink();
}
return super.getLink() + "&SID=" + sid;
}
private String randomSIDGenerator()
{
String sid = "";
sid = String.valueOf(Math.abs(random.nextInt()%100000));
return sid;
}
public Element getCredits()
{
return super.getCustomCredits("Created by: Reto Lippuner, Marcel Wirth", new StringElement(""));
}
}