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)

Introduction

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.

Result

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.

Annunci