From 82e32acb7731ba815e376c26133869182ae40764 Mon Sep 17 00:00:00 2001 From: "wirth.marcel" Date: Mon, 7 Apr 2008 14:28:38 +0000 Subject: [PATCH] * Hints added * Solutions added * Bugfixes * Introduction added (including how to start with webgoat and useful tools) * New lesson: Password strength * New lessons: Multi Level Login * Not yet working new lesson: Session fixation (inital release) git-svn-id: http://webgoat.googlecode.com/svn/trunk@301 4033779f-a91e-0410-96ef-6bf7bf53c507 --- .../owasp/webgoat/lessons/AbstractLesson.java | 1 + .../org/owasp/webgoat/lessons/BackDoors.java | 73 +- .../webgoat/lessons/BlindSqlInjection.java | 105 +-- .../org/owasp/webgoat/lessons/Category.java | 3 + .../ClientSideFiltering.java | 24 +- .../Lab XSS/Lab Block Reflected XSS.html | 10 + ...ock Stored XSS using Input Validation.html | 46 ++ ...lock Stored XSS using Output Encoding.html | 26 + .../Lab XSS/Lab Reflected XSS.html | 11 + .../Lab XSS/Lab Stored XSS Revisited.html | 27 + .../Lab XSS/Lab Stored XSS.html | 31 + .../webgoat/lessons/ConcurrencyCart.java | 2 +- .../CrossSiteScripting.java | 68 +- .../CrossSiteScripting/FindProfile.java | 2 + .../CrossSiteScripting/UpdateProfile.java | 5 +- .../CrossSiteScripting/ViewProfile.java | 18 +- .../DBCrossSiteScripting.java | 3 +- .../org/owasp/webgoat/lessons/DOMXSS.java | 12 +- .../owasp/webgoat/lessons/DangerousEval.java | 4 +- .../org/owasp/webgoat/lessons/Encoding.java | 4 +- .../org/owasp/webgoat/lessons/HowToWork.java | 89 +++ .../org/owasp/webgoat/lessons/HtmlClues.java | 2 +- .../org/owasp/webgoat/lessons/HttpBasics.java | 2 +- .../owasp/webgoat/lessons/HttpSplitting.java | 8 +- .../owasp/webgoat/lessons/LessonAdapter.java | 1 - .../webgoat/lessons/MultiLevelLogin1.java | 703 ++++++++++++++++++ .../webgoat/lessons/MultiLevelLogin2.java | 651 ++++++++++++++++ .../org/owasp/webgoat/lessons/NewLesson.java | 2 +- .../webgoat/lessons/PasswordStrength.java | 204 +++++ .../org/owasp/webgoat/lessons/Phishing.java | 27 +- .../webgoat/lessons/RemoteAdminFlaw.java | 4 +- .../RoleBasedAccessControl.java | 78 +- .../lessons/SQLInjection/ViewProfile.java | 1 + .../webgoat/lessons/SessionFixation.java | 462 ++++++++++++ .../webgoat/lessons/SqlNumericInjection.java | 5 +- .../org/owasp/webgoat/lessons/StoredXss.java | 5 +- .../owasp/webgoat/lessons/UncheckedEmail.java | 9 +- .../owasp/webgoat/lessons/UsefulTools.java | 89 +++ .../owasp/webgoat/lessons/WsSqlInjection.java | 1 + .../lessons/admin/ReportCardScreen.java | 14 +- .../org/owasp/webgoat/session/Course.java | 2 +- .../org/owasp/webgoat/session/CreateDB.java | 102 +++ .../WebContent/images/header/header.jpg | Bin 21360 -> 18688 bytes .../images/introduction/HowToUse_1.jpg | Bin 0 -> 17040 bytes .../images/introduction/HowToUse_2.jpg | Bin 0 -> 32135 bytes .../images/introduction/HowToUse_3.jpg | Bin 0 -> 38055 bytes .../WebContent/images/introduction/Thumbs.db | Bin 0 -> 9728 bytes .../images/introduction/firebug.jpg | Bin 0 -> 35857 bytes .../images/introduction/iewatch.jpg | Bin 0 -> 53526 bytes .../images/introduction/interface.jpg | Bin 0 -> 29278 bytes .../images/introduction/webscarab.jpg | Bin 0 -> 32091 bytes .../javascript/clientSideFiltering.js | 59 +- .../WebContent/lesson_plans/HowToWork.html | 31 + .../WebContent/lesson_plans/HtmlClues.html | 2 +- .../WebContent/lesson_plans/HttpBasics.html | 2 +- .../lesson_plans/MultiLevelLogin1.html | 20 + .../lesson_plans/MultiLevelLogin2.html | 20 + .../lesson_plans/PasswordStrength.html | 10 + .../WebContent/lesson_plans/Phishing.html | 16 + .../WebContent/lesson_plans/ReflectedXSS.html | 6 +- .../WebContent/lesson_plans/SQLInjection.html | 14 + .../WebContent/lesson_plans/UsefulTools.html | 28 + .../lesson_solutions/AccessControlMatrix.html | 2 +- .../lesson_solutions/BasicAuthentication.html | 8 +- .../lesson_solutions/BlindSqlInjection.html | 32 +- .../WebContent/lesson_solutions/CSRF.html | 6 +- .../lesson_solutions/ClientSideFiltering.html | 79 ++ .../clientside_firebug.jpg | Bin 0 -> 23035 bytes .../ClientSideValidation.html | 63 ++ .../ClientSideValidation_stage1.png | Bin 0 -> 55272 bytes .../lesson_solutions/CommandInjection.html | 8 +- .../lesson_solutions/ConcurrencyCart.html | 32 + .../ConcurrencyCart_files/image001.jpg | Bin 0 -> 21263 bytes .../ConcurrencyCart_files/image002.jpg | Bin 0 -> 20553 bytes .../ConcurrencyCart_files/image003.jpg | Bin 0 -> 31550 bytes .../lesson_solutions/DOMInjection.html | 2 +- .../WebContent/lesson_solutions/DOMXSS.html | 51 ++ .../DOMXSS_files/image001.jpg | Bin 0 -> 11784 bytes .../DOMXSS_files/image002.jpg | Bin 0 -> 13870 bytes .../DOMXSS_files/image003.jpg | Bin 0 -> 10089 bytes .../DOMXSS_files/image004.jpg | Bin 0 -> 12160 bytes .../lesson_solutions/DOS_Login.html | 2 +- .../lesson_solutions/DangerousEval.html | 28 + .../WebContent/lesson_solutions/Encoding.html | 22 + .../FailOpenAuthentication.html | 8 +- .../lesson_solutions/ForgotPassword.html | 4 +- .../HiddenFieldTampering.html | 4 +- .../lesson_solutions/HtmlClues.html | 4 +- .../lesson_solutions/HttpBasics.html | 25 +- .../HttpBasics_files/webscarab1.jpg | Bin 0 -> 17040 bytes .../HttpBasics_files/webscarab2.jpg | Bin 0 -> 32135 bytes .../WebContent/lesson_solutions/HttpOnly.html | 6 +- .../lesson_solutions/HttpSplitting.html | 69 +- .../lesson_solutions/JSONInjection.html | 4 +- .../JavaScriptValidation.html | 16 +- ...Lab Add Business Layer Access Control.html | 50 ++ .../Lab Add Data Layer Access Control.html | 56 ++ ... Bypass Business Layer Access Control.html | 48 ++ .../Lab Bypass Data Layer Access Control.html | 46 ++ .../images/access_control_stage1.png | Bin 0 -> 36900 bytes .../images/access_control_stage3.png | Bin 0 -> 35319 bytes .../Lab Numeric SQL Injection.html | 41 + .../Lab Parameterized Query #1.html | 87 +++ .../Lab Parameterized Query #2.html | 51 ++ .../Lab String SQL Injection.html | 39 + .../Lab XSS/Lab Block Reflected XSS.html | 32 + ...ock Stored XSS using Input Validation.html | 46 ++ ...lock Stored XSS using Output Encoding.html | 26 + .../Lab XSS/Lab Reflected XSS.html | 27 + .../Lab XSS/Lab Stored XSS Revisited.html | 27 + .../Lab XSS/Lab Stored XSS.html | 36 + .../Lab XSS/images/stored_xss.png | Bin 0 -> 67357 bytes .../MultiLevelLogin1/MultiLevelLogin1.html | 50 ++ .../MultiLevelLogin2/MultiLevelLogin2.html | 40 + .../lesson_solutions/PasswordStrength.html | 38 + .../PasswordStrength_files/image001.jpg | Bin 0 -> 14305 bytes .../PasswordStrength_files/image002.jpg | Bin 0 -> 38350 bytes .../PasswordStrength_files/image003.jpg | Bin 0 -> 22378 bytes .../WebContent/lesson_solutions/Phishing.html | 67 ++ .../lesson_solutions/RemoteAdminFlaw.html | 10 +- .../lesson_solutions/SilentTransactions.html | 2 +- .../lesson_solutions/SoapRequest.html | 4 +- .../lesson_solutions/SqlNumericInjection.html | 63 +- .../numericinjection.png | Bin 0 -> 31711 bytes .../numericinjection_solved.png | Bin 0 -> 35806 bytes .../lesson_solutions/StoredXss.html | 14 +- .../lesson_solutions/ThreadSafetyProblem.html | 2 +- .../lesson_solutions/UncheckedEmail.html | 4 +- .../WeakAuthenticationCookie.html | 8 +- .../lesson_solutions/WeakSessionID.html | 47 +- .../lesson_solutions/WsSAXInjection.html | 6 +- .../lesson_solutions/WsSqlInjection.html | 9 +- .../lesson_solutions/XMLInjection.html | 33 +- .../lesson_solutions/XPATHInjection.html | 37 +- .../WebContent/lesson_solutions/formate.css | 2 + .../lessons/Ajax/clientSideFiltering.jsp | 2 +- webgoat/main/project/WebContent/main.jsp | 40 +- 137 files changed, 4230 insertions(+), 479 deletions(-) create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Reflected XSS.html create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Stored XSS using Input Validation.html create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Stored XSS using Output Encoding.html create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Reflected XSS.html create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Stored XSS Revisited.html create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Stored XSS.html create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HowToWork.java create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/MultiLevelLogin1.java create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/MultiLevelLogin2.java create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/PasswordStrength.java create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SessionFixation.java create mode 100644 webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/UsefulTools.java create mode 100644 webgoat/main/project/WebContent/images/introduction/HowToUse_1.jpg create mode 100644 webgoat/main/project/WebContent/images/introduction/HowToUse_2.jpg create mode 100644 webgoat/main/project/WebContent/images/introduction/HowToUse_3.jpg create mode 100644 webgoat/main/project/WebContent/images/introduction/Thumbs.db create mode 100644 webgoat/main/project/WebContent/images/introduction/firebug.jpg create mode 100644 webgoat/main/project/WebContent/images/introduction/iewatch.jpg create mode 100644 webgoat/main/project/WebContent/images/introduction/interface.jpg create mode 100644 webgoat/main/project/WebContent/images/introduction/webscarab.jpg create mode 100644 webgoat/main/project/WebContent/lesson_plans/HowToWork.html create mode 100644 webgoat/main/project/WebContent/lesson_plans/MultiLevelLogin1.html create mode 100644 webgoat/main/project/WebContent/lesson_plans/MultiLevelLogin2.html create mode 100644 webgoat/main/project/WebContent/lesson_plans/PasswordStrength.html create mode 100644 webgoat/main/project/WebContent/lesson_plans/Phishing.html create mode 100644 webgoat/main/project/WebContent/lesson_plans/SQLInjection.html create mode 100644 webgoat/main/project/WebContent/lesson_plans/UsefulTools.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/ClientSideFiltering.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/ClientSideFiltering_files/clientside_firebug.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/ClientSideValidation.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/ClientSideValidation_files/ClientSideValidation_stage1.png create mode 100644 webgoat/main/project/WebContent/lesson_solutions/ConcurrencyCart.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/ConcurrencyCart_files/image001.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/ConcurrencyCart_files/image002.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/ConcurrencyCart_files/image003.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/DOMXSS.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/DOMXSS_files/image001.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/DOMXSS_files/image002.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/DOMXSS_files/image003.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/DOMXSS_files/image004.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/DangerousEval.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Encoding.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/HttpBasics_files/webscarab1.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/HttpBasics_files/webscarab2.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab Access Control/Lab Add Business Layer Access Control.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab Access Control/Lab Add Data Layer Access Control.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab Access Control/Lab Bypass Business Layer Access Control.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab Access Control/Lab Bypass Data Layer Access Control.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab Access Control/images/access_control_stage1.png create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab Access Control/images/access_control_stage3.png create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab SQL Injection/Lab Numeric SQL Injection.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab SQL Injection/Lab Parameterized Query #1.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab SQL Injection/Lab Parameterized Query #2.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab SQL Injection/Lab String SQL Injection.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab XSS/Lab Block Reflected XSS.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab XSS/Lab Block Stored XSS using Input Validation.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab XSS/Lab Block Stored XSS using Output Encoding.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab XSS/Lab Reflected XSS.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab XSS/Lab Stored XSS Revisited.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab XSS/Lab Stored XSS.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Lab XSS/images/stored_xss.png create mode 100644 webgoat/main/project/WebContent/lesson_solutions/MultiLevelLogin1/MultiLevelLogin1.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/MultiLevelLogin2/MultiLevelLogin2.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/PasswordStrength.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/PasswordStrength_files/image001.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/PasswordStrength_files/image002.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/PasswordStrength_files/image003.jpg create mode 100644 webgoat/main/project/WebContent/lesson_solutions/Phishing.html create mode 100644 webgoat/main/project/WebContent/lesson_solutions/SqlNumericInjection_files/numericinjection.png create mode 100644 webgoat/main/project/WebContent/lesson_solutions/SqlNumericInjection_files/numericinjection_solved.png create mode 100644 webgoat/main/project/WebContent/lesson_solutions/formate.css diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/AbstractLesson.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/AbstractLesson.java index f54f799e6..8a1bbaf94 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/AbstractLesson.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/AbstractLesson.java @@ -528,6 +528,7 @@ public abstract class AbstractLesson extends Screen implements Comparable try { + System.out.println("Solution: " + getLessonSolutionFileName()); src = readFromFile(new BufferedReader(new FileReader(s.getWebResource(getLessonSolutionFileName()))), false); } catch (IOException e) { diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/BackDoors.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/BackDoors.java index 54a4be525..0802a54a1 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/BackDoors.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/BackDoors.java @@ -78,6 +78,45 @@ public class BackDoors extends SequentialLessonAdapter { return concept2(s); } + + private void addDBEntriesToEC(ElementContainer ec, ResultSet rs) + { + try { + if (rs.next()) + { + Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(1); + TR tr = new TR(); + tr.addElement(new TH("User ID")); + tr.addElement(new TH("Password")); + tr.addElement(new TH("SSN")); + tr.addElement(new TH("Salary")); + tr.addElement(new TH("E-Mail")); + t.addElement(tr); + + tr = new TR(); + tr.addElement(new TD(rs.getString("userid"))); + tr.addElement(new TD(rs.getString("password"))); + tr.addElement(new TD(rs.getString("ssn"))); + tr.addElement(new TD(rs.getString("salary"))); + tr.addElement(new TD(rs.getString("email"))); + t.addElement(tr); + while (rs.next()) + { + tr = new TR(); + tr.addElement(new TD(rs.getString("userid"))); + tr.addElement(new TD(rs.getString("password"))); + tr.addElement(new TD(rs.getString("ssn"))); + tr.addElement(new TD(rs.getString("salary"))); + tr.addElement(new TD(rs.getString("email"))); + t.addElement(tr); + } + ec.addElement(t); + } + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } protected Element concept1(WebSession s) throws Exception { @@ -105,28 +144,8 @@ public class BackDoors extends SequentialLessonAdapter } ResultSet rs = statement.executeQuery(arrSQL[0]); - if (rs.next()) - { - Table t = new Table(0).setCellSpacing(0).setCellPadding(0).setBorder(1); - TR tr = new TR(); - tr.addElement(new TH("User ID")); - tr.addElement(new TH("Password")); - tr.addElement(new TH("SSN")); - tr.addElement(new TH("Salary")); - tr.addElement(new TH("E-Mail")); - t.addElement(tr); - while (rs.next()) - { - tr = new TR(); - tr.addElement(new TD(rs.getString("userid"))); - tr.addElement(new TD(rs.getString("password"))); - tr.addElement(new TD(rs.getString("ssn"))); - tr.addElement(new TD(rs.getString("salary"))); - tr.addElement(new TD(rs.getString("email"))); - t.addElement(tr); - } - ec.addElement(t); - } + addDBEntriesToEC(ec, rs); + } } catch (Exception ex) { @@ -144,14 +163,22 @@ public class BackDoors extends SequentialLessonAdapter if (!userInput.equals("")) { + userInput = SELECT_ST + userInput; String[] arrSQL = userInput.split(";"); + Connection conn = DatabaseUtilities.getConnection(s); + Statement statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY); + if (arrSQL.length == 2) { - if (userInput.toUpperCase().indexOf("CREATE TRIGGER") != 0) + if (userInput.toUpperCase().indexOf("CREATE TRIGGER") != -1) { makeSuccess(s); } } + ResultSet rs = statement.executeQuery(arrSQL[0]); + addDBEntriesToEC(ec, rs); + } return ec; diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/BlindSqlInjection.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/BlindSqlInjection.java index 44c621b75..80c3deb61 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/BlindSqlInjection.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/BlindSqlInjection.java @@ -81,14 +81,7 @@ public class BlindSqlInjection extends LessonAdapter String query = "SELECT * FROM user_data WHERE userid = " + accountNumber; String answer_query; - if (runningOnWindows()) - { - answer_query = "SELECT TOP 1 first_name FROM user_data WHERE userid = " + TARGET_ACCT_NUM; - } - else - { - answer_query = "SELECT first_name FROM user_data WHERE userid = " + TARGET_ACCT_NUM; - } + answer_query = "SELECT TOP 1 first_name FROM user_data WHERE userid = " + TARGET_ACCT_NUM; try { @@ -151,25 +144,6 @@ public class BlindSqlInjection extends LessonAdapter return new StringElement("By Chuck Willis"); } - /** - * - * Determines the OS that WebGoat is running on. Needed because different DB backends are used - * on the different OSes (Access on Windows, InstantDB on others) - * - * @return true if running on Windows, false otherwise - */ - private boolean runningOnWindows() - { - String os = System.getProperty("os.name", "Windows"); - if (os.toLowerCase().indexOf("window") != -1) - { - return true; - } - else - { - return false; - } - } /** * Gets the hints attribute of the DatabaseFieldScreen object @@ -179,78 +153,35 @@ public class BlindSqlInjection extends LessonAdapter protected List getHints(WebSession s) { List hints = new ArrayList(); - if (runningOnWindows()) - { - hints - .add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. " - + "Create a SQL statement that you can use as a true/false test and then " - + "select the first character of the target element and do a start narrowing " - + "down the character using > and <" - + "

