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=""/>
|
||||
<div class="listingblock">
|
||||
<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>
|
||||
<script>
|
||||
@ -151,7 +151,7 @@
|
||||
enctype="application/json;charset=UTF-8">
|
||||
<table>
|
||||
<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">
|
||||
<option>Smith</option>
|
||||
<option>'Smith</option>
|
||||
|
@ -5,7 +5,7 @@ public static String loadAccount() {
|
||||
// Parser returns only valid string data
|
||||
String accountID = getParser().getStringParameter(ACCT_ID, "");
|
||||
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;
|
||||
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||
statement.setString(1, accountID);
|
||||
|
@ -7,7 +7,7 @@ public static bool isUsernameValid(string username) {
|
||||
|
||||
// SqlConnection conn is set and opened elsewhere for brevity.
|
||||
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 );
|
||||
if ( isUsernameValid( 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:
|
||||
|
||||
----
|
||||
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
|
||||
|
@ -5,7 +5,7 @@
|
||||
/* */ are inline 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
|
||||
|
||||
Example: Select * from users; drop table users;
|
||||
Example: SELECT * FROM USERS; DROP TABLE USERS;
|
||||
----
|
||||
|
||||
[source]
|
||||
@ -21,7 +21,7 @@ Example: Select * from users; drop table users;
|
||||
',+,|| allows string concatenation
|
||||
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]
|
||||
------
|
||||
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.
|
||||
@ -50,7 +50,7 @@ The Join operator is used to combine rows from two ore more tables, based on a r
|
||||
|
||||
[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
|
@ -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:
|
||||
|
||||
----
|
||||
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:
|
||||
|
||||
----
|
||||
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.
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
-------------------------------------------------------
|
||||
select * from products;
|
||||
SELECT * FROM PRODUCTS;
|
||||
-------------------------------------------------------
|
||||
|
||||
-------------------------------------------------------
|
||||
select * from users where user = "'" + session.getAttribute("UserID") + "'";
|
||||
SELECT * FROM USERS WHERE USER = "'" + session.getAttribute("UserID") + "'";
|
||||
-------------------------------------------------------
|
||||
|
||||
=== Parameterized Queries
|
||||
-------------------------------------------------------
|
||||
String query = "SELECT * FROM users WHERE last_name = ?";
|
||||
String query = "SELECT * FROM USERS WHERE LAST_NAME = ?";
|
||||
PreparedStatement statement = connection.prepareStatement(query);
|
||||
statement.setString(1, accountName);
|
||||
ResultSet results = statement.executeQuery();
|
||||
|
@ -4,9 +4,9 @@
|
||||
-------------------------------------------------------
|
||||
CREATE PROCEDURE ListCustomers(@Country nvarchar(30))
|
||||
AS
|
||||
SELECT City, COUNT(*)
|
||||
FROM Customers
|
||||
WHERE Country LIKE @Country GROUP BY City
|
||||
SELECT CITY, COUNT(*)
|
||||
FROM CUSTOMERS
|
||||
WHERE COUNTRY LIKE @Country GROUP BY CITY
|
||||
|
||||
|
||||
EXEC ListCustomers ‘USA’
|
||||
@ -17,7 +17,7 @@ EXEC ListCustomers ‘USA’
|
||||
CREATE PROEDURE getUser(@lastName nvarchar(25))
|
||||
AS
|
||||
declare @sql nvarchar(255)
|
||||
set @sql = 'select * from users where
|
||||
LastName = + @LastName + '
|
||||
set @sql = 'SELECT * FROM USERS WHERE
|
||||
LASTNAME = + @LastName + '
|
||||
exec sp_executesql @sql
|
||||
-------------------------------------------------------
|
||||
|
@ -12,8 +12,8 @@ RecordSet rs = null;
|
||||
try {
|
||||
pUserName = request.getParameter("UserName");
|
||||
if ( isUsernameValid (pUsername) ) {
|
||||
ps = conn.prepareStatement("SELECT * FROM user_table
|
||||
WHERE username = ? ");
|
||||
ps = conn.prepareStatement("SELECT * FROM USER_TABLE
|
||||
WHERE USERNAME = ? ");
|
||||
ps.setString(1, pUsername);
|
||||
rs = ps.execute();
|
||||
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:
|
||||
|
||||
------------------------------------------------------------
|
||||
"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.
|
||||
|
@ -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:
|
||||
|
||||
--------------------------------------------------
|
||||
"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.
|
||||
|
@ -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
|
||||
* Example:
|
||||
** Retrieve data:
|
||||
** SELECT phone +
|
||||
FROM employees +
|
||||
WHERE userid = 96134;
|
||||
** SELECT PHONE +
|
||||
FROM EMPLOYEES +
|
||||
WHERE USERID = 96134;
|
||||
** This statement delivers the phone number of the employee with the userid 96134.
|
||||
|
||||
=== 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:
|
||||
|
||||
* `+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; --+` +
|
||||
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; --+` +
|
||||
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; --+` +
|
||||
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
|
||||
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?
|
||||
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.
|
||||
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.
|
||||
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. 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!
|
||||
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