Added an assignment for compromising availability to the sql injections (introduction).

WIP
This commit is contained in:
Benedikt - Desktop 2018-11-05 19:39:22 +01:00 committed by Nanne Baars
parent 4e6c721545
commit 6fe7582dfb
7 changed files with 136 additions and 39 deletions

View File

@ -988,15 +988,19 @@ public class CreateDB {
private void createEmployeesTable(Connection connection) throws SQLException { private void createEmployeesTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement(); Statement statement = connection.createStatement();
// Drop employees table // Drop employees and access_log tables
try { try {
String dropTable = "DROP TABLE employees"; statement.executeUpdate("DROP TABLE employees");
statement.executeUpdate(dropTable);
} catch (SQLException e) { } catch (SQLException e) {
System.out.println("Info - Could not drop employees table"); 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 { try {
String createTableStatement = "CREATE TABLE employees (" String createTableStatement = "CREATE TABLE employees ("
+ "userid varchar(6) not null primary key," + "userid varchar(6) not null primary key,"
@ -1022,6 +1026,18 @@ public class CreateDB {
statement.executeUpdate(insertData3); statement.executeUpdate(insertData3);
statement.executeUpdate(insertData4); statement.executeUpdate(insertData4);
statement.executeUpdate(insertData5); 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());
}
} }
/** /**

View File

@ -19,12 +19,60 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST) @RequestMapping(method = RequestMethod.POST)
public public
@ResponseBody @ResponseBody
AttackResult completed(@RequestParam String name, @RequestParam String auth_tan) { AttackResult completed(@RequestParam String action) {
return injectableQueryConfidentiality(name, auth_tan); return injectableQueryAvailability(action);
} }
protected AttackResult injectableQueryConfidentiality(String name, String auth_tan) { protected AttackResult injectableQueryAvailability(String action) {
return trackProgress(failed().build()); 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;
} }
} }

View File

@ -10,6 +10,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import java.sql.*; import java.sql.*;
@ -31,6 +33,7 @@ public class SqlInjectionLesson8 extends AssignmentEndpoint {
try { try {
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
log(connection, query);
ResultSet results = statement.executeQuery(query); ResultSet results = statement.executeQuery(query);
if ((results != null) && (results.first())) { if ((results != null) && (results.first())) {
@ -88,5 +91,19 @@ public class SqlInjectionLesson8 extends AssignmentEndpoint {
return (t.toString()); 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());
}
}
} }

View File

@ -31,7 +31,8 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint {
try { try {
String query = "SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'"; 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); ResultSet results = statement.executeQuery(query);
results.first(); results.first();
@ -40,29 +41,10 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint {
output.append(SqlInjectionLesson8.generateTable(results, resultsMetaData)); output.append(SqlInjectionLesson8.generateTable(results, resultsMetaData));
} catch (SQLException e) { } catch (SQLException e) {
System.err.println(e.getMessage()); System.err.println(e.getMessage());
return trackProgress(failed().output(e.getMessage()).build()); return checkSalaryRanking(connection, output);
} }
try { return checkSalaryRanking(connection, output);
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) { } catch (Exception e) {
System.err.println(e.getMessage()); 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());
}
}
} }

View File

@ -86,7 +86,8 @@
<form class="attack-form" accept-charset="UNKNOWN" <form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form" method="POST" name="form"
action="/WebGoat/SqlInjection/attack9" action="/WebGoat/SqlInjection/attack9"
enctype="application/json;charset=UTF-8"> enctype="application/json;charset=UTF-8"
autocomplete="off">
<table> <table>
<tr> <tr>
<td><label>Employee Name:</label></td> <td><label>Employee Name:</label></td>
@ -109,19 +110,20 @@
<div class="lesson-page-wrapper"> <div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="doc:SqlInjection_introduction_content10.adoc"></div> <div class="adoc-content" th:replace="doc:SqlInjection_introduction_content10.adoc"></div>
<div class="adoc-content" th:replace="doc:SqlInjection_introduction_content8.adoc"></div>
<div class="attack-container"> <div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div> <div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" <form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form" method="POST" name="form"
action="/WebGoat/SqlInjection/attack5a" action="/WebGoat/SqlInjection/attack10"
enctype="application/json;charset=UTF-8"> enctype="application/json;charset=UTF-8"
autocomplete="off">
<table> <table>
<tr> <tr>
<td>Account Name:</td> <td><label>Action contains:</label></td>
<td><input name="account" value="" type="TEXT"/></td> <td><input name="action" value="" type="TEXT"/></td>
<td><input </tr>
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td> <tr>
<td><button type="SUBMIT">Search logs</button></td>
</tr> </tr>
</table> </table>
</form> </form>

View File

@ -52,3 +52,5 @@ SqlStringInjectionHint9-2=Use the ; metacharacter to do so.
SqlStringInjectionHint9-3=Make use of DML to change your salary. SqlStringInjectionHint9-3=Make use of DML to change your salary.
SqlStringInjectionHint9-4=Make sure that the resulting query is syntactically correct. SqlStringInjectionHint9-4=Make sure that the resulting query is syntactically correct.
SqlStringInjectionHint9-5=How about something like '; UPDATE employees.... 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.

View File

@ -1 +1,8 @@
Availiability == 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.