The backend database is Microsoft Access. Keep that in mind if you research SQL functions " - + "on the Internet since different databases use some different functions and syntax."); + hints.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. " + + "Create a SQL statement that you can use as a true/false test and then " + + "select the first character of the target element and do a start narrowing " + + "down the character using > and <" + + "

The backend database is HSQLDB. Keep that in mind if you research SQL functions " + + "on the Internet since different databases use some different functions and syntax."); hints.add("This is the code for the query being built and issued by WebGoat:

" + "\"SELECT * FROM user_data WHERE userid = \" + accountNumber "); hints.add("The application is taking your input and inserting it at the end of a pre-formed SQL command. " + "You will need to make use of the following SQL functions: " + "

SELECT - query for your target data and get a string " - + "

mid(string, start, length) - returns a " + + "

substr(string, start, length) - returns a " + "substring of string starting at the start character and going for length characters " - + "

asc(string) will return the ascii value of the first character in string " + + "

ascii(string) will return the ascii value of the first character in string " + "

> and < - once you have a character's value, compare it to a choosen one"); hints.add("Example: is the first character of the first_name of userid " + TARGET_ACCT_NUM + " less than 'M' (ascii 77)? " - + "

101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid=" + TARGET_ACCT_NUM + + "

101 AND (ascii( substr((SELECT first_name FROM user_data WHERE userid=" + TARGET_ACCT_NUM + ") , 1 , 1) ) < 77 ); " + "

If you get back that account number is valid, then yes. If get back that the number is" + "invalid then answer is no."); - hints - .add("Another example: is the second character of the first_name of userid " - + TARGET_ACCT_NUM - + " greater than 'm' (ascii 109)? " - + "

101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid=" - + TARGET_ACCT_NUM - + ") , 2 , 1) ) > 109 ); " - + "

