Added my improved assignments

This commit is contained in:
Tobias Melzer 2018-11-12 20:16:16 +01:00 committed by Nanne Baars
parent 551f87dbd9
commit 718b113f86
11 changed files with 364 additions and 19 deletions

View File

@ -26,6 +26,7 @@ import static org.springframework.web.bind.annotation.RequestMethod.POST;
@AssignmentPath("SqlInjection/challenge")
@AssignmentHints(value = {"SqlInjectionChallenge1", "SqlInjectionChallenge2", "SqlInjectionChallenge3"})
@Slf4j
@AssignmentHints(value ={"SqlInjectionChallengeHint1", "SqlInjectionChallengeHint2", "SqlInjectionChallengeHint3", "SqlInjectionChallengeHint4"})
public class SqlInjectionChallenge extends AssignmentEndpoint {
private static final String PASSWORD_TOM = "thisisasecretfortomonly";

View File

@ -1,11 +1,10 @@
package org.owasp.webgoat.plugin.advanced;
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.plugin.introduction.SqlInjectionLesson8;
import org.owasp.webgoat.plugin.introduction.SqlInjectionLesson5a;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -47,7 +46,7 @@ import java.sql.*;
* @created October 28, 2003
*/
@AssignmentPath("/SqlInjection/attack6a")
@AssignmentHints(value = {"SqlStringInjectionHint6", "SqlStringInjectionHint7", "SqlStringInjectionHint8"})
@AssignmentHints(value = {"SqlStringInjectionHint6a1", "SqlStringInjectionHint6a2", "SqlStringInjectionHint6a3", "SqlStringInjectionHint6a4"})
public class SqlInjectionLesson6a extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
@ -60,9 +59,13 @@ public class SqlInjectionLesson6a extends AssignmentEndpoint {
protected AttackResult injectableQuery(String accountName) {
try {
boolean usedUnion = true;
Connection connection = DatabaseUtilities.getConnection(getWebSession());
String query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'";
//Check if Union is used
if(!accountName.matches("(?i)(^[^-/*;)]*)(\\s*)UNION(.*$)")) {
usedUnion = false;
}
try {
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
@ -72,18 +75,19 @@ public class SqlInjectionLesson6a extends AssignmentEndpoint {
ResultSetMetaData resultsMetaData = results.getMetaData();
StringBuffer output = new StringBuffer();
output.append(SqlInjectionLesson8.generateTable(results));
if(! (query.toLowerCase().contains("union") || query.toLowerCase().contains("join")) )
output.append("There is also a way to retrieve the Data by using a UNION or JOIN. Can you figure out, how this is done?");
output.append(SqlInjectionLesson5a.writeTable(results, resultsMetaData));
if(! usedUnion)
output.append("To succesfully complete this Assignement you have to use a UNION");
results.last();
// If they get back more than one user they succeeded
if (results.getRow() >= 5) {
if (results.getRow() >= 5 && usedUnion) {
return trackProgress(success().feedback("sql-injection.6a.success").feedbackArgs(output.toString()).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());
} else {
return trackProgress(failed().output(output.toString()).build());
}
} else {
return trackProgress(failed().feedback("sql-injection.6a.no.results").build());
@ -96,4 +100,4 @@ public class SqlInjectionLesson6a extends AssignmentEndpoint {
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build());
}
}
}
}

View File

@ -0,0 +1,126 @@
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.io.IOException;
import java.sql.*;
/***************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 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 https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* For details, please see http://webgoat.github.io
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
@AssignmentPath("/SqlInjection/attack5a")
public class SqlInjectionLesson5a extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public
@ResponseBody
AttackResult completed(@RequestParam String account, @RequestParam String operator, @RequestParam String injection) {
return injectableQuery(account + " " + operator + " " + injection);
}
protected AttackResult injectableQuery(String accountName) {
try {
Connection connection = DatabaseUtilities.getConnection(getWebSession());
System.out.println(accountName);
String 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);
ResultSet results = statement.executeQuery(query);
if ((results != null) && (results.first())) {
ResultSetMetaData resultsMetaData = results.getMetaData();
StringBuffer output = new StringBuffer();
output.append(writeTable(results, resultsMetaData));
results.last();
// 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());
} else {
return trackProgress(failed().output(output.toString()).build());
}
} else {
return trackProgress(failed().feedback("sql-injection.5a.no.results").build());
}
} catch (SQLException sqle) {
return trackProgress(failed().output(sqle.getMessage()).build());
}
} catch (Exception e) {
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build());
}
}
public static String writeTable(ResultSet results, ResultSetMetaData resultsMetaData) throws IOException,
SQLException {
int numColumns = resultsMetaData.getColumnCount();
results.beforeFirst();
StringBuffer t = new StringBuffer();
t.append("<p>");
if (results.next()) {
for (int i = 1; i < (numColumns + 1); i++) {
t.append(resultsMetaData.getColumnName(i));
t.append(", ");
}
t.append("<br />");
results.beforeFirst();
while (results.next()) {
for (int i = 1; i < (numColumns + 1); i++) {
t.append(results.getString(i));
t.append(", ");
}
t.append("<br />");
}
} else {
t.append("Query Successful; however no data was returned from this query.");
}
t.append("</p>");
return (t.toString());
}
}

View File

@ -0,0 +1,109 @@
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 javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.sql.*;
/***************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 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 https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* For details, please see http://webgoat.github.io
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
@AssignmentPath("/SqlInjection/attack5b")
@AssignmentHints(value = {"SqlStringInjectionHint5b1", "SqlStringInjectionHint5b2", "SqlStringInjectionHint5b3", "SqlStringInjectionHint5b4"})
public class SqlInjectionLesson5b extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public
@ResponseBody
AttackResult completed(@RequestParam String userid, @RequestParam String login_count, HttpServletRequest request) throws IOException {
return injectableQuery(login_count, userid);
}
protected AttackResult injectableQuery(String login_count, String 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,
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());
}
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);
ResultSet results = query.executeQuery();
if ((results != null) && (results.first() == true)) {
ResultSetMetaData resultsMetaData = results.getMetaData();
StringBuffer output = new StringBuffer();
output.append(SqlInjectionLesson5a.writeTable(results, resultsMetaData));
results.last();
// 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());
} else {
return trackProgress(failed().output(output.toString()).build());
}
} else {
return trackProgress(failed().feedback("sql-injection.5b.no.results").build());
// output.append(getLabelManager().get("NoResultsMatched"));
}
} catch (SQLException sqle) {
return trackProgress(failed().output(sqle.getMessage()).build());
}
} catch (Exception e) {
e.printStackTrace();
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build());
}
}
}

View File

@ -33,8 +33,9 @@ public class SqlInjectionLesson12a extends AssignmentEndpoint {
@SneakyThrows
public AttackResult completed(@RequestParam String ip) {
Connection connection = DatabaseUtilities.getConnection(webSession);
PreparedStatement preparedStatement = connection.prepareStatement("select ip from servers where hostname = 'webgoat-prd' and ip = ?");
PreparedStatement preparedStatement = connection.prepareStatement("select ip from servers where ip = ? and hostname = ?");
preparedStatement.setString(1, ip);
preparedStatement.setString(2, "webgoat-prd");
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
return trackProgress(success().build());

View File

@ -52,6 +52,79 @@
<div class="adoc-content" th:replace="doc:SqlInjection_introduction_content7.adoc"></div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:SqlInjection_introduction_content11.adoc"></div>
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/attack5a"
enctype="application/json;charset=UTF-8">
<table>
<tr>
<td>SELECT * FROM users WHERE LOGIN_COUNT > 0 and FIRST_NAME = '</td>
<td><select name="account">
<option>Smith</option>
<option>'Smith</option>
<option>'</option>
<option>'Smith'</option>
</select></td>
<td>
<select name="operator">
<option>or not</option>
<option>and</option>
<option>and not</option>
</select>
</td>
<td>
<select name="injection">
<option>1 = 1</option>
<option>1 = 2</option>
<option>1' = '2</option>
<option>'1' = '1</option>
<option>'1' = '2</option>
<option>Last_Name = 'Smith</option>
</select>
</td>
<td><input
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
</tr>
</table>
</form>
<div class="attack-feedback"></div>
<div class="attack-output"></div>
</div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:SqlInjection_introduction_content12.adoc"></div>
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="/WebGoat/SqlInjection/attack5b"
enctype="application/json;charset=UTF-8">
<table>
<tr>
<td>Login_Count:</td>
<td><input name="login_count" value="" type="text"/></td>
</tr>
<tr>
<td>User_Id:</td>
<td><input name="userid" value="" type="TEXT"/></td>
</tr>
<tr>
<td></td>
<td><input
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
</tr>
</table>
</form>
<div class="attack-feedback"></div>
<div class="attack-output"></div>
</div>
</div>
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:SqlInjection_introduction_content8.adoc"></div>
<div class="attack-container">

View File

@ -12,9 +12,18 @@ SqlInjectionChallenge3=Use tooling to automate this attack
sql-injection.error=<span class='feedback-negative'>Sorry, this solution is not correct. Try again!</span>
NoResultsMatched=No results matched. Try Again.
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 " -- "
SqlInjectionChallengeHint1=The Table Name is randomized at each start of Webgoat, try to figure out the name first.
SqlInjectionChallengeHint2=Find the Field which is vulnerable to SQL Injection use that to change the password.
SqlInjectionChallengeHint3=Change the password through an Update Statement.
SqlInjectionChallengeHint4=The Vulnerable Field is the Username Field of the Register form.
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. Th 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.
SqlStringInjectionHint6a1=Try Appending stuff like ",1" to your query, to figure out how many columns there are.
SqlStringInjectionHint6a2=When using a UNION the number of columns, from both tables should match.
SqlStringInjectionHint6a3=The UNION should contain 7 columns.
SqlStringInjectionHint6a4=Try using these columns in your union: userid, user_name, password, cookie, cookie, cookie, userid.
SqlStringInjectionHint9=Try sorting and look at the request
SqlStringInjectionHint10=Intercept the request and try to specify a different order by
SqlStringInjectionHint10a1=First establish a connection, after that you can create a statement.

View File

@ -1,6 +1,8 @@
== Try It! Pulling data from other tables
Lets try to exploit the fact that you can append your own SQL Statement. One of the tables in the WebGoat database is:
Lets try to exploit the fact that you can use a union to get the contents of another table.
One of the tables in the WebGoat database is:
-------------------------------------------------------
CREATE TABLE user_system_data (userid int not null primary key,
@ -9,7 +11,5 @@ CREATE TABLE user_system_data (userid int not null primary key,
cookie varchar(30));
-------------------------------------------------------
*6.a)* Inject your own Query into the SQL Statement to retrieve all Data from the Table. +
*6.b)* When you have figured it out.... What is Dave's password?
*6.a)* Retrieve all data from the table by using a UNION (You have to use a union to complete this assignment.) +
*6.b)* When you have figured it out.... What is Dave's password?

View File

@ -0,0 +1,9 @@
== Try It! String SQL Injection
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 strings making it susceptible to String SQL injection:
------------------------------------------------------------
"select * from users where LOGIN_COUNT > 0 and FIRST_NAME = " + userName + "'";
------------------------------------------------------------
Using the form below try to retrieve all the users from the users table. You shouldn't need to know any specific user name to get the complete list.

View File

@ -0,0 +1,11 @@
== Try It! Numeric SQL Injection
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 two Input Fields below, try to retrieve all the date from the users table.
Warning: Only one of these fields is susceptible to SQL Injection. You need to find out which, to successfully retrieve all the data.

View File

@ -2,4 +2,6 @@ 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.