Editorial

Publicado: 06 de Junio de 2025 Autor: Josรฉ Miguel Romero aKa x3m1Sec Dificultad: โญ Easy
๐ Descripciรณn
Editorial es una mรกquina Linux de dificultad Easy de HackTheBox que simula un sitio web editorial donde se pueden publicar libros. La mรกquina presenta vulnerabilidades de SSRF (Server-Side Request Forgery) que permiten enumerar servicios internos, exposiciรณn de credenciales a travรฉs de una API interna, filtraciรณn de informaciรณn sensible en repositorios Git, y escalada de privilegios mediante un script Python vulnerable que utiliza GitPython de forma insegura.
El vector de ataque principal comienza con la explotaciรณn de SSRF para descubrir servicios internos, seguido de la obtenciรณn de credenciales a travรฉs de una API expuesta, movimiento lateral usando credenciales encontradas en el historial de Git, y finalmente escalada de privilegios aprovechando una configuraciรณn insegura de Git que permite ejecuciรณn de comandos arbitrarios.
๐ฏ Resumen de Vulnerabilidades
SSRF (Server-Side Request Forgery) - Puerto 80
Exposiciรณn de API interna - Puerto 5000
Credenciales hardcodeadas en respuestas de API
Filtraciรณn de credenciales en historial de Git
Ejecuciรณn de comandos via Git remote-ext protocol
Configuraciรณn insegura de GitPython
๐ญ 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
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 / TCP - editorial.htb

Revisando el contenido del sitio web encontramos otro dominio que aรฑadimos al scope por si pudiese revelar algo.

๐ท๏ธFuzzing de directorios y vhosts
Tras probar a realizar fuzzing con diversas herramientas como dirsearch, gobuster y feroxbuster, no encontramos ningรบn recurso que aรฑadir a nuestro scope que pueda ser de utilidad ni tampoco ningรบn subdominio para editorial.htb ni tiempoarriba.htb.
๐ Anรกlisis de la secciรณn "Publish with us"
Vemos una funciรณn de carga de achivos que a priori no filtra por la extensiรณn. Probamos a subir una web shell en php incrustada en una imagen e interceptamos la peticiรณn con burp:

Observamos que existen dos parรกmetros en el formulario (bookfile y bookurl), Obtenemos en la respuesta la URL donde ha quedado alojado el archivo:
Pero al tratar de acceder, parece que no se estรก ejecutando PHP en el sistema, ya que lo que hace es รบnicamente descargar el archivo:
๐ฏ Explotaciรณn - SSRF (Server-Side Request Forgery)
Cambiamos de estrategia y verificamos si podemos abusar del parรกmetro bookurl para explotar un SSRF. Para comprobar esto, hacemos una pequeรฑa PoC, iniciamos en nuestro host de ataque un servidor web con python:
En la solicitud, aรฑadimos la ip de nuestro host de ataque:

Recibimos la peticiรณn en nuestro servidor con un 200:

๐ Enumeraciรณn de puertos internos
Aprovechando la vulnerabilidad SSRF, verificamos si hay otros puertos o servicios ejecutรกndose internamente en la mรกquina:
Guardamos la solicitud desde Burp indicando con la palabra
FUZZdonde queremos realizar el fuzzingUtilizamos ffuf para realizar el ataque pasando como payload una lista numรฉrica de 0 a 65535:

Y ahora con la herramienta ffuff realizar el ataque pasando como payload una lista numรฉrica de 0 a 65535 que es el nรบmero posible de puertos:

Obtenemos una รบnica respuesta en el puerto 5000.
๐ Acceso a API interna - Puerto 5000
Realizamos una peticiรณn SSRF al puerto 5000 interno y descargamos la respuesta: Hacemos ahora una peticiรณn a ese puerto para ver quรฉ nos devuelve:

Descargamos el enlace de la respuesta:

Descubrimiento crรญtico: El servicio interno expone una API que revela mรบltiples endpoints:
Leemos el contenido del fichero y vemos que parece que se trata de un JSON:

Usamos jq para obtener un mejor formato de salida:
๐ Obtenciรณn de credenciales

Probamos todos los endpoints descubiertos y encontramos que /api/latest/metadata/messages/authors responde con informaciรณn sensible:
ยกCredenciales obtenidas!
Usuario:
devContraseรฑa:
dev080217_devAPI!@
Obtenemos un usuario y una contraseรฑa. Dado que disponemos de un servicio ssh en el puerto 22, merece la pena probar estas credenciales para ver si logramos ganar acceso a la mรกquina para obtener la primera flag en el directorio del usuario dev:
๐ Movimiento lateral: dev โ prod
Encontramos una carpeta llamada apps en el directorio del usuario /dev que vemos que contiene un repositorio git
El comando git statusmuestra todos los archivos que estaban presentes en la รบltima confirmaciรณn que ya no estรกn allรญ, por lo que se muestran como eliminados:

๐ Anรกlisis del historial Git
Examinamos el historial de commits para buscar informaciรณn sensible:
Anรกlisis de diferencias entre commits:
Podemos ver diferencias de cambios entre varios commits con el siguiente comando:

ยกCredenciales encontradas! Al comparar commits, descubrimos que se subieron credenciales del usuario de producciรณn que posteriormente fueron eliminadas:
Usuario:
prodContraseรฑa:
080217_Producti0n_2023!@
โฌ๏ธ Escalada de privilegios: prod โ root
๐ Enumeraciรณn de permisos sudo
Verificamos si el usuario prod puede ejecutar algo como root:
Verificamos los permisos que tiene el usuario prod sobre este script y vemos que puede leerlo y ejecutarlo:
Revisamos el contenido del script para analizarlo:
๐จ Identificaciรณn de la vulnerabilidad
Vulnerabilidades encontradas:
Falta de sanitizaciรณn del input del usuario (
url_to_clone)Configuraciรณn peligrosa:
protocol.ext.allow=alwayshabilitadoEjecuciรณn con privilegios root via sudo
Uso de git-remote-ext que permite ejecuciรณn de comandos locales
El protocolo ext:: de Git permite ejecutar comandos como si fueran servidores remotos, y la configuraciรณn protocol.ext.allow=always elimina todas las restricciones de seguridad.
๐ฅ Explotaciรณn
Paso 1: Creamos un script malicioso que se ejecutarรก como root:
Paso 2: Ejecutar el script con git-remote-ext.Esto funciona porque ext::<cmd> hace que Git ejecute el comando como un "servidor remoto", y con protocol.ext.allow=always, no hay restricciones.
Paso 3: , usamos la shell con SUID para escalar a root:

Last updated