In-band SQL injections

The classics one

First, you have to understand the different types of SQLi, here. I will speak here about In-band Injection, the classic one. divided into 2 types:

  • Error based SQLi
  • UNION based SQLi

Error Based SQLI


Gathering database structure information by Displaying SQL Errors on the target website. In some cases, you can enumerate the entire database with those.

Finding a weak URL

Using Google Dorks. Yes, google is helping you finding weak urls.

→   inurl:"product.php?id="

Here you are asking Google to list Russian site with product.php?id= in the URL. But Why? Because we want to find a page which is directly talking to the database. In most cases you want to search for those patterns: *.php?parameter=n

how do I know this URL is weak to SQLi?

You have to put a ' or %27 just after the parameter’s number and press enter: http[:]//'. If a SQL Error appears there is some probability that this website is injectable.



Leverages the UNION SQL operator to combine the results of two or more SELECT statements into a single result.

the following block is part of a material I wrote for infoSec students. (Offensive security class)

first step

Find an URL that sends SQL queries, like this one: . This URL list products, regrouped in the category named 1. Try to remember that an URL ending with * ? * = * will, in most cases, communicate with a SQL Database, we want to exploit this.

The second step

Translate the products.php?category=1 part of URL into a SQL query. In this scenario (and in a lot of website in production) this piece of URL is a disguised SQL query:

→   products.php?category=1 = SELECT * FROM products WHERE category=1

The third step

Can we inject the category parameter? Let’s try to sort the products list by adding ORDER BY n:

→ ORDER BY 1 Nothing change.

→ ORDER BY 2 The products order have changed! The n number in ORDER BY n indicate from which table’s column number you are sorting the output (in this case the second column of the table products). So wait a minute, what happens if I input a number that exceeds the maximum number of the table? Let’s try out.

→ ORDER BY 3 Order changes again.

→ ORDER BY 4 Blank page! We can deduce that the product’s table has 3 column. This info is crucial for using the SQL UNION ALL operator.

The fourth step

Let’s plan the attack for capturing the flag. So, for instance, let’s assume you can fetch the flag by dumping the email addresses of the w34ksite DB.

Of course, the email entries are not in the product table. They should be elsewhere… You can guess table’s name and more when SQL error appear directly on the web page, but this time, we will try to rely on the UNION leverage attack.

So let’s assume the email’s table is named email, because we know this is the CMS default email’s table name.

→   SELECT * FROM email = ?

Of course not. Who will be crazy enough to create a PHP page that lists the database’s email? Why not password.php?

Don’t forget that products.php?category=1 is our key to communicate with the database and inject things. This key open the database door, the general idea is to use this key for displaying the content of the email table.

We will achieve that by displaying the products table contents (products.php?category=1) and the email table contents. Using the UNION ALL operator. This operator is quite useful, you can merge another SQL request by using it.

Let’s translate again the key URL into a SQL query:

→   products.php?category=1 = SELECT * FROM products WHERE category=1

Let’s add a new query by using the UNION ALL operator:

→   SELECT * FROM products WHERE category=1 AND UNION ALL SELECT *, NULL, NULL FROM email

Let’s merge the key URL and the new query (Which is actually an UNION based SQL injection attack trying to diplay the email table.) We should have something like this : UNION ALL SELECT *, NULL, NULL FROM email

* , NULL, NULL ?

  • NULL: Fake an empty column.
  • , : Separate a column from another
  • * : display entries of this column

Remember the ORDER BY 4 which has return a blank page? We get a very valuable information: the number of column the product’s table possess, the number of column is 3. When using the UNION ALL operator, the table’s column number has to be the same for both queries. For instance if the products table possessed 5 columns, the UNION ALL attack would be something like this UNION ALL SELECT *, NULL, NULL, NULL, NULL FROM email

If nothing happens, try to move the * around like this: