On a local MySQL server, I’m installing a library of UDFs (User Defined Functions) to access system’s command and their output. I will later use that function to make MySQL send messages (calling an appropriate URL) on insert/update/delete events.

My environment is:

  • Windows (but it should work on Linux with few differences)
  • MySQL 5.6, 5.7 (but it should work on other versions as well)


If you don’t know what an UDF library is in a MySQL context, then you should read the MySQL official documentation: https://dev.mysql.com/doc/refman/5.6/en/server-udfs.html

Situation check

You can check the current situation running few queries.

select @@version_compile_os, @@version_compile_machine;

In my case: Win64, x86_64

select @@plugin_dir ;

I’ve got: C:\Program Files\MySQL\MySQL Server 5.6\lib\plugin

SELECT * FROM mysql.func;

It returned an empty result set, meaning that no UDF has been defined in my server.

The Sys UDF library

I started this research because I needed the sys_eval function: it is able to run any command and return the output. I’ve found this interesting page: http://bernardodamele.blogspot.com/2009/01/command-execution-with-mysql-udf.html

The library’s source code and the compiled .so file for Unix/Linux is available at this page: https://github.com/mysqludf/lib_mysqludf_sys

But I’m running Windows and my environment is not ready to compile that project. So I’ve found the library already compiled for windows: https://github.com/rapid7/metasploit-framework/tree/master/data/exploits/mysql

The previous project is described in the following page, that is an interesting reading indeed: https://osandamalith.com/2018/02/11/mysql-udf-exploitation/

Library setup

If you have read the MySQL documentation, the next steps are no surprise for you.

First, put the lib_mysqludf_sys_64.dll file in the @@plugin_dir directory.

Then run the following query:

create function sys_eval returns string soname 'lib_mysqludf_sys_64.dll';

The library contains other useful functions, please look at the documentation, as described above.


Now you are able to execute any arbitrary command of your system with an SQL query:

SELECT sys_eval('dir');

that returns a BLOB, or with a type cast:

SELECT CAST(sys_eval('dir') AS CHAR(10000));

that returns a simpler string.