Reworked all the SQL statements to be uppercase
This commit is contained in:
parent
9fdbbf69d6
commit
a0933d83d5
@ -116,7 +116,7 @@
|
|||||||
<input id="preview-input" type="text" name="username" val=""/>
|
<input id="preview-input" type="text" name="username" val=""/>
|
||||||
<div class="listingblock">
|
<div class="listingblock">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<pre>"SELECT * FROM users WHERE name = '<span id="input-preview" style="font-weight: bold;"></span>'";</pre>
|
<pre>"SELECT * FROM USERS WHERE NAME = '<span id="input-preview" style="font-weight: bold;"></span>'";</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@ -151,7 +151,7 @@
|
|||||||
enctype="application/json;charset=UTF-8">
|
enctype="application/json;charset=UTF-8">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>SELECT * FROM users_data FIRST_NAME = 'John' and Last_NAME = '</td>
|
<td>SELECT * FROM USER_DATA WHERE FIRST_NAME = 'John' and LAST_NAME = '</td>
|
||||||
<td><select name="account">
|
<td><select name="account">
|
||||||
<option>Smith</option>
|
<option>Smith</option>
|
||||||
<option>'Smith</option>
|
<option>'Smith</option>
|
||||||
|
@ -5,7 +5,7 @@ public static String loadAccount() {
|
|||||||
// Parser returns only valid string data
|
// Parser returns only valid string data
|
||||||
String accountID = getParser().getStringParameter(ACCT_ID, "");
|
String accountID = getParser().getStringParameter(ACCT_ID, "");
|
||||||
String data = null;
|
String data = null;
|
||||||
String query = "SELECT first_name, last_name, acct_id, balance FROM user_data WHERE acct_id = ?";
|
String query = "SELECT FIRST_NAME, LAST_NAME, ACCT_ID, BALANCE FROM USER_DATA WHERE ACCT_ID = ?";
|
||||||
try (Connection connection = null;
|
try (Connection connection = null;
|
||||||
PreparedStatement statement = connection.prepareStatement(query)) {
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
statement.setString(1, accountID);
|
statement.setString(1, accountID);
|
||||||
|
@ -7,7 +7,7 @@ public static bool isUsernameValid(string username) {
|
|||||||
|
|
||||||
// SqlConnection conn is set and opened elsewhere for brevity.
|
// SqlConnection conn is set and opened elsewhere for brevity.
|
||||||
try {
|
try {
|
||||||
string selectString = “SELECT * FROM user_table WHERE username = @userID”;
|
string selectString = "SELECT * FROM USER_TABLE WHERE USERNAME = @userID";
|
||||||
SqlCommand cmd = new SqlCommand( selectString, conn );
|
SqlCommand cmd = new SqlCommand( selectString, conn );
|
||||||
if ( isUsernameValid( uid ) ) {
|
if ( isUsernameValid( uid ) ) {
|
||||||
cmd.Parameters.Add( "@userID", SqlDbType.VarChar, 16 ).Value = uid;
|
cmd.Parameters.Add( "@userID", SqlDbType.VarChar, 16 ).Value = uid;
|
||||||
|
@ -34,7 +34,7 @@ This means an `orderExpression` can be a `selectExpression` which can be a funct
|
|||||||
a `case` statement we might be able to ask the database some questions, like:
|
a `case` statement we might be able to ask the database some questions, like:
|
||||||
|
|
||||||
----
|
----
|
||||||
select * from users order by (case when (true) then lastname else firstname)
|
SELECT * FROM USERS ORDER BY (CASE WHEN (TRUE) THEN LASTNAME ELSE FIRSTNAME)
|
||||||
----
|
----
|
||||||
|
|
||||||
So we can substitute any kind of boolean operation in the `when(....)` part. The statement will just work because
|
So we can substitute any kind of boolean operation in the `when(....)` part. The statement will just work because
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/* */ are inline comments
|
/* */ are inline comments
|
||||||
-- , # are line comments
|
-- , # are line comments
|
||||||
|
|
||||||
Example: Select * from users where name = 'admin' --and pass = 'pass'
|
Example: SELECT * FROM USERS WHERE NAME = 'admin' --AND pass = 'pass'
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ Example: Select * from users where name = 'admin' --and pass = 'pass'
|
|||||||
----
|
----
|
||||||
; allows query chaining
|
; allows query chaining
|
||||||
|
|
||||||
Example: Select * from users; drop table users;
|
Example: SELECT * FROM USERS; DROP TABLE USERS;
|
||||||
----
|
----
|
||||||
|
|
||||||
[source]
|
[source]
|
||||||
@ -21,7 +21,7 @@ Example: Select * from users; drop table users;
|
|||||||
',+,|| allows string concatenation
|
',+,|| allows string concatenation
|
||||||
Char() strings without quotes
|
Char() strings without quotes
|
||||||
|
|
||||||
Example: Select * from users where name = '+char(27) or 1=1
|
Example: SELECT * FROM USERS WHERE NAME = '+char(27) OR 1=1
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ of the first column in the second (third, fourth, ...) SELECT Statement. The Sam
|
|||||||
|
|
||||||
[source]
|
[source]
|
||||||
------
|
------
|
||||||
SELECT First_Name from user_system_data UNION SELECT login_count FROM user_data;
|
SELECT FIRST_NAME FROM USER_SYSTEM_DATA UNION SELECT LOGIN_COUNT FROM USER_DATA;
|
||||||
------
|
------
|
||||||
|
|
||||||
The UNION ALL Syntax also allows duplicate Values.
|
The UNION ALL Syntax also allows duplicate Values.
|
||||||
@ -50,7 +50,7 @@ The Join operator is used to combine rows from two ore more tables, based on a r
|
|||||||
|
|
||||||
[source]
|
[source]
|
||||||
-----
|
-----
|
||||||
SELECT * FROM user_data INNER JOIN user_data_tan ON user_data.userid=user_data_tan.userid;
|
SELECT * FROM USER_DATA INNER JOIN USER_DATA_TAN ON USER_DATA.USERID=USER_DATA_TAN.USERID;
|
||||||
-----
|
-----
|
||||||
|
|
||||||
For more detailed information about JOINS visit: https://www.w3schools.com/sql/sql_join.asp
|
For more detailed information about JOINS visit: https://www.w3schools.com/sql/sql_join.asp
|
@ -23,24 +23,24 @@ suppose we have the following url: `https://my-shop.com?article=4`
|
|||||||
On the server side this query will be translated as follows:
|
On the server side this query will be translated as follows:
|
||||||
|
|
||||||
----
|
----
|
||||||
SELECT * from articles where article_id = 4
|
SELECT * FROM ARTICLES WHERE ARTICLE_ID = 4
|
||||||
----
|
----
|
||||||
|
|
||||||
When we want to exploit this we change the url into: `https://my-shop.com?article=4 AND 1=1`
|
When we want to exploit this we change the url into: `https://shop.example.com?article=4 AND 1=1`
|
||||||
This will be translated to:
|
This will be translated to:
|
||||||
|
|
||||||
----
|
----
|
||||||
SELECT * from articles where article_id = 4 AND 1 = 1
|
SELECT * FROM ARTICLES WHERE ARTICLE_ID = 4 and 1 = 1
|
||||||
----
|
----
|
||||||
|
|
||||||
If the browser will return the same page as it used to when using `https://my-shop.com?article=4` you know the
|
If the browser will return the same page as it used to when using `https://shop.example.com?article=4` you know the
|
||||||
website is vulnerable for a blind SQL injection.
|
website is vulnerable for a blind SQL injection.
|
||||||
If the browser responds with a page not found or something else you know a blind SQL injection might not work.
|
If the browser responds with a page not found or something else you know a blind SQL injection might not work.
|
||||||
You can now change the SQL query and test for example: `https://my-shop.com?article=4 AND 1=2` which will not return
|
You can now change the SQL query and test for example: `https://shop.example.com?article=4 AND 1=2` which will not return
|
||||||
anything because the query returns false.
|
anything because the query returns false.
|
||||||
|
|
||||||
So but how do we actually take advantage of this? Above we only asked the database for trivial question but you can
|
So but how do we actually take advantage of this? Above we only asked the database for trivial question but you can
|
||||||
for example also use the following url: `https://my-shop.com?article=4 AND substring(database_version(),1,1) = 2`
|
for example also use the following url: `https://shop.example.com?article=4 AND substring(database_version(),1,1) = 2`
|
||||||
|
|
||||||
Most of the time you start by finding which type of database is used, based on the type of database you can find
|
Most of the time you start by finding which type of database is used, based on the type of database you can find
|
||||||
the system tables of the database you can enumerate all the tables present in the database. With this information
|
the system tables of the database you can enumerate all the tables present in the database. With this information
|
||||||
|
@ -4,16 +4,16 @@ These are the best defense against SQL injection. They either do not have data
|
|||||||
|
|
||||||
=== Static Queries
|
=== Static Queries
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
select * from products;
|
SELECT * FROM PRODUCTS;
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
select * from users where user = "'" + session.getAttribute("UserID") + "'";
|
SELECT * FROM USERS WHERE USER = "'" + session.getAttribute("UserID") + "'";
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
=== Parameterized Queries
|
=== Parameterized Queries
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
String query = "SELECT * FROM users WHERE last_name = ?";
|
String query = "SELECT * FROM USERS WHERE LAST_NAME = ?";
|
||||||
PreparedStatement statement = connection.prepareStatement(query);
|
PreparedStatement statement = connection.prepareStatement(query);
|
||||||
statement.setString(1, accountName);
|
statement.setString(1, accountName);
|
||||||
ResultSet results = statement.executeQuery();
|
ResultSet results = statement.executeQuery();
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
CREATE PROCEDURE ListCustomers(@Country nvarchar(30))
|
CREATE PROCEDURE ListCustomers(@Country nvarchar(30))
|
||||||
AS
|
AS
|
||||||
SELECT City, COUNT(*)
|
SELECT CITY, COUNT(*)
|
||||||
FROM Customers
|
FROM CUSTOMERS
|
||||||
WHERE Country LIKE @Country GROUP BY City
|
WHERE COUNTRY LIKE @Country GROUP BY CITY
|
||||||
|
|
||||||
|
|
||||||
EXEC ListCustomers ‘USA’
|
EXEC ListCustomers ‘USA’
|
||||||
@ -17,7 +17,7 @@ EXEC ListCustomers ‘USA’
|
|||||||
CREATE PROEDURE getUser(@lastName nvarchar(25))
|
CREATE PROEDURE getUser(@lastName nvarchar(25))
|
||||||
AS
|
AS
|
||||||
declare @sql nvarchar(255)
|
declare @sql nvarchar(255)
|
||||||
set @sql = 'select * from users where
|
set @sql = 'SELECT * FROM USERS WHERE
|
||||||
LastName = + @LastName + '
|
LASTNAME = + @LastName + '
|
||||||
exec sp_executesql @sql
|
exec sp_executesql @sql
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
@ -12,8 +12,8 @@ RecordSet rs = null;
|
|||||||
try {
|
try {
|
||||||
pUserName = request.getParameter("UserName");
|
pUserName = request.getParameter("UserName");
|
||||||
if ( isUsernameValid (pUsername) ) {
|
if ( isUsernameValid (pUsername) ) {
|
||||||
ps = conn.prepareStatement("SELECT * FROM user_table
|
ps = conn.prepareStatement("SELECT * FROM USER_TABLE
|
||||||
WHERE username = ? ");
|
WHERE USERNAME = ? ");
|
||||||
ps.setString(1, pUsername);
|
ps.setString(1, pUsername);
|
||||||
rs = ps.execute();
|
rs = ps.execute();
|
||||||
if ( rs.next() ) {
|
if ( rs.next() ) {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
The query in the code builds a dynamic query as seen in the previous example. The query is build by concatenating strings making it susceptible to String SQL injection:
|
The query in the code builds a dynamic query as seen in the previous example. The query is build by concatenating strings making it susceptible to String SQL injection:
|
||||||
|
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
"select * from user_data where FIRST_NAME = 'John' and LAST_NAME = '" + lastName + "'";
|
"SELECT * FROM USER_DATA WHERE FIRST_NAME = 'John' AND LAST_NAME = '" + lastName + "'";
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
|
|
||||||
Using the form below try to retrieve all the users from the users table. You should not need to know any specific user name to get the complete list.
|
Using the form below try to retrieve all the users from the users table. You should not need to know any specific user name to get the complete list.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
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:
|
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 user_data where Login_Count = " + Login_Count + " and USERID = " + User_ID;
|
"SELECT * FROM USER_DATA WHERE LOGIN_COUNT = " + Login_Count + " AND USERID = " + User_ID;
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
||||||
Using the two Input Fields below, try to retrieve all the data from the users table.
|
Using the two Input Fields below, try to retrieve all the data from the users table.
|
||||||
|
@ -12,9 +12,9 @@ If an attacker uses SQL injection of the DML type to manipulate your database, h
|
|||||||
* DELETE - Delete all records from a database table
|
* DELETE - Delete all records from a database table
|
||||||
* Example:
|
* Example:
|
||||||
** Retrieve data:
|
** Retrieve data:
|
||||||
** SELECT phone +
|
** SELECT PHONE +
|
||||||
FROM employees +
|
FROM EMPLOYEES +
|
||||||
WHERE userid = 96134;
|
WHERE USERID = 96134;
|
||||||
** This statement delivers the phone number of the employee with the userid 96134.
|
** This statement delivers the phone number of the employee with the userid 96134.
|
||||||
|
|
||||||
=== It is your turn!
|
=== It is your turn!
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
==== Here are some examples of what a hacker could supply to the input field to perform actions on the database that go further than just reading the data of a single user:
|
==== Here are some examples of what a hacker could supply to the input field to perform actions on the database that go further than just reading the data of a single user:
|
||||||
|
|
||||||
* `+Smith’ OR ‘1’ = ‘1+` +
|
* `+Smith’ OR ‘1’ = ‘1+` +
|
||||||
results in `+"SELECT * FROM users WHERE name = 'Smith' OR TRUE;+` and that way will return all entries from the users table
|
results in `+"SELECT * FROM USERS WHERE NAME = 'Smith' OR TRUE;+` and that way will return all entries from the users table
|
||||||
* `+Smith’ OR 1 = 1; --+` +
|
* `+Smith’ OR 1 = 1; --+` +
|
||||||
results in `+"SELECT * FROM users WHERE name = 'Smith' OR TRUE;--';+` and that way will return all entries from the users table
|
results in `+"SELECT * FROM USERS WHERE NAME = 'Smith' OR TRUE;--';+` and that way will return all entries from the users table
|
||||||
* `+Smith’; DROP TABLE USERS; truncate audit_log; --+` +
|
* `+Smith’; DROP TABLE USERS; TRUNCATE AUDIT_LOG; --+` +
|
||||||
chains multiple SQL-Commands and deletes the USERS table as well as entries from the audit_log
|
chains multiple SQL-Commands and deletes the USERS table as well as entries from the audit_log
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
== Compromising Integrity with Query chaining
|
== 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 SQL *query chaining*.
|
After compromising the confidentiality of data in the previous lesson, this time we are gonna compromise the *integrity*
|
||||||
|
of data by using SQL *query chaining*.
|
||||||
|
|
||||||
The integrity of any data can be compromised, if an attacker per example changes information that he should not even be able to access.
|
The integrity of any data can be compromised, if an attacker per example changes information that he should not even be
|
||||||
|
able to access.
|
||||||
|
|
||||||
=== What is SQL query chaining?
|
=== 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.
|
Query chaining is exactly what it sounds like. When query chaining, you try to append one or more queries to the end of
|
||||||
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 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.
|
||||||
|
|
||||||
=== It is your turn!
|
=== It is your turn!
|
||||||
You just found out that Tobi and Bob both seem to earn more money than you!
|
You just found out that Tobi and Bob both seem to earn more money than you!
|
||||||
|
Loading…
x
Reference in New Issue
Block a user