mayhew64 2dd882a9a8 Minor fixes
removed many System.out.printlns
delete extra solutions directory - wrong location
added 5.2 credits

git-svn-id: http://webgoat.googlecode.com/svn/trunk/webgoat@344 4033779f-a91e-0410-96ef-6bf7bf53c507
2008-04-22 15:34:54 +00:00

828 lines
20 KiB
Java

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 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.BR;
import org.apache.ecs.html.Div;
import org.apache.ecs.html.H1;
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.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 7, 2008
*/
public class MultiLevelLogin2 extends LessonAdapter
{
private final static String USER = "user2";
private final static String PASSWORD = "pass2";
private final static String TAN = "tan2";
private final static String HIDDEN_USER = "hidden_user";
private final static String LOGGEDIN = "loggedin2";
private final static String CORRECTTAN = "correctTan2";
private final static String CURRENTTAN = "currentTan2";
private final static String CURRENTTANPOS = "currentTanPos2";
// needed to see if lesson was successfull
private final static String LOGGEDINUSER = "loggedInUser2";
//private String LoggedInUser = "";
/**
* See if the user is logged in
*
* @param s
* @return true if loggedIn
*/
private boolean loggedIn(WebSession s)
{
try
{
return s.get(LOGGEDIN).equals("true");
} catch (Exception e)
{
return false;
}
}
/**
* See if the user had used a valid tan
*
* @param s
* @return true if correctTan
*/
private boolean correctTan(WebSession s)
{
try
{
return s.get(CORRECTTAN).equals("true");
} catch (Exception e)
{
return false;
}
}
/**
* Get the currentTan
*
* @param s
* @return the logged in user
*/
private String getCurrentTan(WebSession s)
{
try
{
String currentTan = (String) s.get(CURRENTTAN);
return currentTan;
} catch (Exception e)
{
return "";
}
}
/**
* Get the currentTanPossition
*
* @param s
* @return the logged in user
*/
private Integer getCurrentTanPosition(WebSession s)
{
try
{
Integer tanPos = (Integer) s.get(CURRENTTANPOS);
return tanPos;
} catch (Exception e)
{
return 0;
}
}
/**
* 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 "";
}
}
/**
* Creates WebContent
*
* @param s
*/
protected Element createContent(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)
{
String user = "";
user = s.getParser().getStringParameter(USER, "");
String password = "";
password = s.getParser().getStringParameter(PASSWORD, "");
String tan = "";
tan = s.getParser().getStringParameter(TAN, "");
String hiddenUser = "";
hiddenUser = s.getParser().getStringParameter(HIDDEN_USER, "");
// String hiddenTan = s.getParser().getStringParameter(HIDDEN_TAN, "");
ElementContainer ec = new ElementContainer();
// verify that tan is correct and user is logged in
if (loggedIn(s) && correctTan(tan, s))
{
s.add(CORRECTTAN, "true");
}
// user is loggedIn but enters wrong tan
else if (loggedIn(s) && !correctTan(tan, s))
{
s.add(LOGGEDIN, "false");
}
if (correctLogin(user, password, s))
{
s.add(LOGGEDIN, "true");
s.add(LOGGEDINUSER, user);
s.add(CURRENTTANPOS, getTanPosition(user, s));
// currentTanNr = getTanPosition(user, s);
// currentTan = getTan(user, currentTanNr, s);
s.add(CURRENTTAN, getTan(user, getCurrentTanPosition(s), s));
}
// if restart button is clicked owe have to reset log in
if (!s.getParser().getStringParameter("Restart", "").equals(""))
{
resetTans(s);
}
// Logout Button is pressed
if (s.getParser().getRawParameter("logout", "").equals("true"))
{
s.add(LOGGEDIN, "false");
s.add(CORRECTTAN, "false");
}
if (loggedIn(s) && correctTan(s))
{
s.add(LOGGEDIN, "false");
s.add(CORRECTTAN, "false");
createSuccessfulLoginContent(s, ec, hiddenUser);
}
else if (loggedIn(s))
{
if (getCurrentTanPosition(s) > 5)
{
createNoTanLeftContent(ec);
}
else
{
createAskForTanContent(s, ec, getCurrentTanPosition(s), user);
}
}
else
{
String errorMessage = "";
if (!(user + password).equals(""))
{
errorMessage = "Login failed! Make sure " + "that user name and password is correct.";
}
else if (!tan.equals(""))
{
errorMessage = "Login failed. Tan is " + "incorrect.";
}
createLogInContent(ec, errorMessage);
}
return ec;
}
/**
* 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", "Submit"));
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 in which the tan is asked
*
* @param s
* @param ec
* @param tanNr
*/
private void createAskForTanContent(WebSession s, ElementContainer ec, int tanNr, String user)
{
Div loginDiv = new Div();
loginDiv.setID("lesson_login");
Table table = new Table();
table.addAttribute("align='center'", 0);
TR tr1 = new TR();
TD td1 = new TD();
TD td2 = new TD();
td1.addElement(new StringElement("Enter TAN #" + tanNr + ": "));
td2.addElement(new Input(Input.TEXT, TAN));
tr1.addElement(td1);
tr1.addElement(td2);
TR tr2 = new TR();
TD td3 = new TD();
td3.setColSpan(2);
td3.setAlign("center");
td3.addElement(new Input(Input.SUBMIT, "Submit", "Submit"));
tr2.addElement(td3);
table.addElement(tr1);
table.addElement(tr2);
ec.addElement(new Input(Input.HIDDEN, HIDDEN_USER, user));
loginDiv.addElement(table);
ec.addElement(loginDiv);
ec.addElement(createLogoutLink());
}
/**
* Create content if there is no tan left
*
* @param ec
*/
private void createNoTanLeftContent(ElementContainer ec)
{
ec.addElement(new BR());
ec.addElement(new BR());
ec.addElement(new BR());
ec.addElement(new BR());
H1 h = new H1("<center>No tan is left! Please contact the admin. </center>");
ec.addElement(h);
ec.addElement(createLogoutLink());
}
private void createSuccessfulLoginContent(WebSession s, ElementContainer ec, String user)
{
updateTan(user, s);
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("<b>Firstname:</b>"));
tr1.addElement(new TD(user));
try
{
ResultSet results = getUser(user, s);
if (results != null)
{
results.first();
tr2.addElement(new TD("<b>Lastname:</b>"));
tr2.addElement(new TD(results.getString("last_name")));
tr3.addElement(new TD("<b>Credit Card Type:</b>"));
tr3.addElement(new TD(results.getString("cc_type")));
tr4.addElement(new TD("<b>Credit Card Number:</b>"));
tr4.addElement(new TD(results.getString("cc_number")));
if (!user.equals(getLoggedInUser(s)))
{
makeSuccess(s);
}
}
}
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;
}
/**
* Update the tan. Every tan should be used only once.
*
* @param user
* @param s
*/
private void updateTan(String user, WebSession s)
{
int tanNr = getTanPosition(user, s);
Connection connection = null;
try
{
connection = DatabaseUtilities.getConnection(s);
String query = "UPDATE user_data_tan SET login_count = ? WHERE first_name = ?";
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
prepStatement.setInt(1, tanNr);
prepStatement.setString(2, user);
prepStatement.execute();
} catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (connection != null)
{
connection.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
/**
* 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;
}
/**
* If lesson is reseted the tans should be resetted too
*
* @param s
*/
private void resetTans(WebSession s)
{
Connection connection = null;
try
{
connection = DatabaseUtilities.getConnection(s);
String query = "UPDATE user_data_tan SET login_count = 0 WHERE login_count > 0";
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
prepStatement.execute();
} catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (connection != null)
{
connection.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
/**
* Get the count of the tan
*
* @param user
* @param s
* @return tanPosition
*/
private int getTanPosition(String user, WebSession s)
{
int tanNr = 0;
Connection connection = null;
try
{
connection = DatabaseUtilities.getConnection(s);
String query = "SELECT login_count 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();
if ((results != null) && (results.first() == true))
{
tanNr = results.getInt(results.getRow());
tanNr = tanNr + 1;
if (tanNr > 5)
{
tanNr = 0;
}
}
} catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (connection != null)
{
connection.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
return tanNr;
}
/**
* Get the tan for a user with specific position
*
* @param user
* @param tanPosition
* @param s
* @return tan
*/
private String getTan(String user, int tanPosition, WebSession s)
{
Connection connection = null;
try
{
connection = DatabaseUtilities.getConnection(s);
String query = "SELECT tan.tanValue FROM user_data_tan, tan WHERE user_data_tan.first_name = ? "
+ "AND user_data_tan.userid = tan.userid AND tan.tanNr = ?";
PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
prepStatement.setString(1, user);
prepStatement.setInt(2, tanPosition);
ResultSet results = prepStatement.executeQuery();
if ((results != null) && (results.first() == true))
{
//System.out.println(results.getString("tanValue"));
return results.getString("tanValue");
}
} catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (connection != null)
{
connection.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
return "";
}
/**
* See if the tan is correct
*
* @param tan
* @return true if the tan is correct
*/
private boolean correctTan(String tan, WebSession s)
{
// if (!getCurrentTan(s).equals("")) { return tan.equals(String.valueOf(currentTan)); }
if (!getCurrentTan(s).equals("")) { return tan.equals(getCurrentTan(s)); }
return false;
}
/**
* 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;
}
protected Category getDefaultCategory()
{
return Category.AUTHENTICATION;
}
/**
* Gets the hints attribute of the RoleBasedAccessControl object
*
* @return The hints value
*/
public List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("How does the server know which User has to be logged in");
hints.add("Maybe taking a look at the source code helps");
hints.add("Watch out for hidden fields");
hints.add("Manipulate the hidden field 'hidden_user'");
return hints;
}
public String getInstructions(WebSession s)
{
String instructions = "";
instructions = "You are an attacker called Joe. You have a valid account by webgoat financial. Your goal is to log in as "
+ "Jane. Your username is <b>Joe</b> and your password is <b>banana</b>. This are your TANS: <br>"
+ "Tan #1 = 15161<br>"
+ "Tan #2 = 4894<br>"
+ "Tan #3 = 18794<br>"
+ "Tan #4 = 1564<br>"
+ "Tan #5 = 45751<br>";
return (instructions);
}
private final static Integer DEFAULT_RANKING = new Integer(110);
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
public String getTitle()
{
return ("Multi Level Login 2");
}
public Element getCredits()
{
return super.getCustomCredits("Created by: Reto Lippuner, Marcel Wirth", new StringElement(""));
}
}