From 4e6c72154556e84442aedf9e2dc71a4d4929ddd7 Mon Sep 17 00:00:00 2001 From: Benedikt - Desktop Date: Mon, 5 Nov 2018 17:31:56 +0100 Subject: [PATCH] Added an assignment for compromising integrity by query chaining to the sql injections (introduction) --- .../introduction/SqlInjectionLesson10.java | 30 ++++++++ .../introduction/SqlInjectionLesson9.java | 73 +++++++++++++++++++ .../src/main/resources/html/SqlInjection.html | 22 +++--- .../resources/i18n/WebGoatLabels.properties | 19 +++-- .../SqlInjection_introduction_content9.adoc | 18 ++--- 5 files changed, 131 insertions(+), 31 deletions(-) create mode 100644 webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson10.java create mode 100644 webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson9.java 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 new file mode 100644 index 000000000..e5723501b --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson10.java @@ -0,0 +1,30 @@ + +package org.owasp.webgoat.plugin.introduction; + +import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentHints; +import org.owasp.webgoat.assignments.AssignmentPath; +import org.owasp.webgoat.assignments.AttackResult; +import org.owasp.webgoat.session.DatabaseUtilities; +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.sql.*; + +@AssignmentPath("/SqlInjection/attack10") +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); + } + + protected AttackResult injectableQueryConfidentiality(String name, String auth_tan) { + return trackProgress(failed().build()); + } + +} 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 new file mode 100644 index 000000000..305edfc65 --- /dev/null +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson9.java @@ -0,0 +1,73 @@ + +package org.owasp.webgoat.plugin.introduction; + +import org.owasp.webgoat.assignments.AssignmentEndpoint; +import org.owasp.webgoat.assignments.AssignmentHints; +import org.owasp.webgoat.assignments.AssignmentPath; +import org.owasp.webgoat.assignments.AttackResult; +import org.owasp.webgoat.session.DatabaseUtilities; +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.sql.*; + +@AssignmentPath("/SqlInjection/attack9") +@AssignmentHints(value = {"SqlStringInjectionHint9-1", "SqlStringInjectionHint9-2", "SqlStringInjectionHint9-3", "SqlStringInjectionHint9-4", "SqlStringInjectionHint9-5"}) +public class SqlInjectionLesson9 extends AssignmentEndpoint { + + @RequestMapping(method = RequestMethod.POST) + public + @ResponseBody + AttackResult completed(@RequestParam String name, @RequestParam String auth_tan) { + return injectableQueryIntegrity(name, auth_tan); + } + + protected AttackResult injectableQueryIntegrity(String name, String auth_tan) { + StringBuffer output = new StringBuffer(); + 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 results = statement.executeQuery(query); + + results.first(); + + ResultSetMetaData resultsMetaData = results.getMetaData(); + output.append(SqlInjectionLesson8.generateTable(results, resultsMetaData)); + } catch (SQLException e) { + System.err.println(e.getMessage()); + return trackProgress(failed().output(e.getMessage()).build()); + } + + 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()); + } + + } catch (Exception e) { + System.err.println(e.getMessage()); + return trackProgress(failed().output(this.getClass().getName() + " : " + 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 874afc53e..7d4acc81a 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/html/SqlInjection.html +++ b/webgoat-lessons/sql-injection/src/main/resources/html/SqlInjection.html @@ -62,12 +62,12 @@ autocomplete="off"> - - + + - - + + @@ -85,21 +85,19 @@
- - + + - - + + - - +
Login_Count:
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 4131255be..90b5fe90d 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties @@ -11,15 +11,6 @@ SqlInjectionChallenge2=The vulnerability is on the register form SqlInjectionChallenge3=Use tooling to automate this attack NoResultsMatched=No results matched. Try Again. -SqlStringInjectionHint5a1=The application is taking your input and inserting it at the end of a pre-formed SQL command. -SqlStringInjectionHint5a2=This is the code for the query being built and issued by WebGoat:

"SELECT * FROM user_data WHERE last_name = "accountName" -SqlStringInjectionHint5a3=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 -SqlStringInjectionHint5a4=Make sure all quotes (" ' ") are opened and closed properly. -SqlStringInjectionHint5a5=Try appending the Statement with something like: OR 1 = 1. -SqlStringInjectionHint5b1=This is the code for the query being built and issued by WebGoat:

"SELECT * FROM user_data WHERE Login_Count = "Login_Count" and User_Id = "Name" -SqlStringInjectionHint5b2=Note that you don't need to insert any quotations. -SqlStringInjectionHint5b3=Remember how you solved the previous assignment. -SqlStringInjectionHint5b4=It does not matter where you insert a statement that always resolves to true. SqlStringInjectionHint6=Try Appending a new SQL Statement to the Query. SqlStringInjectionHint7=The new SQL Statement can be really simple like: SELECT ... FROM ... SqlStringInjectionHint8=Your new SQL Query should start, with a " ; " and end with " -- " @@ -45,7 +36,7 @@ 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 succeed: {0} +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? 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. @@ -53,3 +44,11 @@ SqlStringInjectionHint8-2=Compound SQL statements can be made by expanding the W SqlStringInjectionHint8-3=Try appending a SQL statement that always resolves to true. 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. {0} + +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.... diff --git a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_introduction_content9.adoc b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_introduction_content9.adoc index 2f2e70fd0..6b769bea7 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_introduction_content9.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_introduction_content9.adoc @@ -1,11 +1,11 @@ -Integrity +== Compromising Integrity with Query Chaining +After compromising the confidentiality of data in the previous lesson, this time we are gonna compromise the integrity of data by using a SQL query chaining. -== Try It! Numeric SQL Injection +== What is SQL query chaining? +Query chaining is exactly what it sounds like. When query chaining, you try to append one or more queries to the end of the actual query. +You can do this by using the *;* metacharacter which marks the end of a query and that way allows to start another one right after it within the same line. -The query in the code builds a dynamic query as seen in the previous example. The query in the code builds a dynamic query by concatenating a number making it susceptible to Numeric SQL injection: - --------------------------------------------------- -"select * from users where Login_Count = " + Login_Count + " and USERID = " + userID; --------------------------------------------------- - -Using the form below try to retrieve all the users from the users table. You shouldn't need to know any specific user name or Login_Count to get the complete list. +=== It's your turn! +You just found out that Tobi and Bob both seem to earn more money than you! +Of course you cannot leave it at that. + +Better go and change your salary so you're at the earner.