BaluFood
Introducción
Sección titulada «Introducción»En este artículo documentamos la resolución de la máquina virtual BaluFood, creada por El Pingüino de Mario y catalogada como fácil en la plataforma DockerLabs. El objetivo es que el writeup sea reproducible y didáctico: explicar qué se hizo, por qué se hizo, y qué buscar en situaciones similares.
El flujo de trabajo se organiza en tres fases:
- Reconocimiento – Identificar servicios expuestos, rutas web y vectores de entrada.
- Explotación – Aprovechar debilidades (credenciales por defecto, ficheros expuestos, etc.) para obtener acceso inicial.
- Escalada de privilegios – Buscar información sensible local que permita elevar privilegios hasta
root.
Aviso: todos los pasos descritos se realizaron en un laboratorio/entorno controlado (DockerLabs). No ejecutes pruebas intrusivas fuera de entornos autorizados.
Información general
Sección titulada «Información general»- Nombre: BaluFood
- Autor: El Pingüino de Mario
- Dificultad: Fácil
- Fecha de creación: 29/04/2025
- Plataforma: DockerLabs
Paso 0 — Preparación y despliegue
Sección titulada «Paso 0 — Preparación y despliegue»- Descargar el paquete desde DockerLabs y descomprimir:
unzip BaluFood.zip- Desplegar el contenedor con el script incluido:
sudo bash auto_deploy.sh BaluFood.tarEl script crea y arranca un contenedor Docker que expone los servicios necesarios. Anota la IP que imprime el script; la usaremos en los siguientes pasos.
Paso 1 — Reconocimiento
Sección titulada «Paso 1 — Reconocimiento»1.1 Organización de trabajo
Sección titulada «1.1 Organización de trabajo»Crear un árbol de trabajo para mantener evidencia y resultados:
mkdir -p BaluFood/{content,exploits,nmap,scripts}cd BaluFoodMantener un directorio ordenado facilita repetir los pasos y preparar el informe final.

1.2 Escaneo de puertos
Sección titulada «1.2 Escaneo de puertos»Realizamos un barrido completo con Nmap (todos los puertos) para identificar servicios expuestos:
nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 172.17.0.2 -oG allPortsExtraemos los puertos detectados (una alternativa rápida si no se dispone del script extractPorts):
extractPorts allPorts
Resultado relevante: puertos abiertos 22 (SSH) y 5000 (HTTP). En 5000 se aloja la aplicación web del restaurante (pizzería) — objetivo principal para enumeración.
1.3 Enumeración web
Sección titulada «1.3 Enumeración web»Usamos gobuster para búsqueda de directorios y endpoints relevantes:
gobuster dir -u http://172.17.0.2:5000/ \ -w /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt \ -x php,html,txt,js -t 200 -o gobuster.txt
Rutas identificadas y primeras observaciones:
/index— Página de inicio del restaurante.
/carta— Menú / carta de platillos (contenido estático dinámico).
/console— Consola online (arrojaBad Request). Puede indicar un endpoint con parámetros mal validados.
/login— Formulario de autenticación.
Observación: endpoints como
/consoley/loginson buenos puntos de partida para probar autenticación débil, credenciales por defecto y fugas de información en el código fuente.
Paso 2 — Explotación
Sección titulada «Paso 2 — Explotación»2.1 Autenticación inicial (credenciales por defecto)
Sección titulada «2.1 Autenticación inicial (credenciales por defecto)»Accedimos a /login en http://172.17.0.2:5000/login. Probamos credenciales comunes/por defecto y obtuvimos acceso con admin:admin. Al autenticarnos fuimos redirigidos a /admin.
POST /loginusername=adminpassword=admin--> 302 Redirect /admin
Por qué funciona: muchas aplicaciones de laboratorio y malas configuraciones mantienen cuentas por defecto o no han cambiado credenciales en despliegues; siempre probar combinaciones estándar durante una auditoría autorizada.
2.2 Revisión del panel y código disponible
Sección titulada «2.2 Revisión del panel y código disponible»El panel de administración muestra pedidos y opciones de gestión. Dado que tenemos acceso administrativo, exploramos el código.
Al revisar el codigo de /admin, encontramos credenciales hardcodeadas y variables sensibles en el código fuente:

2.3 Acceso por SSH con credenciales encontradas
Sección titulada «2.3 Acceso por SSH con credenciales encontradas»Con las credenciales obtenidas en el código, probamos acceso SSH y obtuvimos entrada como el usuario SysAdmin (ejemplo):
ssh SysAdmin@172.17.0.2# password: <credencial_obtenida>
Resultado: sesión de usuario con permisos limitados pero con acceso a ficheros del servidor web.
Paso 3 — Escalada de privilegios
Sección titulada «Paso 3 — Escalada de privilegios»Dentro del usuario SysAdmin realizamos una enumeración local básica:
iduname -aps auxls -la ~find / -type f -perm -u=s -ls 2>/dev/null # archivos SUIDListado del home reveló archivos del proyecto web; el archivo app.py contenía variables interesantes (secrects/credenciales) ya mencionadas.

3.2 Movimiento lateral: credenciales para otro usuario
Sección titulada «3.2 Movimiento lateral: credenciales para otro usuario»A partir de la información en app.py encontramos credenciales que pertenecen al usuario Balulero. Con estas credenciales accedimos a la cuenta Balulero:


Dentro del home de Balulero vimos un .bashrc con contenido sospechoso — por ejemplo, una contraseña en claro, una cadena codificada (base64) o un script que exporta variables de entorno con contraseñas:

Técnica empleada: leer .bashrc y otros ficheros de configuración del usuario en busca de credenciales o claves; frecuentemente los desarrolladores dejan claves en scripts o en variables de entorno para pruebas locales.
3.3 Obtener root
Sección titulada «3.3 Obtener root»Tras extraer la credencial encontrada en .bashrc intentamos autenticar como root con la contraseña hallada. Conseguimos acceso root con la contraseña recuperada:
su - root# password: <contraseña_obtenida>
Conclusión y aprendizajes
Sección titulada «Conclusión y aprendizajes»Cadena de explotación (resumen)
Sección titulada «Cadena de explotación (resumen)»- Descubrimos servicio HTTP en
5000y directorios públicos congobuster. - Encontramos
/loginy autenticamos con credenciales por defectoadmin:admin. - Desde el panel accedimos al código/archivos del servidor y localizamos credenciales hardcodeadas en
app.py. - Usamos esas credenciales para SSH a
SysAdmin. - Del home de
SysAdminyBaluleroextrajimos más credenciales (contenido en.bashrc), decodificamos/empleamos y obtuvimosroot.
Fallos de seguridad identificados
Sección titulada «Fallos de seguridad identificados»- Credenciales por defecto (admin:admin) sin política de cambio.
- Credenciales hardcodeadas en código fuente / backups accesibles desde la web o desde archivos con permisos inseguros.
- Ficheros de configuración con contraseñas en
.bashrco otros scripts sin protección. - Respuestas web que filtran información (panel administrativo con acceso a ficheros).
- Ausencia de cifrado en enlaces internos que podría haber expuesto credenciales.
Recomendaciones (remediación)
Sección titulada «Recomendaciones (remediación)»- Eliminar credenciales por defecto; forzar cambio de contraseñas en despliegue.
- No almacenar secretos en el repositorio ni en ficheros accesibles por el servidor web; usar gestores de secretos o variables de entorno bien protegidas.
- Restringir permisos de archivos sensibles (
chmod 600) y limitar qué usuarios pueden leer backups. - Deshabilitar auth por contraseña en SSH cuando sea posible y usar llaves públicas + MFA.
- Evitar incluir contraseñas en archivos ejecutables (.bashrc, scripts); si es imprescindible, protegerlos y auditar accesos.
- Normalizar respuestas del servidor y reducir la cantidad de información de error que pueda ayudar a la enumeración.