0% found this document useful (0 votes)
26 views35 pages

W12-Attacking Data Stores (Part II)

The document discusses SQL injection techniques and defenses, focusing on methods like bypassing filters, second-order SQL injection, and retrieving data through conditional responses and time delays. It emphasizes the importance of using parameterized queries and stored procedures as effective defenses against SQL injection attacks. Additionally, it highlights the use of tools like sqlmap for automating SQL injection exploitation and warns against illegal activities without permission.

Uploaded by

phantomsixth6
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views35 pages

W12-Attacking Data Stores (Part II)

The document discusses SQL injection techniques and defenses, focusing on methods like bypassing filters, second-order SQL injection, and retrieving data through conditional responses and time delays. It emphasizes the importance of using parameterized queries and stored procedures as effective defenses against SQL injection attacks. Additionally, it highlights the use of tools like sqlmap for automating SQL injection exploitation and warns against illegal activities without permission.

Uploaded by

phantomsixth6
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 35

Attacking Data Stores

(Part II)

ICT2214—Web Security
Where we are …

• Session management
• Authentication
• Access controls
• SQL injection  this week and last week
• Cross-site scripting (last week of the trimester)
Reminder -

Quiz 2 today
• Online - available on the from 9 am to 6 pm
• Open book test
• You will have one hour to complete the quiz.
• 20 questions, worth 1 mark each
• Quiz 2 is worth 5% of your overall grade for this module.

• Covers Weeks 6, 8, 9, & 10


• the questions at the end of the slides give you an idea of what will
be asked
Review of Week 11
• Web applications use SQL-based database systems
• SQL is vulnerable to attacks because it is an interpreted language
• Common techniques for string data:
• Bypassing login password - use double-dashes, single quotation marks, OR 1=1 –
• Create new rows in databases with the INSERT command
• Modify existing rows in databases with the UPDATE command
• SQL concatenator characters (varies by database), wildcard character %
• For numeric data
• Use simple or complex mathematical expressions (such as the ASCII command)
• Common SQL injection points
• INSERT and UPDATE commands, WHERE and ORDER BY clauses
• The UNION command can be used to to inject a second SELECT query and append its
results to those of the first
• Need to know the names of the table and columns, number of columns, type of
data in each column → usually interested in string data, so look for those
This week

More SQL injection techniques


- bypassing filters
- second-order SQL injection
- using SUBSTRING to retrieve data as numbers
- conditional responses and errors

Defending against SQL injection attacks

** Question – did you complete the Portswigger exercises?


Preventing SQL injection

Ineffective methods Effective methods

• Input validation, e.g., via whitelists or


blacklists—can easily be circumvented • Parameterized queries—also known as
prepared statements
• Escaping dangerous characters, such as
single quotation marks—may still lead to • Stored database procedures
second-order SQL injection

Next few slides explain Later slides explain why


why these don’t work these work 6
Bypassing filters

Avoiding blocked Circumventing simple


characters: validation: Using SQL comments:

• Use the CHAR function • If certain keywords are • If whitespaces are


and the concatenation blocked or removed, try blocked or removed, use
operator to construct the following (e.g., for the inline SQL comments to
strings, for example,'ma' SELECT keyword): simulate them:
can be written as
CHAR(109)+CHAR(97) SeLeCt SELECT/*foo*/username
• Blocked comment symbol %00SELECT ,password/*foo*/FROM/
Use ' OR 'a'='a SELSELECTECT *foo*/users
instead of ' OR 1=1 -- %53%45%4c%45%43%54

7
Second-order SQL injection

• A particularly interesting type of filter bypass is related to


second-order SQL injection
• Also known as “stored SQL injection”
• Many applications handle data safely when it is first inserted into
the database
• For example, all single quotes are "escaped"
• But these data may later be processed in unsafe ways, either by
the application itself or by other back-end processes
• Those processes may not have the stringent security of the
Internet-facing application

8
Second-order SQL injection

1) An attacker submits malicious SQL code as user input → the input is


