What is SQL Injection?
SQL Injection is a type of database attack in which an attacker tries to steal information from a web application’s database. This can even result to remote code execution depending upon web application environment and database version.
SQL Injection happens due to poor sanitization of user input. If you take input from user in some coding language (PHP, ASP.NET) and pass it directly to server’s database without applying any filter on the input, this can result to SQL Injection vulnerability.
For example, the following PHP code is vulnerable to SQL Injection attack because its directly passing the user input to database. Attacker can craft its own malicious database query to extract data from database.
$id = $_GET['id'];
// The userinput is directly executed in database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
// In case of error or success, the results are returned to user
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
$num = mysql_numrows($result);
On the other hand, a secure code example of such code to interact with database is given. It takes user input and filters any malicious characters from it, then passes it to the database.
$id = stripslashes($id);
$id = mysql_real_escape_string($id);
Normal vs Blind SQL Injection
Normal SQL Injection
In normal SQL Injection, if an attacker tries to put a single quote (‘) as input, when this single quote is executed in database, the database responds with an error. The error is printed at attacker’s browser.
The code responsible for this error is
to print the error
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
In Normal SQL Injection, attacker can see the error results and its easy to identify and exploit.
Blind SQL Injection
In the case of Blind SQL Injection, when a malicious query such as a single quote is executed, the database error isn’t displayed at attacker’s browser or it is displayed in a very generic manner that cannot be identified and exploited easily by the attacker.
The backend code responsible for this is given below
In Blind SQL Injection, attacker can’t see the complete results, hence this type of SQLi is difficult to identify and exploit but it has same risk level as of normal SQLi.
Techniques to Detect Blind SQL Injection
While normal SQL Injection can be detected by sending single quote (‘) as input and examining the output error, Blind SQL injection cannot be detected using this technique because it doesn’t display any SQL error. There are many techniques to detect a Blind SQL injection, some of them are given as follow
TRUE and FALSE Based detection
One of the characteristics of Databases including MySQL is the different behaviour upon True and False statements. Even if database doesn’t show any errors, we can decide using the use of True and False statements. Consider the following scenario,
The following page is vulnerable to Blind SQL injection, giving it a true statement will display all entries in the database
Giving a False query as input will not display any data.
Even the webpage doesn’t show any errors, the difference between the two pages tells that our queries are being successfully executed in the database.
TIME based detection
There is a function in databases including MySQL, MS-SQL and others for delays. We can use the SLEEP() function in our query, if database’s response is slow that means our query is executed successfully and webpage is vulnerable to Blind SQL Injection.
There is another time consuming function “BENCHMARK” which can be used to delay the database response
The above line will execute the SHA1() function 10000000 times in the database, which will add a significant amount of delay in response.
Time based Blind SQL Injection in other databases
MS SQL : ID=1;waitfor delay ‘0:0:10’–
ORACLE SQL : AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE(‘[RANDSTR]’,[SLEEPTIME])
PostgreSQL : AND [RANDNUM]=(SELECT [RANDNUM] FROM PG_SLEEP([SLEEPTIME]))
SQLite : AND [RANDNUM]=LIKE(‘ABCDEFG’,UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
Extracting Database Information
The first step of extracting database is determining column numbers in the database. Then try to find vulnerable columns to extract further data.
Blind SQL Injection behaves differently with different column numbers in “order by” query.
The above statement is true because at least 1 column always exist in a database. Now try with a very large number.
The database response is different than the previous one. Now try with 2 columns.
The statement worked, that means database has 2 or more columns. Now try with 3 columns.
The database hasn’t send any response, that means database has 2 columns only. Now we’ll try to dump the list of tables in the database, we’ll use the following query for that
tables where table_schema=database()#
There are two tables in the backend database “guestbook & users”. The “users” table may contain usernames and passwords. To extract column names from the table, insert the following query.
columns where table_schema=database()#
Now we have extracted column names, this includes user and password columns. These columns store customers’ usernames and their passwords.
Now we’ll try to extract the data using the following query
And that’s how you can exploit Blind SQL Injection without relying on errors. Output passwords are hashed most of the time, which can be decrypted using tools like John The Ripper or Hashcat.
Conclusion:
Blind SQL Injection is the type of SQLi which doesn’t show database errors or responds with a very generic message. That’s why It is very difficult to identify Blind SQL Injection vulnerability in a webpage. Once detected, you can exploit it easily by manual or automated process using SQLmap.