Blind SQL injection
Introduction
Blind SQL injection arises when an application is vulnerable to SQL injection, but its HTTP responses do not contain the results of the relevant SQL query or the details of any database errors.
With blind SQL injection vulnerabilities, many techniques such as UNION attacks
, are not effective because they rely on being able to see the results of the injected query within the application's responses.
Exploiting blind SQL injection by triggering conditional responses
When a request containing a TrackingId cookie is processed, the application determines whether this is a known user using an SQL query like this:
This query is vulnerable to SQL injection, but the results from the query are not returned to the user. If it returns data (because a recognized TrackingId was submitted), then a "Welcome back" message is displayed within the page.
This behavior is enough to be able to exploit the blind SQL injection vulnerability and retrieve information by triggering different responses conditionally, depending on an injected condition. To see how this works, suppose that two requests are sent containing the following TrackingId cookie values in turn:
The first of these values will cause the query to return results, because the injected AND '1'='1 condition is true, and so the "Welcome back" message will be displayed.
Whereas the second value will cause the query to not return any results, because the injected condition is false, and so the "Welcome back" message will not be displayed. This allows us to determine the answer to any single injected condition, and so extract data one bit at a time.
SUBSTRING Function
For example, suppose there is a table called Users with the columns Username and Password, and a user called Administrator. We can systematically determine the password for this user by sending a series of inputs to test the password one character at a time.
To do this, we start with the following input:
This returns the "Welcome back" message, indicating that the injected condition is true, and so the first character of the password is greater than m.
Next, we send the following input:
This does not return the "Welcome back" message, indicating that the injected condition is false, and so the first character of the password is not greater than t.
Eventually, we send the following input, which returns the "Welcome back" message, thereby confirming that the first character of the password is s:
We can continue this process to systematically determine the full password for the Administrator user.
Confirm it table exists in the database
Confirm if entry exists in the database
Check Length of password in the database
Inducing conditional responses by triggering SQL errors
In the preceding example, suppose instead that the application carries out the same SQL query, but does not behave any differently depending on whether the query returns any data. The preceding technique will not work, because injecting different Boolean conditions makes no difference to the application's responses.
In this situation, it is often possible to induce the application to return conditional responses by triggering SQL errors conditionally, depending on an injected condition.
To see how this works, suppose that two requests are sent containing the following TrackingId cookie values in turn:
These inputs use the CASE keyword to test a condition and return a different expression depending on whether the expression is true. With the first input, the CASE expression evaluates to 'a', which does not cause any error. With the second input, it evaluates to 1/0, which causes a divide-by-zero error. Assuming the error causes some difference in the application's HTTP response, we can use this difference to infer whether the injected condition is true.
Last updated