not executed as SQL but stored as data in the database.
2) When the application retrieves the stored data and uses it in a new
SQL query (, such as displaying user information or updating
records) without sanitization or parameterization, the malicious SQL
code is executed.
3) This can lead to unauthorized data access, data modification, or
data deletion. It can also be used for privilege escalation or to gain
control over the database server.
Second-order SQL injection Example

Context:
a web application where users can register with a username, and these
usernames are not sanitized or parameterized before being used in a query

1) A user registers with a username like XXX' OR 1=1 --.


2) The registration is accepted, and the username is stored in the database.
3) When the application retrieves the username to display user information, it
might use a query like SELECT * FROM users WHERE username = '$username'. If
$username is not sanitized, the malicious SQL code is executed.
Second-order SQL injection Example

Assume a web application where users can search for books


based on the publisher’s name. The application validates the
input by escaping single quotes

When the user enters the search term O'Reilly, the application makes the
following query: SELECT author,title,year FROM books WHERE
publisher='O''Reilly’

The single quotation mark supplied by the user has been converted into two
single quotation marks, so there are no syntax errors or injection vulnerabilities.
The stored value becomes: O''Reilly

A problem arises when the data item passes through several SQL queries,
being written to the database and then read back more than once

11
Second-order SQL injection Example

When the data item is read back from the database and used in another SQL
query, the application may escape it again, treating the two single quotes ('') as a
literal single quote (') and escaping it further by adding another pair of single
quotes. ….

So, the data item O''Reilly becomes: O''''Reilly

Each time the data passes through a query (e.g., being read, processed, and written
back), additional escaping occurs. This leads to an exponential increase in the number
of single quotes!
O''''Reilly → O''''''Reilly → O''''''''Reilly → ...

Consequences:
- Data is corrupted, queries may behave in unexpected ways, more vulnerabilities for
attackers to exploit
Second-order SQL injection Example

Context: a web application that allows self-registration

Attempting to register the username foo' results in the following query:

INSERT INTO users (username, password, ID, privs) VALUES


('foo''', 'secret', 2248, 1)

So far, the INSERT statement causes no problems for the database, and the
username foo' is stored in the database

The application also allows users to change their passwords

13
Second-order SQL injection example

This password change functionality requires users to submit their old


password, and then verifies that this is correct by retrieving the user’s current
password from the database

To do this, it first retrieves the user’s username from the database and then
constructs the following query:

SELECT password FROM users WHERE username = 'foo''

Therefore, when the user’s original bad input is embedded directly into the
query, a SQL injection flaw arises (and causes an error)

Thus, the attacker can register complex usernames that inject arbitrary
queries
14
Retrieving data as numbers
Sometimes, when an SQL injection attack is attempted, a web application may not directly display
the results of the query. Instead, it displays error messages from the database complaining that
the SQL query’s syntax is incorrect, different HTTP responses, and so on.

In these situations, the attacker is forced to steal data by asking the database a series of true or
false questions. So, the results of the injected queries will be received as numeric responses
from the web application. The SUBSTRING function is commonly used in these kind of blind
SQL injection attacks to extract data from a database one character at a time.

The challenge is to process the results of your injected queries in such a way that
string data can be retrieved in numeric form

Two key functions can be used: SUBSTRING (or SUBSTR in Oracle) and ASCII

SUBSTRING('Foo',1,1) returns F (first number is the start, second is the length)

