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 prepared mail " + "which looks like an official mail from the bank" + "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("")); } }