If you get back that account number is valid, then yes. If get back that the number is " - + "invalid then answer is no."); - } - else - { - hints.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. " - + "Create a SQL statement that you can use as a true/false test and then " - + "select the first character of the target element and do a start narrowing " - + "down the character using > and <"); - - hints - .add("The database backend is InstantDB. Here is a reference guide : http://www.instantdb.com/doc/syntax.html"); - hints.add("This is the code for the query being built and issued by WebGoat:

" - + "\"SELECT * FROM user_data WHERE userid = \" + accountNumber "); - hints - .add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND.

The application is taking your input and inserting it at the end of a pre-formed SQL command. " - + "You will need to make use of the following SQL functions: " - + "

SELECT - query for your target data and get a string " - + "

mid(string, start, length) - returns a " - + "substring of string starting at the start character and going for length characters " - + "

asc(string) will return the ascii value of the first character in string " - + "

> and < - once you have a character's value, compare it to a choosen one"); - hints - .add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND.

Example: is the first character of the first_name of userid " - + TARGET_ACCT_NUM - + " less than 'M' (ascii 77)? " - + "

101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid=" - + TARGET_ACCT_NUM - + ") , 1 , 1) ) < 77 ); " - + "

If you get back that account number is valid, then yes. If get back that the number is" - + "invalid then answer is no."); - hints - .add("THIS HINT IS FOR THE MS ACCESS DB. IT NEEDS TO BE ALTERED FOR THE INSTANTDB BACKEND.

example: is the second character of the first_name of userid " - + TARGET_ACCT_NUM - + " greater than 'm' (ascii 109)? " - + "

101 AND (asc( mid((SELECT first_name FROM user_data WHERE userid=" - + TARGET_ACCT_NUM - + ") , 2 , 1) ) > 109 ); " - + "

If you get back that account number is valid, then yes. If get back that the number is " - + "invalid then answer is no."); - } + hints.add("Another example: is the second character of the first_name of userid " + + TARGET_ACCT_NUM + + " greater than 'm' (ascii 109)? " + + "

101 AND (ascii( substr((SELECT first_name FROM user_data WHERE userid=" + + TARGET_ACCT_NUM + + ") , 2 , 1) ) > 109 ); " + + "