ASCII('A') returns 65 (the decimal value of the character's ASCII code)

15
Retrieving data as numbers

Recall our HR application and assume we have a URL where you can query an
employee's last name to retrieve their employee ID

The underlying SQL query may be the following:

SELECT * from employees WHERE lname='King'

We want to extract the password for the admin user via a UNION operator

First, we need to know how many columns the SQL query returns:

' UNION SELECT NULL #


' UNION SELECT NULL,NULL #
' UNION SELECT NULL,NULL,NULL # (successful query)

16
Retrieving data as numbers

Next, we need to figure out which column is returned, and use it to retrieve a
password from the users table

We can test the column that is returned with a single query:

' UNION SELECT 4,5,6 # (output is 4, so first column is returned)

Thus, the query we want to extract the password is the following:

' UNION SELECT password,NULL,NULL FROM users WHERE


username='admin' #

Notice that the query is successful, but only 0 is returned (integer output)

17
Retrieving data as numbers

However, using the SUBSTRING and ASCII functions, we can extract the admin's
password, character by character, via multiple queries

Let's extract the first character:

' UNION SELECT ASCII(SUBSTRING(password,1,1)),NULL,NULL FROM


users WHERE username='admin' # (returns 113, i.e., 'q')

And then the second:

' UNION SELECT ASCII(SUBSTRING(password,2,1)),NULL,NULL FROM


users WHERE username='admin' # (returns 119, i.e., 'w')

...
18
Conditional responses

• Suppose that you have not identified any method of transmitting the
results of your injected queries back to the browser
• For example, in a user login functionality, where the output is either
success or failure
• However, we already know how to use SQL injection to modify the
application's behavior
• For example, submitting the following two inputs causes very
different results:
• admin' AND 1=1 --
• admin' AND 1=2 --

AND 1=1 → always TRUE


AND 1=2 → always FALSE 19
Conditional responses

Recall our web interface, where we could log in as admin by supplying an arbitrary
password and the username admin' #

Suppose we also want to extract the admin's password. We can use conditional
responses to determine each password character separately:

admin' and ASCII(SUBSTRING(password,1,1))=33 # (login fails)


admin' and ASCII(SUBSTRING(password,1,1))=34 # (login fails)
...
admin' and ASCII(SUBSTRING(password,1,1))=113 # (login succeeds)

ASCII 113 corresponds to letter 'q'

20
Conditional errors

• In some cases, you may be injecting into a query that has no


noticeable effect on the application’s behavior, such as a login
mechanism
• Thus, it may be difficult to find a way to cause a detectable
difference in behavior
• One idea is to inject a query that induces a database error
contingent on some specified condition
• Consider a SELECT statement containing a WHERE clause:
SELECT X FROM Y WHERE C
• We can choose as X an expression that causes a database error
• If condition C is false, no error is generated

21
Conditional errors

The expression X can be something like 1/0 (division by zero), which causes
different behavior in different databases (e.g., return nothing or null or error)

Suppose we want to check whether a certain username alice exists in the


users table. We can inject the following query:

SELECT 1/0 FROM dual WHERE (SELECT username FROM users WHERE
username = 'alice') = 'alice'

dual is a dummy table that exists by default in most DBMSs

If the query causes an error, alice is a valid username

22
Using time delays

• In some situations, none of the previous techniques are effective


• The injected query returns no results to the browser, and has no
effect on the application's behavior, even when it induces a
database error
• In this case, we may craft a query that would cause a time delay,
contingent on some condition
• The attacker can submit the query and then monitor the time taken
for the server to respond
• If a delay occurs, the attacker may infer that the condition is true
• Even if the actual content of the application’s response is identical
in the two cases, the presence or absence of a time delay enables
the attacker to extract a single bit of information from the database

23
Using time delays

Let's go back to our HR application and try to extract some information using time
delays. In this case, we want to retrieve the database version

We can do this with a UNION query, where the time delay is caused by performing
a large number of hashing (SHA1) operations at the server:

' UNION SELECT IF(ASCII(SUBSTRING(@@version,1,1))=49,


BENCHMARK(5000000,SHA1('dummy_data')),NULL),NULL,NULL #

Since the first character of the database version is '1', whose ASCII code is 49,
you will observe a delay in the server's response

If you try other values, the server will respond much faster

24
Using SQL exploitation tools

• Many of the techniques we have described involve performing large


numbers of requests to extract small amounts of data at a time
• Fortunately, numerous tools are available that automate much of
this process
• These tools are aware of the database-specific syntax required to
deliver successful attacks
• They can be configured to identify (and exploit) vulnerabilities on
any parameter of an HTTP request, using different techniques
• Probably the most popular SQL exploitation tool available, is
sqlmap

25
How these tools exploit SQL injection vulnerabilities

▪ Brute-force all parameters in the target request to locate SQL injection points
▪ Determine the location of the vulnerable field within the back-end SQL query by
appending various characters such as closing brackets, comment characters, and SQL
keywords
▪ Attempt to perform a UNION attack by brute-forcing the number of required columns and
then identifying a column with the varchar data type, which can be used to return results
▪ Inject custom queries to retrieve arbitrary data—if necessary, concatenating data from
multiple columns into a string that can be retrieved through a single result of the varchar
data type
▪ If results cannot be retrieved using UNION, inject Boolean conditions (AND 1=1, AND
1=2, and so on) into the query to determine whether conditional responses can be used
to retrieve data
▪ If results cannot be retrieved by injecting conditional expressions, try using conditional
time delays to retrieve data

26
Working with sqlmap

▪ sqlmap is available here: https://sqlmap.org/


▪ The easiest way to install is via git
$ git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git
sqlmap-dev

▪ This will download the Python code to your local directory


▪ You can go into that directory and run the application
▪ To see all the available options, type the following

$ ./sqlmap.py -hh

27
WARNING!!

Attacking a web application or server without the


owner’s explicit permission is illegal

28
Preventing SQL injection

Ineffective methods:
Effective methods:
• Input validation, e.g., via whitelists or
blacklists—can easily be circumvented • Parameterized queries—also known as
• Escaping dangerous characters, such as prepared statements
single quotation marks—may still lead to • Stored database procedures
second-order SQL injection

29
Incorrect statement preparation

▪ In this PHP example, the SQL statement is generated dynamically from the user's input
▪ The inputs here are $username and $password which are read from the submitted
HTML form
▪ If the SQL statement is prepared in this manner, the application is vulnerable to SQL
injection

30
Prepared statements with parameterized queries

▪ The correct way to prepare a SQL statement is to use proper parameterbinding


▪ user input is treated as data rather than executable code
▪ In the following example, the prepared SQL statement includes placeholders (?) where
the user-supplied input is inserted
▪ If a user enters a username such as "admin' --", the query will try to find a row in the
database where the username is actually "admin' --"
▪ Also, the query structure remains fixed regardless of user input, so attackers cannot
inject additional clauses

31
Stored procedures

▪ The second method for preventing SQL injection is using stored procedures (i.e.,
functions) at the database server
▪ The following example shows how to properly write a procedure for a login SQL
statement
▪ The parameters @username and @password are passed to the procedure by the PHP
code

Code from: https://docs.microsoft.com/en-us/archive/blogs/brian_swan/do-stored-procedures-protect-against-sql-injection 32


Question - why is this web application vulnerable?

<?php
$conn = new mysqli("localhost", "root", "", "testdb");
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$username = $_GET['username'];
$sql = "SELECT * FROM users WHERE username='$username'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo "id: " . $row["id"]. " - Name: " . $row["username"]. " " . $row["password"]. "<br>";
}
} else {
echo "0 results";
}
$conn->close();
?>
Explanation
1) Directly Uses User Input in SQL Queries
** No validation or sanitization of username – user input goes from the URL
($_GET['username']) directly into the SQL query → allows an attacker to inject malicious
SQL code, such as: http://localhost/index.php?username=' OR '1’=‘1, which would return
all rows from the users table
** Always validate and
sanitize user input

2) Prepared statements not used


** The SQL query is constructed
using string concatenation, which is
inherently insecure.
** Example of how to rewrite the code ➔
Acknowledgements
This set of slides for AY24/25 Tri 2 was prepared/adapted from the hard work of previous
professors who taught this module, namely:
• Prof. Weihan
• Prof. Linda
• Prof. Liming
• Prof. Spiros

35
Web Applications |2024
Goh Weihan | January

You might also like