Linkvortex

Publicado: 07 de Junio de 2025 Autor: José Miguel Romero aKa x3m1Sec Dificultad: ⭐ Easy
📝 Descripción
Linkvortex es una máquina Linux de dificultad Easy de HackTheBox que presenta un CMS Ghost vulnerable (versión 5.58) con una vulnerabilidad de lectura arbitraria de archivos (CVE-2023-40028). La escalada de privilegios se realiza mediante la explotación de un script personalizado que procesa enlaces simbólicos de forma insegura.
🎯 Objetivos de Aprendizaje
Enumeración web y descubrimiento de subdominios
Explotación de repositorios Git expuestos
Aprovechamiento de vulnerabilidades en Ghost CMS
Lectura de archivos sensibles del sistema
Escalada de privilegios mediante manipulación de enlaces simbólicos
🏷️ Categorías
Web Exploitation
Information Disclosure
Git Repository Enumeration
Privilege Escalation
Symlink Attack
🛠️ Herramientas Utilizadas
nmap- Escaneo de puertos y serviciosdirsearch/feroxbuster- Fuzzing de directoriosffuf- Fuzzing de virtual hostsgit_dumper- Extracción de repositorios GitExploit CVE-2023-40028 para Ghost 5.58
🔭 Reconocimiento
Ping para verificación en base a TTL
💡 Nota: El TTL cercano a 64 sugiere que probablemente sea una máquina Linux.
Escaneo de puertos TCP
Enumeración de servicios
⚠️ Importante: Detectamos durante la fase de enumeración con nmap que se está realizando virtual hosting. Debemos añadir el siguiente vhost a nuestro fichero /etc/hosts
🌐 Enumeración Web
80 HTTP (linkvortex.htb)
No encontramos gran cosa al enumerar el sitio de forma manual. La opción de registro no está implementada ni tampoco hay formularios en la web.

👻 Identificación de Ghost CMS
Revisando el código fuente encontramos una etiqueta meta que hace referencia a Ghost 5.58
Buscando información sobre este software encontré que es una aplicación para crear contenido, un CMS: https://ghost.org/
Al buscar información sobre este software también encontré que había tenido vulnerabilidades y en concreto parece que tuvo una vulnerabilidad de tipo Arbitrary File Read en la versión 5.58:
https://github.com/0xDTC/Ghost-5.58-Arbitrary-File-Read-CVE-2023-40028
Pero echemos un ojo primero a ver si encontramos algo realizando fuzzing.
📂 Fuzzing de directorios
Tras probar a realizar fuzzing de directorios con dirsearch y ferxobuster encontramos algunos recursos que añadir a nuestro scope:


Uno de ellos nos permite saber que hay un usuario admin, ya todos los post son de este usuario.


🔐 Panel de autenticación
Revisando el panel de login, nos pide una cuenta de correo como usuario. Si probamos con el nombre de usuario encontrado y el dominio vemos que parece ser válido, ya que si introducimos otro distinto el mensaje de error es diferente:
http://linkvortex.htb/ghost


Una opción a valorar sería usar hydra y un ataque de diccionario para ver si logramos la contraseña, pero como este probablemente sería un proceso largo, continuemos primero enumerando para ver si existen también otros subdominios.
🔧 Subdominio de desarrollo (dev.linkvortex.htb)
Fuzzing de vhosts
Al realizr fuzzing de vhosts encontramos un subdominio llamado dev que procedemos a añadir a nuestro fichero /etc/hosts

Al acceder encontramos que el sitio parece estar todavía en construcción

📂 Fuzzing del subdominio dev
Al realizar fuzzing sobre este subdominio encontramos un repositorio en git:

⬇️ Extracción del repositorio Git
Podemos usar la herramienta git_dumper para descargar el repositorio a nuestro host de ataque.
El repositorio está en un estado un poco extraño:
Actualmente no está en una rama, pero tiene dos archivos modificados pendientes de confirmación. Puedo ver la diferencia en cada uno de ellos usando git diff --cached. El Dockerfile.ghost es completamente nuevo:

Vemos que hay un archivo de configuración en /var/lib/ghost/config.production.json
🗝️ Descubrimiento de credenciales
Revisemos primero las diferencias del otro archivo que habíamos visto:

La cosa se pone interesante porque aquí encontramos una contraseña. Vamos a probar esta contraseña OctopiFociPilfer45 con la cuenta del usuario admin@linkvortex.htb y comprobemos si mereció la pena seguir enumerando en lugar de intentar el ataque de fuerza bruta con hydra:

Estamos dentro! Esto se pone interesante, ya que el exploit que vimos para
💥 Explotación

Ahora probemos con la ruta del fichero que habíamos descubierto en el archivo de configuración del repositorio en git: /var/lib/ghost/config.production.json
🔐 Acceso SSH
Encontramos una nueva credencial: bob@linkvortex.htb:fibber-talented-worth en lo que parece ser un servicio SMTP. Pero tal como vemos, este servicio no está expuesto.
Lo único que nos queda verificar es si se puede estar reutilizando esta credencial en algún otro servicio, por ejemplo el servicio ssh:

Ganamos acceso a la máquina como usuario bob y obtenemos la primer flag en su directorio de usuario.
🚀 Escalada de privilegios
Verificamos si bob puede ejecutar algún comando como root:
📋 Análisis del script vulnerable
El script básicamente lo que hace es analizar un enlace simbólico (symlink) a una imagen .png, determinar si apunta a un archivo crítico (como algo en /etc o /root), y en ese caso eliminarlo o moverlo a cuarentena.
Vamos paso a paso:
Se define el directorio de cuarentena donde se moverán los enlaces sospechosos.
Comprobación de variable opcional.
Si la variable de entorno
CHECK_CONTENTno está definida, se le asigna el valorfalse.Esta variable indica si se debe imprimir el contenido del archivo al que apunta el symlink.
Captura del argumento introducido por el usuario
En este if se valida la extensión del archivo que ha introducido el usuario.
Se verifica, usando
sudo, si el archivo es un enlace simbólico (-L).Si no lo es, no hace nada (fin del script).
Se analiza el enlace simbólico.
LINK_NAME: obtiene solo el nombre del archivo (sin ruta).LINK_TARGET: obtiene a qué archivo apunta realmente el enlace.
Se comprueba si el enlace apunta a ficheros críticos del sistema:
Si el destino del enlace contiene
etcoroot(ej./etc/passwdo/root/.ssh/id_rsa), lo considera peligroso.Imprime una advertencia y elimina el enlace simbólico con
unlink.
Si no apunta a un archivo sensible, se mueve a la carpeta de cuarentena (/var/quarantined).
Si
CHECK_CONTENTestá activado, intenta leer el contenido del archivo al que apuntaba el enlace.
🔗 Explotación mediante Symlink Attack
Primero, creamos un enlace simbólico (symlink) que apunte al archivo /root/root.txt:

Con esto lo que estamos haciendo es crear un enlace simbólico llamado x3m1sec.txt que apunte al fichero /root/.ssh/id_rsa.txt
Recordemos que el script requiere que el archivo que le indiquemos tenga extensión .png, por lo que creamos otro enlace simbólico

ln -s /home/bob/x3m1sec.txt x3m1sec.png→ Creamos un segundo symlink (x3m1sec.png) que apunta ax3m1sec.txt, el cual a su vez apunta aroot.txtlogrando de esta forma evadir el filtro del script.
Nos falta un paso todavía, ya que necesitamos que la variable esté inicializada. CHECK_CONTENT=true
¿Qué pasa aquí?
CHECK_CONTENT=true→ Hace que el script muestre el contenido del archivo después de moverlo a/var/quarantined/./opt/ghost/clean_symlink.sh /home/bob/x3m1sec.png→ El script moverá el symlink y leerá su contenido.

Obtenemos la clave ssh de root. Ahora podemos copiarla en nuestro host de ataque, darle permisos 600 y ganar acceso como root para leer la flag:

Last updated