If you get back that account number is valid, then yes. If get back that the number is " + + "invalid then answer is no."); return hints; } diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Category.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Category.java index e69fbcc90..223d6d228 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Category.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Category.java @@ -39,6 +39,8 @@ import java.util.List; public class Category implements Comparable { + public final static Category INTRODUCTION = new Category("Introduction", new Integer(5)); + public final static Category UNVALIDATED_PARAMETERS = new Category("Unvalidated Parameters", new Integer(110)); public final static Category ACCESS_CONTROL = new Category("Access Control Flaws", new Integer(210)); @@ -83,6 +85,7 @@ public class Category implements Comparable static { + categories.add(INTRODUCTION); categories.add(UNVALIDATED_PARAMETERS); categories.add(ACCESS_CONTROL); categories.add(AUTHENTICATION); diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/ClientSideFiltering.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/ClientSideFiltering.java index 153e66f24..804f26fb8 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/ClientSideFiltering.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/ClientSideFiltering.java @@ -95,6 +95,8 @@ public class ClientSideFiltering extends SequentialLessonAdapter t.setID("hiddenEmployeeRecords"); t.setStyle("display: none"); + + workspaceDiv.addElement(t); @@ -328,28 +330,28 @@ public class ClientSideFiltering extends SequentialLessonAdapter List hints = new ArrayList(); hints - .add("The information displayed when an employee is choosen from the drop down menu is stored on the client side."); + .add("Stage 1: The information displayed when an employee is choosen from the drop down menu is stored on the client side."); - hints.add("Use Firebug to find where the information is stored on the client side."); + hints.add("Stage 1: Use Firebug to find where the information is stored on the client side."); - hints.add("Examine the hidden table to see if there is anyone listed who is not in the drop down menu."); + hints.add("Stage 1: Examine the hidden table to see if there is anyone listed who is not in the drop down menu."); - hints.add("Look in the last row of the hidden table."); + hints.add("Stage 1: Look in the last row of the hidden table."); hints - .add("You can access the server directly here " + .add("Stage 1: You can access the server directly here " + "to see what results are being returned"); - hints.add("The server uses an XPath query agasinst an XML database."); + hints.add("Stage 2: The server uses an XPath query agasinst an XML database."); - hints.add("The query currently returns all of the contents of the database."); + hints.add("Stage 2: The query currently returns all of the contents of the database."); hints - .add("The query should only return the information of employees who are managed by Moe Stooge, who's userID is 102"); + .add("Stage 2: The query should only return the information of employees who are managed by Moe Stooge, who's userID is 102"); - hints.add("Try using a filter operator."); + hints.add("Stage 2: Try using a filter operator."); - hints.add("your filter operator shoiuld look something like: [Managers/Manager/text()="); + hints.add("Stage 2: Your filter operator should look something like: [Managers/Manager/text()="); return hints; @@ -361,7 +363,7 @@ public class ClientSideFiltering extends SequentialLessonAdapter if (getLessonTracker(s).getStage() == 1) { - instructions = "STAGE 1:\tYou are Moe Stooge, CSO of Goat Hills Financial. " + instructions = "STAGE 1:\tYou are Moe Stooge, CSO of Goat Hills Financial. " + "You have access to everyone in the company's information, except the CEO, " + "Neville Bartholomew. Or at least you shouldn't have access to the CEO's information." + " For this exercise, " diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Reflected XSS.html b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Reflected XSS.html new file mode 100644 index 000000000..652044954 --- /dev/null +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Reflected XSS.html @@ -0,0 +1,10 @@ + + + + +Insert title here + + +stub stage 6 + + \ No newline at end of file diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Stored XSS using Input Validation.html b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Stored XSS using Input Validation.html new file mode 100644 index 000000000..5e30990d2 --- /dev/null +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Stored XSS using Input Validation.html @@ -0,0 +1,46 @@ + + + + +Solution Lab Block Stored XSS + + + +

Lesson Plan Title: How to Perform Cross Site Scripting (XSS)

+ +

Concept / Topic To Teach:
+It is always a good practice to scrub all inputs, especially those inputs that will later be used as parameters to OS commands, scripts, and database queries. It is particularly important for content that will be permanently stored somewhere. Users should not be able to create message content that could cause another user to load an undesirable page or undesirable content when the user's message is retrieved. +XSS can also occur when unvalidated user input is used in an HTTP response. In a reflected XSS attack, an attacker can craft a URL with the attack script and post it to another website, email it, or otherwise get a victim to click on it. +

+ +

General Goal(s):
+For this exercise, you will perform stored and reflected XSS attacks. You will also implement code changes in the web application to defeat these attacks. +

+ +

Solution:
+You have to alter the method parseEmployeeProfile in the class UpdateProfile.java which is +placed in the package org.owasp.webgoat.lessons.CrossSiteScripting
+The place to Code is marked! Following Code will work:
+

+

+ +/**Your code**/
+String regex = "[\\s\\w-,]*";
+String stringToValidate = firstName+lastName+ssn+title+phone+address1+address2+
startDate+ccn+disciplinaryActionDate+
disciplinaryActionNotes+personalDescription;
+Pattern pattern = Pattern.compile(regex);
+validate(stringToValidate, pattern);
+/**End of your code**/ +
+

+

+This Validation allows following:
+\s = whitspace: \t\n\x0B\f\r
+\w = word: a-zA-Z_0-9
+and the characters - and , +

+

+Use of any other Character will throw a Validation Exception. +

+ + + \ No newline at end of file diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Stored XSS using Output Encoding.html b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Stored XSS using Output Encoding.html new file mode 100644 index 000000000..fc795aac1 --- /dev/null +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Block Stored XSS using Output Encoding.html @@ -0,0 +1,26 @@ + + + + +Solution Lab Block Stored XSS + + + +

Lesson Plan Title: How to Perform Cross Site Scripting (XSS)

+ +

Concept / Topic To Teach:
+It is always a good practice to scrub all inputs, especially those inputs that will later be used as parameters to OS commands, scripts, and database queries. It is particularly important for content that will be permanently stored somewhere. Users should not be able to create message content that could cause another user to load an undesirable page or undesirable content when the user's message is retrieved. +XSS can also occur when unvalidated user input is used in an HTTP response. In a reflected XSS attack, an attacker can craft a URL with the attack script and post it to another website, email it, or otherwise get a victim to click on it. +

+ +

General Goal(s):
+For this exercise, you will perform stored and reflected XSS attacks. You will also implement code changes in the web application to defeat these attacks. +

+ +

Solution:
+You have to use a static method called encode(String s) which is part of the class org.owasp.webgoat.util.HtmlEncoder; +

This method changes all special characters in the string. Now you have to use this method in the getEmployeeProfile method in the org.owasp.webgoat.lessons.CrossSiteScripting class. +Replace all answer_results.getString(someString) with HtmlEncoder.encode(answer_results.getString(someString)) and you are done.

+ + + \ No newline at end of file diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Reflected XSS.html b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Reflected XSS.html new file mode 100644 index 000000000..417b51164 --- /dev/null +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Reflected XSS.html @@ -0,0 +1,11 @@ + + + + +Insert title here + + +stub stage5 + + + \ No newline at end of file diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Stored XSS Revisited.html b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Stored XSS Revisited.html new file mode 100644 index 000000000..7b60f64f6 --- /dev/null +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Stored XSS Revisited.html @@ -0,0 +1,27 @@ + + + + +Solution Lab Block Stored XSS + + + +

Lesson Plan Title: How to Perform Cross Site Scripting (XSS)

+ +

Concept / Topic To Teach:
+It is always a good practice to scrub all inputs, especially those inputs that will later be used as parameters to OS commands, scripts, and database queries. It is particularly important for content that will be permanently stored somewhere. Users should not be able to create message content that could cause another user to load an undesirable page or undesirable content when the user's message is retrieved. +XSS can also occur when unvalidated user input is used in an HTTP response. In a reflected XSS attack, an attacker can craft a URL with the attack script and post it to another website, email it, or otherwise get a victim to click on it. +

+ +

General Goal(s):
+For this exercise, you will perform stored and reflected XSS attacks. You will also implement code changes in the web application to defeat these attacks. +

+ +

Solution:
+Log in as David with david as password. Choose Bruce from the List and click +on the 'ViewProfile' Button. + +

+ + + \ No newline at end of file diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Stored XSS.html b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Stored XSS.html new file mode 100644 index 000000000..15fa67743 --- /dev/null +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ClientSideFiltering/Lab XSS/Lab Stored XSS.html @@ -0,0 +1,31 @@ + + + + +Solution Lab Block Stored XSS + + + +

Lesson Plan Title: How to Perform Cross Site Scripting (XSS)

+ +

Concept / Topic To Teach:
+It is always a good practice to scrub all inputs, especially those inputs that will later be used as parameters to OS commands, scripts, and database queries. It is particularly important for content that will be permanently stored somewhere. Users should not be able to create message content that could cause another user to load an undesirable page or undesirable content when the user's message is retrieved. +XSS can also occur when unvalidated user input is used in an HTTP response. In a reflected XSS attack, an attacker can craft a URL with the attack script and post it to another website, email it, or otherwise get a victim to click on it. +

+ +

General Goal(s):
+For this exercise, you will perform stored and reflected XSS attacks. You will also implement code changes in the web application to defeat these attacks. +

+ +

Solution:
+First Login as Tom with tom as password. Select Tom from the list and click on the View Profile Button. +Now should appear Tom's Profile. Click on the 'Edit Profile' Button and try an XSS attack on the street filed.
+For example: <script>alert("Got Ya");</script>
+Click on the UpdateProfile Button and Log out.

+Now log in as Jerry with jerry as password. Select from the the list the profile of tom and hit the +ViewProfile Button. Congratulation! You have completed the lesson. + +

+ + + \ No newline at end of file diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ConcurrencyCart.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ConcurrencyCart.java index 119741496..67d78e19c 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ConcurrencyCart.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/ConcurrencyCart.java @@ -585,7 +585,7 @@ public class ConcurrencyCart extends LessonAdapter List hints = new ArrayList(); hints.add("Can you purchase the merchandise in your shopping cart for a lower price?"); hints.add("Try using a new browser window to get a lower price."); - hints.add("In window A, purchase a low cost item, in window B a high cost item."); + hints.add("In window A, purchase a low cost item. In window B, update the card with a high cost item."); hints.add("In window A, commit after updating cart in window B."); return hints; diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/CrossSiteScripting.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/CrossSiteScripting.java index 60dac506d..9d75b7d18 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/CrossSiteScripting.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/CrossSiteScripting.java @@ -1,9 +1,17 @@ package org.owasp.webgoat.lessons.CrossSiteScripting; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.ecs.ElementContainer; +import org.apache.ecs.StringElement; +import org.apache.ecs.html.Body; +import org.apache.ecs.html.Head; +import org.apache.ecs.html.Html; +import org.apache.ecs.html.Title; import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.GoatHillsFinancial.DeleteProfile; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; @@ -90,7 +98,32 @@ public class CrossSiteScripting extends GoatHillsFinancial { return Category.XSS; } + + + public String getLessonSolutionFileName(WebSession s) { + String solutionFileName = null; + String stage = getStage(s); + solutionFileName = "/lesson_solutions/Lab XSS/Lab " + stage + ".html"; + return solutionFileName; + } + + @Override + public String getSolution(WebSession s) { + String src = null; + try + { + System.out.println("Solution: " + getLessonSolutionFileName(s)); + src = readFromFile(new BufferedReader(new FileReader(s.getWebResource(getLessonSolutionFileName(s)))), false); + } catch (IOException e) + { + s.setMessage("Could not find the solution file"); + src = ("Could not find the solution file"); + } + + return src; + } + /** * Gets the hints attribute of the DirectoryScreen object * @@ -101,29 +134,27 @@ public class CrossSiteScripting extends GoatHillsFinancial List hints = new ArrayList(); // Stage 1 - hints.add("You can put HTML tags in form input fields."); - hints.add("Bury a SCRIPT tag in the field to attack anyone who reads it."); + hints.add("Stage1: You can put HTML tags in form input fields."); + hints.add("Stage1: Bury a SCRIPT tag in the field to attack anyone who reads it."); hints - .add("Enter this: <script language=\"javascript\" type=\"text/javascript\">alert(\"Ha Ha Ha\");</script> in message fields."); - hints.add("Enter this: <script>alert(\"document.cookie\");</script> in message fields."); + .add("Stage1: Enter this: <script language=\"javascript\" type=\"text/javascript\">alert(\"Ha Ha Ha\");</script> in message fields."); + hints.add("Stage1: Enter this: <script>alert(\"document.cookie\");</script> in message fields."); // Stage 2 - hints.add("Many scripts rely on the use of special characters such as: <"); + hints.add("Stage2: Many scripts rely on the use of special characters such as: <"); hints - .add("Allowing only a certain set of characters (positive filtering) is preferred to blocking a set of characters (negative filtering)."); - hints.add("The java.util.regex package is useful for filtering string values."); + .add("Stage2: Allowing only a certain set of characters (positive filtering) is preferred to blocking a set of characters (negative filtering)."); + hints.add("Stage2: The java.util.regex package is useful for filtering string values."); // Stage 3 - hints - .add("Browsers recognize and decode HTML entity encoded content after parsing and interpretting HTML tags."); - hints.add("An HTML entity encoder is provided in the ParameterParser class."); + // Stage 4 - hints.add("Examine content served in response to form submissions looking for data taken from the form."); - + hints.add("Stage4: Examine content served in response to form submissions looking for data taken from the form."); + hints.add("Stage4: There is a class called HtmlEncoder in org.owasp.webgoat.util"); // Stage 5 hints - .add("Validate early. Consider: out.println(\"Order for \" + request.getParameter(\"product\") + \" being processed...\");"); + .add("Stage5: Validate early. Consider: out.println(\"Order for \" + request.getParameter(\"product\") + \" being processed...\");"); return hints; } @@ -144,11 +175,12 @@ public class CrossSiteScripting extends GoatHillsFinancial { instructions = "Stage 1: Execute a Stored Cross Site Scripting (XSS) attack.
" + "As 'Tom', execute a Stored XSS attack against the Street field on the Edit Profile page. " - + "Verify that 'Jerry' is affected by the attack."; + + "Verify that 'Jerry' is affected by the attack.
The passwords for the accounts are the prenames."; } else if (STAGE2.equals(stage)) { - instructions = "Stage 2: Block Stored XSS using Input Validation.
" + instructions = "Stage 2: Block Stored XSS using Input Validation.

" + + " THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT

" + "Implement a fix to block the stored XSS before it can be written to the database. " + "Repeat stage 1 as 'Eric' with 'David' as the manager. Verify that 'David' is not affected by the attack."; } @@ -160,7 +192,8 @@ public class CrossSiteScripting extends GoatHillsFinancial } else if (STAGE4.equals(stage)) { - instructions = "Stage 4: Block Stored XSS using Output Encoding.
" + instructions = "Stage 4: Block Stored XSS using Output Encoding.

" + + " THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT

" + "Implement a fix to block XSS after it is read from the database. " + "Repeat stage 3. Verify that 'David' is not affected by Bruce's profile attack."; } @@ -172,7 +205,8 @@ public class CrossSiteScripting extends GoatHillsFinancial } else if (STAGE6.equals(stage)) { - instructions = "Stage 6: Block Reflected XSS using Input Validation.
" + instructions = "Stage 6: Block Reflected XSS using Input Validation.

" + + " THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT

" + "Implement a fix to block this reflected XSS attack. " + "Repeat step 5. Verify that the attack URL is no longer effective."; } diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/FindProfile.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/FindProfile.java index c240cde80..badaacec0 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/FindProfile.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/FindProfile.java @@ -17,6 +17,7 @@ import org.owasp.webgoat.session.UnauthenticatedException; import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.WebSession; +import org.owasp.webgoat.util.HtmlEncoder; /*************************************************************************************************** @@ -128,6 +129,7 @@ public class FindProfile extends DefaultLessonAction protected String getRequestParameter(WebSession s, String name) throws ParameterNotFoundException, ValidationException { + return s.getParser().getRawParameter(name); } diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/UpdateProfile.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/UpdateProfile.java index 449247e36..4997bcc91 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/UpdateProfile.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/UpdateProfile.java @@ -111,8 +111,8 @@ public class UpdateProfile extends DefaultLessonAction { // The input validation can be added using a parsing component // or by using an inline regular expression. The parsing component - // is the better solution. - + // is the better solution. + HttpServletRequest request = s.getRequest(); String firstName = request.getParameter(CrossSiteScripting.FIRST_NAME); String lastName = request.getParameter(CrossSiteScripting.LAST_NAME); @@ -129,6 +129,7 @@ public class UpdateProfile extends DefaultLessonAction String disciplinaryActionDate = request.getParameter(CrossSiteScripting.DISCIPLINARY_DATE); String disciplinaryActionNotes = request.getParameter(CrossSiteScripting.DISCIPLINARY_NOTES); String personalDescription = request.getParameter(CrossSiteScripting.DESCRIPTION); + Employee employee = new Employee(subjectId, firstName, lastName, ssn, title, phone, address1, address2, manager, startDate, salary, ccn, ccnLimit, disciplinaryActionDate, disciplinaryActionNotes, diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/ViewProfile.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/ViewProfile.java index 83a70aad2..80499438b 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/ViewProfile.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/CrossSiteScripting/ViewProfile.java @@ -4,14 +4,20 @@ package org.owasp.webgoat.lessons.CrossSiteScripting; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; + +import org.apache.ecs.xhtml.html; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.GoatHillsFinancial; import org.owasp.webgoat.session.Employee; import org.owasp.webgoat.session.ParameterNotFoundException; +import org.owasp.webgoat.session.ParameterParser; import org.owasp.webgoat.session.UnauthenticatedException; import org.owasp.webgoat.session.UnauthorizedException; import org.owasp.webgoat.session.ValidationException; import org.owasp.webgoat.session.WebSession; +import org.owasp.webgoat.util.HtmlEncoder; + +import com.sun.corba.se.spi.activation.Server; /*************************************************************************************************** @@ -86,11 +92,11 @@ public class ViewProfile extends DefaultLessonAction { Employee profile = null; + // Query the database for the profile data of the given employee try { String query = "SELECT * FROM employee WHERE userid = " + subjectUserId; - try { Statement answer_statement = WebSession.getConnection(s) @@ -98,11 +104,12 @@ public class ViewProfile extends DefaultLessonAction ResultSet answer_results = answer_statement.executeQuery(query); if (answer_results.next()) { + // Note: Do NOT get the password field. profile = new Employee(answer_results.getInt("userid"), answer_results.getString("first_name"), answer_results.getString("last_name"), answer_results.getString("ssn"), answer_results - .getString("title"), answer_results.getString("phone"), answer_results - .getString("address1"), answer_results.getString("address2"), answer_results + .getString("title"), answer_results.getString("phone"), + answer_results.getString("address1"), answer_results.getString("address2"), answer_results .getInt("manager"), answer_results.getString("start_date"), answer_results .getInt("salary"), answer_results.getString("ccn"), answer_results .getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results @@ -124,13 +131,14 @@ public class ViewProfile extends DefaultLessonAction return profile; } + public Employee getEmployeeProfile_BACKUP(WebSession s, int userId, int subjectUserId) throws UnauthorizedException { // Query the database to determine if this employee has access to this function // Query the database for the profile data of the given employee if "owned" by the given // user - + Employee profile = null; // Query the database for the profile data of the given employee @@ -154,6 +162,8 @@ public class ViewProfile extends DefaultLessonAction .getInt("salary"), answer_results.getString("ccn"), answer_results .getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results .getString("disciplined_notes"), answer_results.getString("personal_description")); + + /* * System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " + * profile.getLastName() + " (" + profile.getId() + ")"); diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/DBCrossSiteScripting.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/DBCrossSiteScripting.java index 71492bd20..1a935639a 100755 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/DBCrossSiteScripting.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/DBCrossSiteScripting.java @@ -124,7 +124,8 @@ public class DBCrossSiteScripting extends GoatHillsFinancial String stage = getStage(s); if (STAGE1.equals(stage)) { - instructions = "Stage 1: Execute a Stored Cross Site Scripting (XSS) attack.
" + instructions = "Stage 1: Execute a Stored Cross Site Scripting (XSS) attack.

"+ + " THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT

" + "As 'Tom', execute a Stored XSS attack against the Street field on the Edit Profile page. " + "Verify that 'Jerry' is affected by the attack. " + "A sample JavaScript snippet you can use is: <SCRIPT>alert('bang!');</SCRIPT>."; diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DOMXSS.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DOMXSS.java index 332ae8f2f..3c5f7dc35 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DOMXSS.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DOMXSS.java @@ -179,17 +179,17 @@ public class DOMXSS extends SequentialLessonAdapter { List hints = new ArrayList(); - hints.add("Try entering the following: " + "<IMG SRC=\"images/logos/owasp.jpg\"/>"); + hints.add("Stage 1: Try entering the following: " + "<IMG SRC=\"images/logos/owasp.jpg\"/>"); - hints.add("Try entering the following: " + "<img src=x onerror=;;alert('XSS') />"); + hints.add("Stage 2: Try entering the following: " + "<img src=x onerror=;;alert('XSS') />"); - hints.add("Try entering the following: " + "<IFRAME SRC=\"javascript:alert('XSS');\"></IFRAME>"); + hints.add("Stage 3: Try entering the following: " + "<IFRAME SRC=\"javascript:alert('XSS');\"></IFRAME>"); - hints - .add("Try entering the following: " + hints.add("Stage 4: Try entering the following: " + "Please enter your password:<BR><input type = \"password\" name=\"pass\"/><button " + "onClick=\"javascript:alert('I have your password: ' + pass.value);\">Submit</button><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>"); + hints.add("Stage 5: You will find the JavaScripts in tomcat\\webapps\\WebGoat\\javascript (Standart Version) or in WebContent\\javascript (Developer Version)."); // Attack Strings: // @@ -257,7 +257,7 @@ public class DOMXSS extends SequentialLessonAdapter } else if (getLessonTracker(s).getStage() == 5) { - instructions = "STAGE 5:\tPerform client-side HTML entity encoding to mitigate the DOM XSS vulnerability. A utility method is provided for you in WebContent/javascript/escape.js."; + instructions = "STAGE 5:\tPerform client-side HTML entity encoding to mitigate the DOM XSS vulnerability. A utility method is provided for you in escape.js."; } return (instructions); } diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DangerousEval.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DangerousEval.java index 0a7f3cd7b..4eef387c4 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DangerousEval.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DangerousEval.java @@ -87,7 +87,8 @@ public class DangerousEval extends LessonAdapter float runningTotal = 0.0f; // FIXME: encode output of field2, then s.setMessage( field2 ); - ec.addElement(""); + // ec.addElement(new HR().setWidth("90%")); ec.addElement(new Center().addElement(new H1().addElement("Shopping Cart "))); Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1).setWidth("90%").setAlign("center"); @@ -202,6 +203,7 @@ public class DangerousEval extends LessonAdapter ec.addElement(t); ec.addElement(new BR()); ec.addElement(new HR().setWidth("90%")); + } catch (Exception e) { s.setMessage("Error generating " + this.getClass().getName()); diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Encoding.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Encoding.java index 887dfa0eb..f98790f23 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Encoding.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Encoding.java @@ -266,7 +266,7 @@ public class Encoding extends LessonAdapter description = "Rot13 encoding is a way to make text unreadable, but is easily reversed and provides no security."; - t.addElement(makeRow(description, rot13(userInput), rot13(userInput))); + t.addElement(makeRow(description, rot13(userInput), userInput)); description = "XOR with password encoding is a weak encryption scheme that mixes a password into data."; @@ -575,7 +575,7 @@ public class Encoding extends LessonAdapter System.out.print("Hex encoding: "); System.out.println(hexEncode(userInput) + " : " + hexDecode(userInput)); System.out.print("Rot13 encoding: "); - System.out.println(rot13(userInput) + " : " + rot13(userInput)); + System.out.println(rot13(userInput) + " : " + userInput); System.out.print("XOR with password: "); System.out.println(xorEncode(userInput, userKey) + " : " + xorDecode(userInput, userKey)); System.out.print("Double unicode encoding is..."); diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HowToWork.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HowToWork.java new file mode 100644 index 000000000..25d971a64 --- /dev/null +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HowToWork.java @@ -0,0 +1,89 @@ + +package org.owasp.webgoat.lessons; + +import org.apache.ecs.Element; +import org.apache.ecs.ElementContainer; +import org.apache.ecs.StringElement; +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 4, 2008 + */ +public class HowToWork extends LessonAdapter +{ + /** + * Description of the Method + * + * @param s + * Description of the Parameter + * @return Description of the Return Value + */ + protected Element createContent(WebSession s) + { + makeSuccess(s); + ElementContainer ec = new ElementContainer(); + ec.addElement(new StringElement("Welcome to WebGoat !!")); + return (ec); + } + + /** + * Gets the category attribute of the HowToWork object + * + * @return The category value + */ + protected Category getDefaultCategory() + { + return Category.INTRODUCTION; + } + + private final static Integer DEFAULT_RANKING = new Integer(10); + + protected Integer getDefaultRanking() + { + return DEFAULT_RANKING; + } + + /** + * Gets the title attribute of the DirectoryScreen object + * + * @return The title value + */ + public String getTitle() + { + return ("How to work with Webgoat"); + } + + public Element getCredits() + { + return super.getCustomCredits("Created by: Reto Lippuner, Marcel Wirth", new StringElement("")); + } + +} diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HtmlClues.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HtmlClues.java index c41d374e4..879bce3b5 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HtmlClues.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HtmlClues.java @@ -108,7 +108,7 @@ public class HtmlClues extends LessonAdapter makeSuccess(s); s.setMessage("BINGO -- admin authenticated"); - ec.addElement(makeUser(s, "jsnow", "CREDENTIALS")); + ec.addElement(makeUser(s, "admin", "CREDENTIALS")); } else { diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HttpBasics.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HttpBasics.java index bc229823b..f5406f37f 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HttpBasics.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HttpBasics.java @@ -92,7 +92,7 @@ public class HttpBasics extends LessonAdapter { List hints = new ArrayList(); hints.add("Type in your name and press 'go'"); - hints.add("Turn on Show Parameters or other features"); + hints.add("Try to intercept the request with WebScarab"); hints.add("Press the Show Lesson Plan button to view a lesson summary"); hints.add("Press the Show Solution button to view a lesson solution"); diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HttpSplitting.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HttpSplitting.java index 3317e465c..1b571c284 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HttpSplitting.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/HttpSplitting.java @@ -224,19 +224,19 @@ public class HttpSplitting extends SequentialLessonAdapter List hints = new ArrayList(); 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("Use CR (%0d) and LF (%0a) for a new line in Windows and only LF (%0a) in Linux."); 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>"); + .add("NOTE: THIS HINT IS FOR WINDOWS AND HAS TO BE ALTERED FOR ANOTHER SYSTEM
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>"); + .add("NOTE: THIS HINT IS FOR WINDOWS AND HAS TO BE ALTERED FOR ANOTHER SYSTEM
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%202030%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"); + .add("NOTE: THIS HINT IS FOR WINDOWS AND HAS TO BE ALTERED FOR ANOTHER SYSTEM
Try to intercept the reply and add HTTP/1.1 304 Not Modified0d%0aDate:%20Mon,%2027%20Oct%202030%2014:50:18%20GMT"); return hints; } diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/LessonAdapter.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/LessonAdapter.java index a1e14e1b4..6ac017ca1 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/LessonAdapter.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/LessonAdapter.java @@ -32,7 +32,6 @@ import org.owasp.webgoat.session.WebSession; * 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 diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/MultiLevelLogin1.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/MultiLevelLogin1.java new file mode 100644 index 000000000..4bc201e25 --- /dev/null +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/MultiLevelLogin1.java @@ -0,0 +1,703 @@ + +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 MultiLevelLogin1 extends SequentialLessonAdapter +{ + private boolean loggedIn = false; + private boolean correctTan = false; + private String LoggedInUser = ""; + + private final static String USER = "user"; + private final static String PASSWORD = "pass"; + private final static String HIDDEN_TAN = "hidden_tan"; + private final static String TAN = "tan"; + + /** + * Creates Staged WebContent + * + * @param s + */ + protected Element createContent(WebSession s) + { + return super.createStagedContent(s); + } + + /** + * Creation of the main content + * + * @param s + * @return Element + */ + protected Element createMainContent(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 hiddenTan = s.getParser().getStringParameter(HIDDEN_TAN, ""); + + ElementContainer ec = new ElementContainer(); + + // verify that tan is correct and user is logged in + if (loggedIn && correctTan(LoggedInUser, tan, hiddenTan, s)) + { + correctTan = true; + } + // user is loggedIn but enters wrong tan + else if (loggedIn && !correctTan(LoggedInUser, tan, hiddenTan, s)) + { + loggedIn = false; + } + + // verify the password + if (correctLogin(user, password, s)) + { + loggedIn = true; + LoggedInUser = user; + } + + // if restart link is clicked owe have to reset log in + if (!s.getParser().getStringParameter("Restart", "").equals("")) + { + loggedIn = false; + correctTan = false; + resetTans(s); + } + // Logout Button is pressed + if (s.getParser().getRawParameter("logout", "").equals("true")) + { + loggedIn = false; + correctTan = false; + + } + if (loggedIn && correctTan) + { + loggedIn = false; + correctTan = false; + + createSuccessfulLoginContent(s, ec); + if (getLessonTracker(s).getStage() == 2) + { + if (hiddenTan.equals("1")) + { + makeSuccess(s); + } + } + else + { + getLessonTracker(s).setStage(2); + s.setMessage("Stage 1 completed."); + } + } + + else if (loggedIn) + { + int tanNr = getTanPosition(LoggedInUser, s); + if (tanNr == 0) + { + createNoTanLeftContent(ec); + + } + else + { + createAskForTanContent(s, ec, tanNr); + } + + } + 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) + { + + 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_TAN, tanNr)); + loginDiv.addElement(table); + ec.addElement(loginDiv); + ec.addElement(createLogoutLink()); + + updateTan(LoggedInUser, s); + } + + /** + * 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("
No tan is left! Please contact the admin.
"); + ec.addElement(h); + ec.addElement(createLogoutLink()); + } + + /** + * 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(LoggedInUser)); + + try + { + ResultSet results = getUser(LoggedInUser, 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; + } + + /** + * 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); + + try + { + Connection 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(); + } + + } + + /** + * If lesson is reseted the tans should be resetted too + * + * @param s + */ + private void resetTans(WebSession s) + { + + try + { + Connection 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(); + } + + } + + /** + * Get the count of the tan + * + * @param user + * @param s + * @return tanPosition + */ + private int getTanPosition(String user, WebSession s) + { + int tanNr = 0; + try + { + Connection 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; + } + // make sure you don't get the first tan in stage 2 + if (getLessonTracker(s).getStage() == 2 && tanNr == 1) + { + ++tanNr; + } + } + } catch (Exception e) + { + e.printStackTrace(); + } + + return tanNr; + } + + /** + * Get a user by its name + * + * @param user + * @param s + * @return ResultSet containing the user + */ + private ResultSet getUser(String user, WebSession s) + { + try + { + Connection 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(); + } + return null; + + } + + /** + * See if the tan is correct + * + * @param user + * @param tan + * @param tanPosition + * @param s + * @return true if the tan is correct + */ + private boolean correctTan(String user, String tan, String tanPosition, WebSession s) + { + if (tan.equals("")) { return false; } + try + { + Connection connection = DatabaseUtilities.getConnection(s); + String query = "SELECT user_data_tan.userid FROM user_data_tan, tan WHERE user_data_tan.first_name = ? " + + "AND user_data_tan.userid = tan.userid AND tan.tanValue = ? AND tan.tanNr = ?"; + PreparedStatement prepStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY); + prepStatement.setString(1, user); + prepStatement.setString(2, tan); + prepStatement.setString(3, tanPosition); + + ResultSet results = prepStatement.executeQuery(); + + if ((results != null) && (results.first() == true)) { + + return true; + + } + + } catch (Exception e) + { + e.printStackTrace(); + } + 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) + { + try + { + Connection 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(); + } + + return false; + + } + + /** + * Gets the category attribute of the RoleBasedAccessControl object + * + * @return The category value + */ + protected ElementContainer doStage1(WebSession s) + { + ElementContainer ec = new ElementContainer(); + ec.addElement(createMainContent(s)); + return ec; + + } + + /** + * After finishing succesful stage1 this function is called + */ + protected Element doStage2(WebSession s) + { + ElementContainer ec = new ElementContainer(); + ec.addElement(createMainContent(s)); + return ec; + } + + /** + * Get the category + * + * @return the category + */ + protected Category getDefaultCategory() + { + return Category.AUTHENTICATION; + } + + /** + * 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: Just do a regular login"); + hints.add("Stage 2: How does the server know which TAN has to be used"); + hints.add("Stage 2: Maybe taking a look at the source code helps"); + hints.add("Stage 2: Watch out for hidden fields"); + hints.add("Stage 2: Manipulate the hidden field 'hidden_tan'"); + + return hints; + + } + + /** + * Get the instructions for the user + */ + public String getInstructions(WebSession s) + { + String instructions = ""; + if (getLessonTracker(s).getStage() == 1) + { + instructions = "STAGE 1:\t This stage is just to show how a classic multi login works. " + + "Your goal is to do a regular login as Jane with password tarzan. " + + "You have following TAN:
" + "Tan #1 = 15648
" + "Tan #2 = 92156
" + + "Tan #3 = 4879
" + "Tan #4 = 9458
" + "Tan #5 = 4879
"; + + } + else if (getLessonTracker(s).getStage() == 2) + { + instructions = "STAGE 2:\tNow you are a hacker who " + "already has stolen some information from Jane by " + + "a phishing mail. " + "You have the password which is tarzan and " + + "the Tan #1 which is 15648
" + "The problem is that the first tan is already " + + "used... try to break into the system anyway. "; + } + + return (instructions); + } + + private final static Integer DEFAULT_RANKING = new Integer(110); + + /** + * Get the ranking for the hirarchy of lessons + */ + protected Integer getDefaultRanking() + { + return DEFAULT_RANKING; + } + + /** + * Get the title of the Lesson + */ + public String getTitle() + { + return ("Multi Level Login 1"); + } + + public Element getCredits() + { + return super.getCustomCredits("Created by: Reto Lippuner, Marcel Wirth", new StringElement("")); + } +} diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/MultiLevelLogin2.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/MultiLevelLogin2.java new file mode 100644 index 000000000..664f38e59 --- /dev/null +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/MultiLevelLogin2.java @@ -0,0 +1,651 @@ + +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 boolean loggedIn = false; + private boolean correctTan = false; + private String currentTan = ""; + private int currentTanNr = 0; + + private final static String USER = "user"; + private final static String PASSWORD = "pass"; + private final static String TAN = "tan"; + private final static String HIDDEN_USER = "hidden_user"; + + // needed to see if lesson was successfull + private String LoggedInUser = ""; + + /** + * 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 && correctTan(tan)) + { + correctTan = true; + } + // user is loggedIn but enters wrong tan + else if (loggedIn && !correctTan(tan)) + { + loggedIn = false; + } + + if (correctLogin(user, password, s)) + { + loggedIn = true; + LoggedInUser = user; + currentTanNr = getTanPosition(user, s); + currentTan = getTan(user, currentTanNr, s); + + } + + // if restart button is clicked owe have to reset log in + if (!s.getParser().getStringParameter("Restart", "").equals("")) + { + loggedIn = false; + correctTan = false; + currentTanNr = 0; + resetTans(s); + } + // Logout Button is pressed + if (s.getParser().getRawParameter("logout", "").equals("true")) + { + loggedIn = false; + correctTan = false; + + } + if (loggedIn && correctTan) + { + loggedIn = false; + correctTan = false; + + createSuccessfulLoginContent(s, ec, hiddenUser); + + } + else if (loggedIn) + { + if (currentTanNr > 5) + { + createNoTanLeftContent(ec); + } + else + { + createAskForTanContent(s, ec, currentTanNr, 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); + } + + System.out.println("Logged In: " + loggedIn); + + 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()); + + updateTan(user, s); + } + + /** + * 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("
No tan is left! Please contact the admin.
"); + ec.addElement(h); + ec.addElement(createLogoutLink()); + } + + private void createSuccessfulLoginContent(WebSession s, ElementContainer ec, String user) + { + + 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(user)); + + try + { + ResultSet results = getUser(user, s); + if (results != null) + { + 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"))); + + if (!user.equals(LoggedInUser)) + { + 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); + + try + { + Connection 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(); + } + + } + + /** + * Get a user by its name + * + * @param user + * @param s + * @return ResultSet containing the user + */ + private ResultSet getUser(String user, WebSession s) + { + try + { + Connection 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(); + } + return null; + + } + + /** + * If lesson is reseted the tans should be resetted too + * + * @param s + */ + private void resetTans(WebSession s) + { + + try + { + Connection 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(); + } + + } + + /** + * Get the count of the tan + * + * @param user + * @param s + * @return tanPosition + */ + private int getTanPosition(String user, WebSession s) + { + int tanNr = 0; + try + { + Connection 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(); + } + + 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) + { + try + { + Connection 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(); + } + return ""; + + } + + /** + * See if the tan is correct + * + * @param tan + * @return true if the tan is correct + */ + private boolean correctTan(String tan) + { + if (!currentTan.equals("")) { return tan.equals(String.valueOf(currentTan)); } + 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) + { + try + { + Connection 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(); + } + + return false; + + } + + protected Category getDefaultCategory() + { + return Category.AUTHENTICATION; + } + + /** + * Gets the hints attribute of the RoleBasedAccessControl object + * + * @return The hints value + */ + public List getHints(WebSession s) + { + List hints = new ArrayList(); + + 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 Joe and your password is banana. This are your TANS:
" + + "Tan #1 = 15161
" + + "Tan #2 = 4894
" + + "Tan #3 = 18794
" + + "Tan #4 = 1564
" + + "Tan #5 = 45751
"; + + 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("")); + } + +} diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/NewLesson.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/NewLesson.java index 09d1c1d53..ce125fee1 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/NewLesson.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/NewLesson.java @@ -60,7 +60,7 @@ public class NewLesson extends LessonAdapter */ protected Category getDefaultCategory() { - return Category.GENERAL; + return Category.INTRODUCTION; } private final static Integer DEFAULT_RANKING = new Integer(85); diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/PasswordStrength.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/PasswordStrength.java new file mode 100644 index 000000000..e405792f0 --- /dev/null +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/PasswordStrength.java @@ -0,0 +1,204 @@ + +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.BR; +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.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 Reto Lippuner, Marcel Wirth + * @created April 7, 2008 + */ + +public class PasswordStrength extends LessonAdapter +{ + private final static String USER = "user"; + + /** + * Description of the Method + * + * @param s + * Description of the Parameter + * @return Description of the Return Value + */ + protected Element createContent(WebSession s) + { + ElementContainer ec = new ElementContainer(); + + StringBuffer person = null; + try + { + + ec.addElement(new StringElement("How much time you need for these passwords? ")); + ec.addElement(new BR()); + ec.addElement(new BR()); + ec.addElement(new BR()); + Table table = new Table(); + table.addAttribute("align='center'", 0); + TR tr1 = new TR(); + TD td1 = new TD(); + TD td2 = new TD(); + Input input1 = new Input(Input.TEXT, "pass1", ""); + td1.addElement(new StringElement("Password = 123456")); + td2.addElement(input1); + td2.addElement(new StringElement("seconds")); + tr1.addElement(td1); + tr1.addElement(td2); + + TR tr2 = new TR(); + TD td3 = new TD(); + TD td4 = new TD(); + Input input2 = new Input(Input.TEXT, "pass2", ""); + td3.addElement(new StringElement("Password = abzfez")); + td4.addElement(input2); + td4.addElement(new StringElement("seconds")); + tr2.addElement(td3); + tr2.addElement(td4); + + TR tr3 = new TR(); + TD td5 = new TD(); + TD td6 = new TD(); + Input input3 = new Input(Input.TEXT, "pass3", ""); + td5.addElement(new StringElement("Password = a9z1ez")); + td6.addElement(input3); + td6.addElement(new StringElement("hours")); + tr3.addElement(td5); + tr3.addElement(td6); + + TR tr4 = new TR(); + TD td7 = new TD(); + TD td8 = new TD(); + Input input4 = new Input(Input.TEXT, "pass4", ""); + td7.addElement(new StringElement("Password = aB8fEz")); + td8.addElement(input4); + td8.addElement(new StringElement("days")); + tr4.addElement(td7); + tr4.addElement(td8); + + TR tr5 = new TR(); + TD td9 = new TD(); + TD td10 = new TD(); + Input input5 = new Input(Input.TEXT, "pass5", ""); + td9.addElement(new StringElement("Password = z8!E?7")); + td10.addElement(input5); + td10.addElement(new StringElement("days")); + tr5.addElement(td9); + tr5.addElement(td10); + table.addElement(tr1); + table.addElement(tr2); + table.addElement(tr3); + table.addElement(tr4); + table.addElement(tr5); + ec.addElement(table); + ec.addElement(new BR()); + ec.addElement(new BR()); + Element b = ECSFactory.makeButton("Go!"); + ec.addElement(b); + } catch (Exception e) + { + s.setMessage("Error generating " + this.getClass().getName()); + e.printStackTrace(); + } + + if (s.getParser().getStringParameter("pass1", "").equals("0") + && s.getParser().getStringParameter("pass2", "").equals("1394") + && s.getParser().getStringParameter("pass3", "").equals("5") + && s.getParser().getStringParameter("pass4", "").equals("2") + && s.getParser().getStringParameter("pass5", "").equals("41")) + { + makeSuccess(s); + } + + return (ec); + } + + /** + * Gets the hints attribute of the HelloScreen object + * + * @return The hints value + */ + public List getHints(WebSession s) + { + List hints = new ArrayList(); + hints.add("Copy the passwords in the code checker."); + return hints; + } + + /** + * Gets the ranking attribute of the HelloScreen object + * + * @return The ranking value + */ + private final static Integer DEFAULT_RANKING = new Integer(6); + + protected Integer getDefaultRanking() + { + return DEFAULT_RANKING; + } + + protected Category getDefaultCategory() + { + return Category.AUTHENTICATION; + } + + public String getInstructions(WebSession s) + { + String instructions = "The Accounts of your Webapplication are only as save as the passwords. " + + "For this exercise, your job is to test several passwords on https://www.cnlab.ch/codecheck. " + + " You must test all 5 passwords at the same time...
" + + " On your applications you should set good password requirements! "; + return (instructions); + } + + /** + * Gets the title attribute of the HelloScreen object + * + * @return The title value + */ + public String getTitle() + { + return ("Password Strength"); + } + + public Element getCredits() + { + return super.getCustomCredits("Created by: Reto Lippuner, Marcel Wirth", new StringElement("")); + } +} diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Phishing.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Phishing.java index f529f9e77..941d113da 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Phishing.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/Phishing.java @@ -177,7 +177,7 @@ public class Phishing extends LessonAdapter hints .add("Add functionality that can post a request, a button might work

" + "After getting the button on the page, don't forget you will need to steal the credentials and post them to:
" - + "http://localhost./WebGoat/capture/PROPERTY=yes&ADD_CREDENTIALS_HERE"); + + "http://localhost/WebGoat/capture/PROPERTY=yes&ADD_CREDENTIALS_HERE"); hints .add("Try:
" + "<input type="submit" name="login" " @@ -207,28 +207,27 @@ public class Phishing extends LessonAdapter + "
  • javascript string concatentation uses a \"+\" " + "

    Solution for this hint():

    " + "password<script>function hack(){ alert("Had this been a real attack... Your credentials were just stolen." - + "\nUser Name = " + document.forms(0).user.value + "\nPassword = " + document.forms(0).pass.value); " - + "XSSImage=new Image; XSSImage.src="http://localhost./WebGoat/catcher?PROPERTY=yes&user="+" - + "document.forms(0).user.value + "&password=" + document.forms(0).pass.value + "";}" + + "\nUser Name = " + document.forms[0].user.value + "\nPassword = " + document.forms[0].pass.value); " + + "XSSImage=new Image; XSSImage.src="http://localhost/WebGoat/catcher?PROPERTY=yes&user="+" + + "document.forms[0].user.value + "&password=" + document.forms[0].pass.value + "";}" + "</script>"); hints .add("Complete solution for this lesson:

    " + "password<script>function hack(){ alert("Had this been a real attack... Your credentials were just stolen." - + "\nUser Name = " + document.forms(0).user.value + "\nPassword = " + document.forms(0).pass.value); " - + "XSSImage=new Image; XSSImage.src="http://localhost./WebGoat/catcher?PROPERTY=yes&user="+" - + "document.forms(0).user.value + "&password=" + document.forms(0).pass.value + "";}" + + "\nUser Name = " + document.forms[0].user.value + "\nPassword = " + document.forms[0].pass.value); " + + "XSSImage=new Image; XSSImage.src="http://localhost/WebGoat/catcher?PROPERTY=yes&user="+" + + "document.forms[0].user.value + "&password=" + document.forms[0].pass.value + "";}" + "</script><form><br><br><HR><H3>This feature requires account login:</H2" + "><br><br>Enter Username:<br><input type="text" id="user" " + "name="user"><br>Enter Password:<br><input type="password" " + "name = "pass"><br><input type="submit" name="login" " - + "value="login" onclick="hack()"></form><br><br><HR>" - + "

    You may need to remove the '.' from the http://localhost./"); + + "value="login" onclick="hack()"></form><br><br><HR>"); /** * password

    + * were just stolen.\nUser Name = " + document.forms[0].user.value + "\nPassword = " + + * document.forms[0].pass.value); XSSImage=new Image; + * XSSImage.src="http://localhost/WebGoat/catcher?PROPERTY=yes&user="+document.forms[0].user.value + + * "&password=" + document.forms[0].pass.value + "";}
    *
    *
    *

    This feature requires account login:

    @@ -259,7 +258,7 @@ public class Phishing extends LessonAdapter + "Using XSS and HTML insertion, your goal is to:
      " + "
    • Insert html to that requests credentials" + "
    • Add javascript to actually collect the credentials" - + "
    • Post the credentials to http://localhost./WebGoat/catcher?PROPERTY=yes...
    " + + "
  • Post the credentials to http://localhost/WebGoat/catcher?PROPERTY=yes... " + "To pass this lesson, the credentials must be posted to the catcher servlet.
    "; return (instructions); diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RemoteAdminFlaw.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RemoteAdminFlaw.java index 81d1f9e63..11873247f 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RemoteAdminFlaw.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RemoteAdminFlaw.java @@ -85,9 +85,9 @@ public class RemoteAdminFlaw extends LessonAdapter List hints = new ArrayList(); hints.add("WebGoat has 2 admin interfaces."); hints.add("WebGoat has one admin interface that is controlled via a URL parameter and is 'hackable'"); - hints - .add("WebGoat has one admin interface that is controlled via server side security constraints and should not be 'hackable'"); + hints.add("WebGoat has one admin interface that is controlled via server side security constraints and should not be 'hackable'"); hints.add("Follow the Source!"); + hints.add("On success you will see new submenu items in the menupoint 'Admin Functions'"); return hints; } diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/RoleBasedAccessControl.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/RoleBasedAccessControl.java index c4b8aaf55..aff7c7767 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/RoleBasedAccessControl.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/RoleBasedAccessControl/RoleBasedAccessControl.java @@ -1,9 +1,17 @@ package org.owasp.webgoat.lessons.RoleBasedAccessControl; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.ecs.ElementContainer; +import org.apache.ecs.StringElement; +import org.apache.ecs.html.Body; +import org.apache.ecs.html.Head; +import org.apache.ecs.html.Html; +import org.apache.ecs.html.Title; import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.GoatHillsFinancial.DefaultLessonAction; import org.owasp.webgoat.lessons.GoatHillsFinancial.FindProfile; @@ -85,6 +93,7 @@ public class RoleBasedAccessControl extends GoatHillsFinancial return Category.ACCESS_CONTROL; } + /** * Gets the hints attribute of the DirectoryScreen object * @@ -92,22 +101,29 @@ public class RoleBasedAccessControl extends GoatHillsFinancial */ protected List getHints(WebSession s) { + String stage = getStage(s); List hints = new ArrayList(); hints.add("Many sites attempt to restrict access to resources by role."); hints.add("Developers frequently make mistakes implementing this scheme."); hints.add("Attempt combinations of users, roles, and resources."); // Stage 1 - hints.add("How does the application know that the user selected the delete function?"); + hints.add("Stage1: How does the application know that the user selected the delete function?"); + + + hints.add("Stage2: You have to code to check the authorization of the user for the action."); // Stage 2 + + // Stage 3 - hints.add("How does the application know that the user selected any particular employee to view?"); + hints.add("Stage3: How does the application know that the user selected any particular employee to view?"); + // Stage 4 - hints.add("Note that the contents of the staff listing change depending on who is logged in."); - + hints.add("Stage4: You have to code to check the authorization of the user for the action on a certain employee."); + return hints; } @@ -134,13 +150,16 @@ public class RoleBasedAccessControl extends GoatHillsFinancial { instructions = "Stage 1: Bypass Presentational Layer Access Control.
    " + "As regular employee 'Tom', exploit weak access control to use the Delete function from the Staff List page. " - + "Verify that Tom's profile can be deleted."; + + "Verify that Tom's profile can be deleted." + + "The password for a user is always his prename.."; } else if (STAGE2.equals(stage)) { - instructions = "Stage 2: Add Business Layer Access Control.
    " + instructions ="Stage 2: Add Business Layer Access Control.

    " + + " THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT

    " + "Implement a fix to deny unauthorized access to the Delete function. " - + "Repeat stage 1. Verify that access to Delete is properly denied."; + + "Repeat stage 1. Verify that access to Delete is properly denied.
    " + + "To do this you have to alter code."; } else if (STAGE3.equals(stage)) { @@ -149,7 +168,8 @@ public class RoleBasedAccessControl extends GoatHillsFinancial } else if (STAGE4.equals(stage)) { - instructions = "Stage 4: Add Data Layer Access Control.
    " + instructions = "Stage 4: Add Data Layer Access Control.

    " + + " THIS LESSON ONLY WORKS WITH THE DEVELOPER VERSION OF WEBGOAT

    " + "Implement a fix to deny unauthorized access to this data. " + "Repeat stage 3. Verify that access to other employee's profiles is properly denied."; } @@ -157,6 +177,41 @@ public class RoleBasedAccessControl extends GoatHillsFinancial return instructions; } + + public String getLessonSolutionFileName(WebSession s) { + String solutionFileName = null; + String stage = getStage(s); + solutionFileName = "/lesson_solutions/Lab Access Control/Lab " + stage + ".html"; + return solutionFileName; + } + + @Override + public String getSolution(WebSession s) { + String src = null; + + try + { + System.out.println("Solution: " + getLessonSolutionFileName(s)); + src = readFromFile(new BufferedReader(new FileReader(s.getWebResource(getLessonSolutionFileName(s)))), false); + } catch (IOException e) + { + s.setMessage("Could not find the solution file"); + src = ("Could not find the solution file"); + } + +// Html html = new Html(); +// +// Head head = new Head(); +// head.addElement(new Title(getLessonSolutionFileName(s))); +// +// Body body = new Body(); +// body.addElement(new StringElement(src)); +// +// html.addElement(head); +// html.addElement(body); + + return src; + } public void handleRequest(WebSession s) { @@ -179,7 +234,7 @@ public class RoleBasedAccessControl extends GoatHillsFinancial try { - LessonAction action = getAction(requestedActionName); + DefaultLessonAction action = (DefaultLessonAction) getAction(requestedActionName); if (action != null) { // System.out.println("RoleBasedAccessControl.handleRequest() dispatching to: " + @@ -191,6 +246,11 @@ public class RoleBasedAccessControl extends GoatHillsFinancial } else { + //***************CODE HERE************************* + + + + //************************************************* if (action.isAuthenticated(s)) { action.handleRequest(s); diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/ViewProfile.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/ViewProfile.java index 9d0bdd396..9cd13499b 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/ViewProfile.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SQLInjection/ViewProfile.java @@ -117,6 +117,7 @@ public class ViewProfile extends DefaultLessonAction .getInt("salary"), answer_results.getString("ccn"), answer_results .getInt("ccn_limit"), answer_results.getString("disciplined_date"), answer_results .getString("disciplined_notes"), answer_results.getString("personal_description")); + System.out.println("Profile: " + profile); /* * System.out.println("Retrieved employee from db: " + profile.getFirstName() + " " + * profile.getLastName() + " (" + profile.getId() + ")"); diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SessionFixation.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SessionFixation.java new file mode 100644 index 000000000..db69846ca --- /dev/null +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SessionFixation.java @@ -0,0 +1,462 @@ + +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.html.B; +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.owasp.webgoat.session.WebSession; + + +public class SessionFixation extends SequentialLessonAdapter +{ + + private String LoggedInUser = ""; + + 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 = "mailname"; + + private final static String USER = "user"; + private final static String PASSWORD = "pass"; + + /** + * Creates Staged WebContent + * + * @param s + */ + protected Element createContent(WebSession s) + { + 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(); + String mailContent = s.getParser().getStringParameter(MAILCONTENTNAME, ""); + if (mailContent.contains("SSID")) + { + + // ec.addElement(mailContent); + return ec; + } + + ec.addElement(createStage1Content(s)); + return ec; + + } + + private Element createStage1Content(WebSession s) + { + + String link = getLink(); + String mailText = "Dear MS. Plane

    " + "During the last week we had a few problems with our servers. " + + "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:

    WebGoat Financial


    " + + "We are sorry for the caused inconvenience and thank you for your colaboration.

    " + + "Your WebGoat 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("MailTo: "); + td1.addElement(b); + td2.addElement(mailTo); + + b = new B(); + b.addElement("MailFrom: "); + 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", 50); + mailContent.addAttribute("rows", 10); + 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 createMainContent(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(); + // + // 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 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(LoggedInUser)); + // + // try + // { + // ResultSet results = getUser(LoggedInUser, 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) + // { + // try { + // Connection 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(); + // } + // return null; + // + // } + + // /** + // * 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) + // { + // try { + // Connection 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(); + // } + // + // return false; + // + // } + + /** + * 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: Just do a regular login"); + hints.add("Stage 2: How does the server know which TAN has to be used"); + hints.add("Stage 2: Maybe taking a look at the source code helps"); + hints.add("Stage 2: Watch out for hidden fields"); + hints.add("Stage 2: Manipulate the hidden field 'hidden_tan'"); + + return hints; + + } + + /** + * Get the instructions for the user + */ + public String getInstructions(WebSession s) + { + String instructions = "Stub"; + + 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"); + } + +} diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SqlNumericInjection.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SqlNumericInjection.java index 07ef38ac3..6e9185834 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SqlNumericInjection.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/SqlNumericInjection.java @@ -303,12 +303,13 @@ public class SqlNumericInjection extends SequentialLessonAdapter protected List getHints(WebSession s) { List hints = new ArrayList(); - hints.add("The application is taking your input and inserting it at the end of a pre-formed SQL command."); + hints.add("The application is taking the input from the select box and inserts it at the end of a pre-formed SQL command."); hints.add("This is the code for the query being built and issued by WebGoat:

    " + "\"SELECT * FROM weather_data WHERE station = \" + station "); hints.add("Compound SQL statements can be made by joining multiple tests with keywords like AND and OR. " + "Try appending a SQL statement that always resolves to true."); - hints.add("Try entering [ 101 OR 1 = 1 ]."); + hints.add("Try to intercept the post request with WebScarab and replace the station " + + "with 101 OR 1 = 1"); return hints; } diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/StoredXss.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/StoredXss.java index 0806da40c..9e395041d 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/StoredXss.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/StoredXss.java @@ -159,9 +159,8 @@ public class StoredXss extends LessonAdapter List hints = new ArrayList(); hints.add("You can put HTML tags in your message."); hints.add("Bury a SCRIPT tag in the message to attack anyone who reads it."); - hints - .add("Enter this: <script language=\"javascript\" type=\"text/javascript\">alert(\"Ha Ha Ha\");</script> in the message field."); - hints.add("Enter this: <script>alert(\"document.cookie\");</script> in the message field."); + hints.add("Enter this: <script language=\"javascript\" type=\"text/javascript\">alert(\"Ha Ha Ha\");</script> in the message field."); + hints.add("Enter this: <script>alert(document.cookie);</script> in the message field."); return hints; } diff --git a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/UncheckedEmail.java b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/UncheckedEmail.java index fb63dcba8..63c8f0496 100644 --- a/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/UncheckedEmail.java +++ b/webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/UncheckedEmail.java @@ -125,9 +125,14 @@ public class UncheckedEmail extends LessonAdapter sendSimulatedMail(ec, to, subject, message); } } + + if(to.length() > 0 && "webgoat.admin@owasp.org".equals(to) && message.contains("