Added an assignment for compromising availability to the sql injections (introduction).
WIP
This commit is contained in:
parent
4e6c721545
commit
6fe7582dfb
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -86,7 +86,8 @@
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/SqlInjection/attack9"
|
||||
enctype="application/json;charset=UTF-8">
|
||||
enctype="application/json;charset=UTF-8"
|
||||
autocomplete="off">
|
||||
<table>
|
||||
<tr>
|
||||
<td><label>Employee Name:</label></td>
|
||||
@ -109,19 +110,20 @@
|
||||
<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_content8.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">
|
||||
action="/WebGoat/SqlInjection/attack10"
|
||||
enctype="application/json;charset=UTF-8"
|
||||
autocomplete="off">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Account Name:</td>
|
||||
<td><input name="account" value="" type="TEXT"/></td>
|
||||
<td><input
|
||||
name="Get Account Info" value="Get Account Info" type="SUBMIT"/></td>
|
||||
<td><label>Action contains:</label></td>
|
||||
<td><input name="action" value="" type="TEXT"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="SUBMIT">Search logs</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
|
@ -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.
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user