diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionLesson6a.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionLesson6a.java index 3650ef760..157e21606 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionLesson6a.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/advanced/SqlInjectionLesson6a.java @@ -46,7 +46,8 @@ import java.sql.*; * @created October 28, 2003 */ @AssignmentPath("/SqlInjection/attack6a") -@AssignmentHints(value = {"SqlStringInjectionHint-advanced-6a-1", "SqlStringInjectionHint-advanced-6a-2", "SqlStringInjectionHint-advanced-6a-3"}) +@AssignmentHints(value = {"SqlStringInjectionHint-advanced-6a-1", "SqlStringInjectionHint-advanced-6a-2", "SqlStringInjectionHint-advanced-6a-3", +"SqlStringInjectionHint-advanced-6a-4", "SqlStringInjectionHint-advanced-6a-5"}) public class SqlInjectionLesson6a extends AssignmentEndpoint { @RequestMapping(method = RequestMethod.POST) @@ -58,10 +59,11 @@ public class SqlInjectionLesson6a extends AssignmentEndpoint { } protected AttackResult injectableQuery(String accountName) { + String query = ""; try { boolean usedUnion = true; Connection connection = DatabaseUtilities.getConnection(getWebSession()); - String query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'"; + query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'"; //Check if Union is used if(!accountName.matches("(?i)(^[^-/*;)]*)(\\s*)UNION(.*$)")) { usedUnion = false; @@ -77,27 +79,26 @@ public class SqlInjectionLesson6a extends AssignmentEndpoint { output.append(SqlInjectionLesson5a.writeTable(results, resultsMetaData)); if(! usedUnion) - output.append("To succesfully complete this Assignement you have to use a UNION"); + output.append("To successfully complete this Assignment you have to use a UNION"); results.last(); // If they get back more than one user they succeeded if (results.getRow() >= 5 && usedUnion) { - return trackProgress(success().feedback("sql-injection.advanced.6a.success").feedbackArgs(output.toString()).build()); + return trackProgress(success().feedback("sql-injection.advanced.6a.success").feedbackArgs(output.toString()).output(" Your query was: " + query).build()); } else if((output.toString().contains("dave") && output.toString().contains("passW0rD")) && !usedUnion) { - return trackProgress(failed().output("To succesfully complete this Assignement you have to use a UNION").build()); + return trackProgress(failed().output("To successfully complete this Assignment you have to use a UNION" + "
Your query was: " + query).build()); } else { - return trackProgress(failed().output(output.toString()).build()); + return trackProgress(failed().output(output.toString() + "
Your query was: " + query).build()); } } else { - return trackProgress(failed().feedback("sql-injection.advanced.6a.no.results").build()); - + return trackProgress(failed().feedback("sql-injection.advanced.6a.no.results").output(" Your query was: " + query).build()); } } catch (SQLException sqle) { - return trackProgress(failed().output(sqle.getMessage()).build()); + return trackProgress(failed().output(sqle.getMessage() + "
Your query was: " + query).build()); } } catch (Exception e) { e.printStackTrace(); - return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build()); + return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage() + "
Your query was: " + query).build()); } } } \ No newline at end of file diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson5a.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson5a.java index a8fbaa0e4..a588ce806 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson5a.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson5a.java @@ -55,10 +55,11 @@ public class SqlInjectionLesson5a extends AssignmentEndpoint { } protected AttackResult injectableQuery(String accountName) { + String query = ""; try { Connection connection = DatabaseUtilities.getConnection(getWebSession()); System.out.println(accountName); - String query = "SELECT * FROM user_data WHERE first_name = 'John' and last_name = '" + accountName + "'"; + query = "SELECT * FROM user_data WHERE first_name = 'John' and last_name = '" + accountName + "'"; try { Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); @@ -73,20 +74,20 @@ public class SqlInjectionLesson5a extends AssignmentEndpoint { // If they get back more than one user they succeeded if (results.getRow() >= 6) { - return trackProgress(success().feedback("sql-injection.5a.success").feedbackArgs(output.toString()).build()); + return trackProgress(success().feedback("sql-injection.5a.success").output("Your query was: " + query).feedbackArgs(output.toString()).build()); } else { - return trackProgress(failed().output(output.toString()).build()); + return trackProgress(failed().output(output.toString() + "
Your query was: " + query).build()); } } else { - return trackProgress(failed().feedback("sql-injection.5a.no.results").build()); + return trackProgress(failed().feedback("sql-injection.5a.no.results").output("Your query was: " + query).build()); } } catch (SQLException sqle) { - return trackProgress(failed().output(sqle.getMessage()).build()); + return trackProgress(failed().output(sqle.getMessage() + "
Your query was: " + query).build()); } } catch (Exception e) { - return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build()); + return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage() + "
Your query was: " + query).build()); } } diff --git a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson5b.java b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson5b.java index b24316510..320554a10 100644 --- a/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson5b.java +++ b/webgoat-lessons/sql-injection/src/main/java/org/owasp/webgoat/plugin/introduction/SqlInjectionLesson5b.java @@ -57,22 +57,24 @@ public class SqlInjectionLesson5b extends AssignmentEndpoint { return injectableQuery(login_count, userid); } + protected AttackResult injectableQuery(String login_count, String accountName) { + String queryString = "SELECT * From user_data WHERE Login_Count = ? and userid= " + accountName; try { Connection connection = DatabaseUtilities.getConnection(getWebSession()); - PreparedStatement query = connection.prepareStatement("SELECT * From user_data WHERE Login_Count = ? and userid= " + accountName, ResultSet.TYPE_SCROLL_INSENSITIVE, + PreparedStatement query = connection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); int count = 0; try { count = Integer.parseInt(login_count); } catch(Exception e) { - return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build()); + return trackProgress(failed().output("Could not parse: " + login_count + " to a number" + + "
Your query was: " + queryString.replace("?", login_count)).build()); } query.setInt(1, count); //String query = "SELECT * FROM user_data WHERE Login_Count = " + login_count + " and userid = " + accountName, ; - System.err.println("Querry: " + query); try { Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); @@ -87,23 +89,22 @@ public class SqlInjectionLesson5b extends AssignmentEndpoint { // If they get back more than one user they succeeded if (results.getRow() >= 6) { - return trackProgress(success().feedback("sql-injection.5b.success").feedbackArgs(output.toString()).build()); + return trackProgress(success().feedback("sql-injection.5b.success").output("Your query was: " + queryString.replace("?", login_count)).feedbackArgs(output.toString()).build()); } else { - return trackProgress(failed().output(output.toString()).build()); + return trackProgress(failed().output(output.toString() + "
Your query was: " + queryString.replace("?", login_count)).build()); } } else { - return trackProgress(failed().feedback("sql-injection.5b.no.results").build()); + return trackProgress(failed().feedback("sql-injection.5b.no.results").output("Your query was: " + queryString.replace("?", login_count)).build()); // output.append(getLabelManager().get("NoResultsMatched")); } } catch (SQLException sqle) { - return trackProgress(failed().output(sqle.getMessage()).build()); + return trackProgress(failed().output(sqle.getMessage() + "
Your query was: " + queryString.replace("?", login_count)).build()); } } catch (Exception e) { - e.printStackTrace(); - return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build()); + return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage() + "
Your query was: " + queryString.replace("?", login_count)).build()); } } } \ No newline at end of file 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 d589c03f5..22f49d679 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/html/SqlInjection.html +++ b/webgoat-lessons/sql-injection/src/main/resources/html/SqlInjection.html @@ -196,11 +196,11 @@ - + - + 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 9f5d1045d..34fdec207 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties +++ b/webgoat-lessons/sql-injection/src/main/resources/i18n/WebGoatLabels.properties @@ -30,7 +30,7 @@ sql-injection.5b.success=You have succeed: {0}No results matched. Try Again. SqlStringInjectionHint5b1=Try to check which of the input fields is susceptible to an injection attack. -SqlStringInjectionHint5b2=Insert 0 or 1 = 1 into the first input field. The Output should tell you if this field is injectable. +SqlStringInjectionHint5b2=Insert: 0 or 1 = 1 into the first input field. The Output should tell you if this field is injectable. SqlStringInjectionHint5b3=The first Input field is not susceptible to sql injection. SqlStringInjectionHint5b4=You don't need to insert any quotations into your injection-string. @@ -39,9 +39,11 @@ sql-injection.6a.no.results=No results matched. sql-injection.advanced.6a.success=You have succeed: {0} sql-injection.advanced.6a.no.results=No results matched. Try Again. -SqlStringInjectionHint-advanced-6a-1=Try Appending a new SQL Statement to the Query. -SqlStringInjectionHint-advanced-6a-2=The new SQL Statement can be really simple like: SELECT ... FROM ... -SqlStringInjectionHint-advanced-6a-3=Your new SQL Query should start, with a " ; " and end with " -- " +SqlStringInjectionHint-advanced-6a-1=Remember, that when using a Union, Each SELECT statement within UNION must have the same number of columns. +SqlStringInjectionHint-advanced-6a-2=The Datatype of a column in the first SELECT statement must have a similar datatype to that in the second SELECT statement. +SqlStringInjectionHint-advanced-6a-3=Your new SQL Query must end with a comment. eg: -- +SqlStringInjectionHint-advanced-6a-4=If a column needs a String you could substitute something like 'a String' for it. For an integer you could substitute a 1. +SqlStringInjectionHint-advanced-6a-5=Try something like: Smith' UNION SELECT userid,user_name, password, 'a', 'b', 'c', 1 from user_system_data -- sql-injection.6b.success=You have succeed: {0} sql-injection.6b.no.results=No results matched. Try Again. diff --git a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6a.adoc b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6a.adoc index 8256ad1ff..4380b1150 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6a.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_content6a.adoc @@ -1,8 +1,21 @@ == Try It! Pulling data from other tables -Lets try to exploit the fact that you can use a union to get the contents of another table. +The input field below is used to get data from a user by their last name. + +The table is called 'user_data': -One of the tables in the WebGoat database is: +------------------------------------------------------- +CREATE TABLE user_data (userid int not null, + first_name varchar(20), + last_name varchar(20), + cc_number varchar(30), + cc_type varchar(10), + cookie varchar(20), + login_count int); +------------------------------------------------------- + +Through experimentation you found that this field is susceptible to SQL Injection. +Now you want to use that knowledge to get the contents of another table. + +The table you want to pull data from is: ------------------------------------------------------- CREATE TABLE user_system_data (userid int not null primary key, diff --git a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_order_by.adoc b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_order_by.adoc index d4806d1ed..6e8ff54e0 100644 --- a/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_order_by.adoc +++ b/webgoat-lessons/sql-injection/src/main/resources/lessonPlans/en/SqlInjection_order_by.adoc @@ -2,6 +2,4 @@ In this assignment try to perform an SQL injection through the ORDER BY field. Try to find the ip address of the `webgoat-prd` server, guessing the complete ip address might take too long so we give you the last part: `xxx.130.219.202` -Tip: To complete this assignment a tool such as OWASP ZAP is required. - Note: The submit field of this assignment is *NOT* vulnerable for an SQL injection. \ No newline at end of file
Login_Count:
User_Id: