From 1bcddaf710fdf5e5520a15ee7852a4576e840151 Mon Sep 17 00:00:00 2001 From: Benedikt - Desktop Date: Tue, 6 Nov 2018 17:44:26 +0100 Subject: [PATCH] Reworked and polished assignment 8 and 9 (C and I) --- .../org/owasp/webgoat/session/CreateDB.java | 12 ++-- .../introduction/SqlInjectionLesson10.java | 19 +++---- .../introduction/SqlInjectionLesson8.java | 57 +++++++++++-------- .../introduction/SqlInjectionLesson9.java | 19 ++++--- .../src/main/resources/css/assignments.css | 6 +- .../resources/i18n/WebGoatLabels.properties | 19 +++++-- 6 files changed, 73 insertions(+), 59 deletions(-) diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java b/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java index 31e1bb3da..a34e734db 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/session/CreateDB.java @@ -1007,7 +1007,7 @@ public class CreateDB { + "first_name varchar(20)," + "last_name varchar(20)," + "department varchar(20)," - + "salary varchar(10)," + + "salary int," + "auth_tan varchar(6)" + ")"; statement.executeUpdate(createTableStatement); @@ -1016,11 +1016,11 @@ public class CreateDB { } // Populate - String insertData1 = "INSERT INTO employees VALUES ('32147','Paulina', 'Travers', 'Accounting', '$46.000', 'P45JSI')"; - String insertData2 = "INSERT INTO employees VALUES ('89762','Tobi', 'Barnett', 'Development', '$77.000', 'TA9LL1')"; - String insertData3 = "INSERT INTO employees VALUES ('96134','Bob', 'Franco', 'Marketing', '$83.700', 'LO9S2V')"; - String insertData4 = "INSERT INTO employees VALUES ('34477','Abraham ', 'Holman', 'Development', '$50.000', 'UU2ALK')"; - String insertData5 = "INSERT INTO employees VALUES ('37648','John', 'Smith', 'Marketing', '$64.350', '3SL99A')"; + String insertData1 = "INSERT INTO employees VALUES ('32147','Paulina', 'Travers', 'Accounting', 46000, 'P45JSI')"; + String insertData2 = "INSERT INTO employees VALUES ('89762','Tobi', 'Barnett', 'Development', 77000, 'TA9LL1')"; + String insertData3 = "INSERT INTO employees VALUES ('96134','Bob', 'Franco', 'Marketing', 83700, 'LO9S2V')"; + String insertData4 = "INSERT INTO employees VALUES ('34477','Abraham ', 'Holman', 'Development', 50000, 'UU2ALK')"; + String insertData5 = "INSERT INTO employees VALUES ('37648','John', 'Smith', 'Marketing', 64350, '3SL99A')"; statement.executeUpdate(insertData1); statement.executeUpdate(insertData2); statement.executeUpdate(insertData3); diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson10.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson10.java index 2fd3fdb3a..ff305bdf6 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson10.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson10.java @@ -25,23 +25,20 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint { } protected AttackResult injectableQueryAvailability(String action) { + StringBuffer output = new StringBuffer(); + String query = "SELECT * FROM access_log WHERE action LIKE '%" + action + "%'"; + try { Connection connection = DatabaseUtilities.getConnection(getWebSession()); - String query = "SELECT * FROM access_log WHERE action LIKE '%" + action + "%'"; - - StringBuffer output = new StringBuffer(); try { Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ResultSet results = statement.executeQuery(query); - if ((results != null) && (results.first())) { - ResultSetMetaData resultsMetaData = results.getMetaData(); - - output.append(SqlInjectionLesson8.generateTable(results, resultsMetaData)); + if (results.getStatement() != null && results.first()) { + output.append(SqlInjectionLesson8.generateTable(results)); results.last(); - - return trackProgress(failed().output(output.toString()).build()); + return trackProgress(failed().feedback("sql-injection.10.entries").output(output.toString()).build()); } else { if (tableExists(connection)) { return trackProgress(failed().output(output.toString()).build()); @@ -52,7 +49,7 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint { } } catch (SQLException e) { if (tableExists(connection)) { - return trackProgress(failed().output(output.toString()).build()); + return trackProgress(failed().output("" + e.getMessage() + "
" + output.toString()).build()); } else { return trackProgress(success().feedback("sql-injection.10.success").build()); @@ -60,7 +57,7 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint { } } catch (Exception e) { - return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build()); + return trackProgress(failed().output("" + e.getMessage() + "").build()); } } diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson8.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson8.java index f7144f893..f03b19c6c 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson8.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson8.java @@ -27,68 +27,75 @@ public class SqlInjectionLesson8 extends AssignmentEndpoint { } protected AttackResult injectableQueryConfidentiality(String name, String auth_tan) { + StringBuffer output = new StringBuffer(); + String query = "SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'"; + try { Connection connection = DatabaseUtilities.getConnection(getWebSession()); - String query = "SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'"; try { Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); log(connection, query); ResultSet results = statement.executeQuery(query); - if ((results != null) && (results.first())) { - ResultSetMetaData resultsMetaData = results.getMetaData(); - StringBuffer output = new StringBuffer(); + if (results.getStatement() != null) { + if (results.first()) { + output.append(generateTable(results)); + results.last(); - output.append(generateTable(results, resultsMetaData)); - results.last(); + if (results.getRow() > 1) { + // more than one record, the user succeeded + return trackProgress(success().feedback("sql-injection.8.success").output(output.toString()).build()); + } else { + // only one record + return trackProgress(failed().feedback("sql-injection.8.one").output(output.toString()).build()); + } - // If they get back more than one user they succeeded - if (results.getRow() > 1) { - return trackProgress(success().feedback("sql-injection.8.success").feedbackArgs(output.toString()).build()); } else { - return trackProgress(failed().output(output.toString()).build()); + // no results + return trackProgress(failed().feedback("sql-injection.8.no.results").build()); } } else { - return trackProgress(failed().feedback("sql-injection.8.no.results").build()); + return trackProgress(failed().feedback("sql-injection.error").build()); } } catch (SQLException e) { - return trackProgress(failed().output(e.getMessage()).build()); + return trackProgress(failed().feedback("sql-injection.error").output("
" + e.getMessage() + "").build()); } } catch (Exception e) { - return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build()); + return trackProgress(failed().feedback("sql-injection.error").output("
" + e.getMessage() + "").build()); } } - public static String generateTable(ResultSet results, ResultSetMetaData resultsMetaData) throws SQLException { + public static String generateTable(ResultSet results) throws SQLException { + ResultSetMetaData resultsMetaData = results.getMetaData(); int numColumns = resultsMetaData.getColumnCount(); results.beforeFirst(); - StringBuffer t = new StringBuffer(); - t.append(""); + StringBuffer table = new StringBuffer(); + table.append("
"); if (results.next()) { - t.append(""); + table.append(""); for (int i = 1; i < (numColumns + 1); i++) { - t.append(""); + table.append(""); } - t.append(""); + table.append(""); results.beforeFirst(); while (results.next()) { - t.append(""); + table.append(""); for (int i = 1; i < (numColumns + 1); i++) { - t.append(""); + table.append(""); } - t.append(""); + table.append(""); } } else { - t.append("Query Successful; however no data was returned from this query."); + table.append("Query Successful; however no data was returned from this query."); } - t.append("
" + resultsMetaData.getColumnName(i) + "" + resultsMetaData.getColumnName(i) + "
" + results.getString(i) + "" + results.getString(i) + "
"); - return (t.toString()); + table.append(""); + return (table.toString()); } public static void log(Connection connection, String action) { diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson9.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson9.java index dfee40190..4ef63c4e3 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson9.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson9.java @@ -26,28 +26,29 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint { protected AttackResult injectableQueryIntegrity(String name, String auth_tan) { StringBuffer output = new StringBuffer(); + String query = "SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'"; + try { Connection connection = DatabaseUtilities.getConnection(getWebSession()); try { - String query = "SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'"; Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); SqlInjectionLesson8.log(connection, query); ResultSet results = statement.executeQuery(query); - if (results != null && results.first()) { - output.append(SqlInjectionLesson8.generateTable(results, results.getMetaData())); + if (results.getStatement() != null && results.first()) { + output.append(SqlInjectionLesson8.generateTable(results)); } } catch (SQLException e) { System.err.println(e.getMessage()); - return checkSalaryRanking(connection, output); + return trackProgress(failed().feedback("sql-injection.error").output("
" + e.getMessage() + "").build()); } return checkSalaryRanking(connection, output); } catch (Exception e) { System.err.println(e.getMessage()); - return trackProgress(failed().output("
" + this.getClass().getName() + " : " + e.getMessage() + "").build()); + return trackProgress(failed().feedback("sql-injection.error").output("
" + e.getMessage() + "").build()); } } @@ -60,15 +61,15 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint { results.first(); // user completes lesson if John Smith is the first in the list if ((results.getString(2).equals("John")) && (results.getString(3).equals("Smith"))) { - output.append(SqlInjectionLesson8.generateTable(results, results.getMetaData())); - return trackProgress(success().feedback("sql-injection.8.success").feedbackArgs(output.toString()).build()); + output.append(SqlInjectionLesson8.generateTable(results)); + return trackProgress(success().feedback("sql-injection.9.success").output(output.toString()).build()); } else { - return trackProgress(failed().output(output.toString()).build()); + return trackProgress(failed().feedback("sql-injection.9.one").output(output.toString()).build()); } } catch (SQLException e) { System.err.println(e.getMessage()); - return trackProgress(failed().output("
" + e.getMessage() + "").build()); + return trackProgress(failed().feedback("sql-injection.error").output("
" + e.getMessage() + "").build()); } } diff --git a/webgoat-lessons/sql-injection/src/main/resources/css/assignments.css b/webgoat-lessons/sql-injection/src/main/resources/css/assignments.css index dc1e3cdd4..2c086e843 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/css/assignments.css +++ b/webgoat-lessons/sql-injection/src/main/resources/css/assignments.css @@ -1,7 +1,7 @@ -.attack-feedback { +.feedback-positive { color: green; } -.attack-feedback table { - color: black; +.feedback-negative { + color: red; } \ No newline at end of file diff --git a/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties b/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties index 94703284e..4b10380ab 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties @@ -5,10 +5,11 @@ EnterLastName=Enter your last name: sql.injection.title=SQL Injection (introduction) sql.mitigation.title=SQL Injection (mitigation) sql.advanced.title=SQL Injection (advanced) - + SqlInjectionChallenge1=Look at the different response you receive from the server SqlInjectionChallenge2=The vulnerability is on the register form SqlInjectionChallenge3=Use tooling to automate this attack +sql-injection.error=Sorry, this solution is not correct. Try again! NoResultsMatched=No results matched. Try Again. SqlStringInjectionHint6=Try Appending a new SQL Statement to the Query. @@ -36,10 +37,10 @@ sql-injection.6a.no.results=No results matched. Try Again. sql-injection.6b.success=You have succeeded: {0} sql-injection.6b.no.results=No results matched. Try Again. -sql-injection.8.success=You have succeeded! You successfully compromised the confidentiality of data by viewing internal information that you should not have access to. Well done! {0} -sql-injection.8.no.results=No employee found with matching lastname. Or maybe your authentication TAN is incorrect? -sql-injection.9.success=Well done! Now you're earning the most money. And at the same time you successfully compromised the integrity of data by changing the salary! {0} -sql-injection.10.success=Success! You successfully deleted the access_log table and that way compromised the availability of the data. + +sql-injection.8.success=You have succeeded! You successfully compromised the confidentiality of data by viewing internal information that you should not have access to. Well done! +sql-injection.8.no.results=No employee found with matching lastname. Or maybe your authentication TAN is incorrect? +sql-injection.8.one=That's only one account. You want them all! Try again. SqlStringInjectionHint8-1=The application is taking your input and inserting the values into the variables 'name' and 'auth_tan' of the pre-formed SQL command. SqlStringInjectionHint8-2=Compound SQL statements can be made by expanding the WHERE clause of the statement with keywords like AND and OR. @@ -47,12 +48,20 @@ SqlStringInjectionHint8-3=Try appending a SQL statement that always resolves to SqlStringInjectionHint8-4=Make sure all quotes (" ' ") are opened and closed properly so the resulting SQL query is syntactically correct. SqlStringInjectionHint8-5=Try extending the WHERE clause of the statement by adding something like: ' OR '1' = '1. + +sql-injection.9.success=Well done! Now you're earning the most money. And at the same time you successfully compromised the integrity of data by changing the salary! +sql-injection.9.one=Still not earning enough! Better try again and change that. + SqlStringInjectionHint9-1=Try to find a way, to chain another query to the end of the existing one. SqlStringInjectionHint9-2=Use the ; metacharacter to do so. SqlStringInjectionHint9-3=Make use of DML to change your salary. SqlStringInjectionHint9-4=Make sure that the resulting query is syntactically correct. SqlStringInjectionHint9-5=How about something like '; UPDATE employees.... + +sql-injection.10.success=Success! You successfully deleted the access_log table and that way compromised the availability of the data. +sql-injection.10.entries=There's still evidence of what you did. Better remove the whole table. + SqlStringInjectionHint10-1=Use the techniques that you have learned before. SqlStringInjectionHint10-2=The application takes your input and filters for entries that are LIKE it. SqlStringInjectionHint10-3=Try query chaining to reach the goal.