From 6fe7582dfba802cc21ce60125f53a6c9de405436 Mon Sep 17 00:00:00 2001 From: Benedikt - Desktop Date: Mon, 5 Nov 2018 19:39:22 +0100 Subject: [PATCH] Added an assignment for compromising availability to the sql injections (introduction). WIP --- .../org/owasp/webgoat/session/CreateDB.java | 24 ++++++-- .../introduction/SqlInjectionLesson10.java | 56 +++++++++++++++++-- .../introduction/SqlInjectionLesson8.java | 17 ++++++ .../introduction/SqlInjectionLesson9.java | 49 ++++++++-------- .../src/main/resources/html/SqlInjection.html | 18 +++--- .../resources/i18n/WebGoatLabels.properties | 2 + .../SqlInjection_introduction_content10.adoc | 9 ++- 7 files changed, 136 insertions(+), 39 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 8edb54dc9..31e1bb3da 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 @@ -988,15 +988,19 @@ public class CreateDB { private void createEmployeesTable(Connection connection) throws SQLException { Statement statement = connection.createStatement(); - // Drop employees table + // Drop employees and access_log tables try { - String dropTable = "DROP TABLE employees"; - statement.executeUpdate(dropTable); + statement.executeUpdate("DROP TABLE employees"); } catch (SQLException e) { System.out.println("Info - Could not drop employees table"); } + try { + statement.executeUpdate("DROP TABLE access_log"); + } catch (SQLException e) { + System.out.println("Info - Could not drop access_log table"); + } - // Create the new table + // Create the employees table try { String createTableStatement = "CREATE TABLE employees (" + "userid varchar(6) not null primary key," @@ -1022,6 +1026,18 @@ public class CreateDB { statement.executeUpdate(insertData3); statement.executeUpdate(insertData4); statement.executeUpdate(insertData5); + + // Create the logging table + try { + String createTableStatement = "CREATE TABLE access_log (" + + "id int not null primary key identity," + + "time varchar(50)," + + "action varchar(200)" + + ")"; + statement.executeUpdate(createTableStatement); + } catch (SQLException e) { + System.out.println("Error creating access_log table " + e.getLocalizedMessage()); + } } /** 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 e5723501b..e1dcc4add 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 @@ -19,12 +19,60 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) public @ResponseBody - AttackResult completed(@RequestParam String name, @RequestParam String auth_tan) { - return injectableQueryConfidentiality(name, auth_tan); + AttackResult completed(@RequestParam String action) { + return injectableQueryAvailability(action); } - protected AttackResult injectableQueryConfidentiality(String name, String auth_tan) { - return trackProgress(failed().build()); + protected AttackResult injectableQueryAvailability(String 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)); + results.last(); + + return trackProgress(failed().output(output.toString()).build()); + } else { + if (tableExists(connection)) { + return trackProgress(failed().output(output.toString()).build()); + } + else { + return trackProgress(success().feedback("sql-injection.10.success").build()); + } + } + } catch (SQLException e) { + if (tableExists(connection)) { + return trackProgress(failed().output(output.toString()).build()); + } + else { + return trackProgress(success().feedback("sql-injection.10.success").build()); + } + } + + } catch (Exception e) { + return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build()); + } + } + + private boolean tableExists(Connection connection) throws SQLException { + ResultSet res = connection.getMetaData().getTables(null, null, "access_log", null); + while (res.next()) { + String table_name = res.getString("TABLE_NAME"); + if (table_name != null && table_name.equals("access_log")) { + return true; + } + } + + return false; } } 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 be5ed678f..f7144f893 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 @@ -10,6 +10,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import java.util.Calendar; +import java.text.SimpleDateFormat; import java.sql.*; @@ -31,6 +33,7 @@ public class SqlInjectionLesson8 extends AssignmentEndpoint { 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())) { @@ -88,5 +91,19 @@ public class SqlInjectionLesson8 extends AssignmentEndpoint { return (t.toString()); } + public static void log(Connection connection, String action) { + action = action.replace('\'', '"'); + Calendar cal = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String time = sdf.format(cal.getTime()); + String log_query = "INSERT INTO access_log (time, action) VALUES ('" + time + "', '" + action + "')"; + + try { + Statement statement = connection.createStatement(); + statement.executeUpdate(log_query); + } catch (SQLException e) { + System.err.println(e.getMessage()); + } + } } 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 305edfc65..36da98a24 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 @@ -31,7 +31,8 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint { try { String query = "SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'"; - Statement statement = connection.createStatement(); + Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + SqlInjectionLesson8.log(connection, query); ResultSet results = statement.executeQuery(query); results.first(); @@ -40,29 +41,10 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint { output.append(SqlInjectionLesson8.generateTable(results, resultsMetaData)); } catch (SQLException e) { System.err.println(e.getMessage()); - return trackProgress(failed().output(e.getMessage()).build()); + return checkSalaryRanking(connection, output); } - try { - String query = "SELECT * FROM employees ORDER BY salary desc"; - Statement statement = connection.createStatement(); - ResultSet results = statement.executeQuery(query); - - results.first(); - System.out.println(results.getString(2)); - System.out.println(results.getString(3)); - - // user completes lesson if John Smith is the first in the list - if ((results.getString(2).equals("John")) && (results.getString(3).equals("Smith"))) { - return trackProgress(success().feedback("sql-injection.9.success").feedbackArgs(output.toString()).build()); - } else { - return trackProgress(failed().output(output.toString()).build()); - } - - } catch (SQLException e) { - System.err.println(e.getMessage()); - return trackProgress(failed().output(e.getMessage()).build()); - } + return checkSalaryRanking(connection, output); } catch (Exception e) { System.err.println(e.getMessage()); @@ -70,4 +52,27 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint { } } + private AttackResult checkSalaryRanking(Connection connection, StringBuffer output) { + try { + String query = "SELECT * FROM employees ORDER BY salary DESC"; + Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet results = statement.executeQuery(query); + + results.first(); + System.out.println(results.getString(2)); + System.out.println(results.getString(3)); + + // user completes lesson if John Smith is the first in the list + if ((results.getString(2).equals("John")) && (results.getString(3).equals("Smith"))) { + return trackProgress(success().feedback("sql-injection.9.success").feedbackArgs(output.toString()).build()); + } else { + return trackProgress(failed().output(output.toString()).build()); + } + + } catch (SQLException e) { + System.err.println(e.getMessage()); + return trackProgress(failed().output(e.getMessage()).build()); + } + } + } diff --git a/webgoat-lessons/sql-injection/src/main/resources/html/SqlInjection.html b/webgoat-lessons/sql-injection/src/main/resources/html/SqlInjection.html index 7d4acc81a..f99ea51f3 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/html/SqlInjection.html +++ b/webgoat-lessons/sql-injection/src/main/resources/html/SqlInjection.html @@ -86,7 +86,8 @@
+ enctype="application/json;charset=UTF-8" + autocomplete="off"> @@ -109,19 +110,20 @@
-
+ action="/WebGoat/SqlInjection/attack10" + enctype="application/json;charset=UTF-8" + autocomplete="off">
- - - + + + + +
Account Name:
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 90b5fe90d..7c0e27cf2 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties @@ -52,3 +52,5 @@ 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. \ No newline at end of file diff --git a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_introduction_content10.adoc b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_introduction_content10.adoc index b3a12d370..633bc8215 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_introduction_content10.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_introduction_content10.adoc @@ -1 +1,8 @@ -Availiability \ No newline at end of file +== Compromising Availability +After successfully compromising confidentiality and integrity in the previous lessons, we now are going to compromise the third element of the CIA-Triad: *availability*. + +=== It's your turn! +Now you're the top earner in your company. +But do you see that? +There seems to be a table, where all your actions have been logged to! + +Better go and delete it quickly before anyone notices.