Titanic

Reconnaissance
Realizaremos un reconocimiento con nmap para ver los puertos que están expuestos en la máquina Titanic. Este resultado lo almacenaremos en un archivo llamado allPorts.
A través de la herramienta de extractPorts, la utilizaremos para extraer los puertos del archivo que nos generó el primer escaneo a través de Nmap. Esta herramienta nos copiará en la clipboard los puertos encontrados.
Lanzaremos scripts de reconocimiento sobre los puertos encontrados y lo exportaremos en formato oN y oX para posteriormente trabajar con ellos. En el resultado, comprobamos que se encuentran abierta una página web de Apache el servicio SSHhabilitado
Transformaremos el archivo generado targetedXML para transformar el XML en un archivo HTML para posteriormente montar un servidor web y visualizarlo.
Accederemos a http://localhost y verificaremos el resultado en un formato más cómodo para su análisis.

Añadiremos la siguiente entrada en nuestro archivo /etc/hosts.
Web Enumeration
Realizaremos una comprobación de las tecnologías que utiliza el sitio web.
Accedemos a http://titanic.htb y nos encontramos con la siguiente página web, con pocas páginas funcionales a excepción de una opción que veremos a continuación.

Al darle a la opción de Book Now se nos abre un pop-up en el cual nos permite ingresar nuestros datos. Proporcionaremos datos inventados y le daremos a Submit para ver cómo reacciona la aplicación web.

Al darle a dicha opción, se nos intenta descargar un archivo JSON.

Analizamos el archivo que se nos ha descargado y comprobamos que es unJSON con los datos que se le han asignado en el formulario antes de darle al botón.
Realizaremos la misma prueba, pero esta vez interceptándolo a través de BurpSuite para validar cómo se tramita la petición al servidor.
Verificamos que al intentar enviar la solicitud por POST, se nos habilita la opción de Follow Redirection y además, en la respuesta por parte del servidor se nos muestra la ruta dónde seremos redirigidos.

Al realizar la redirección, visualizamos la siguiente respuesta por parte nuestra y del servidor. Por lo que parece ser, cuando se nos descarga el JSON, hace la llamada a /download?ticket=.

Subdomain Enumeration
Realizamos una enumeración de subdominios de la aplicación web, finalmente logramos obtener el siguiente subdominio dev.titanic.htb.
Añadiremos esta nueva entrada en nuestro archivo /etc/hosts.
Realizaremos una enumeración básica para verificar las tecnologías que utiliza la aplicación web.
Al acceder a http://dev.titanic.htb nos encontramos con la siguiente página de Gitea.
Gitea permite la creación y gestión de repositorios basados en Git . También hace que la revisión de código sea increíblemente fácil y cómoda, mejorando la calidad del código para los usuarios y las empresas.

Al acceder a los repositorios públicos disponemos, nos encontramos con dos repositorios del usuario developer.

Accedemos al repositorio de developer/docker-config en el cual se muestran lo que parece ser archivos de configuración de los distintos contenedores que dispone la máquina Titanic.

Al acceder al archivo docker-compose.yml de docker-config/gitea, nos encontramos con el siguiente contenido.
En el cual se menciona que Gitea está montado en el volumen /home/developer/gite/data.

Al revisar el docker-compose.yml del repositorio docker-config/mysql logramos localizar las credenciales del usuario de la base de datos de MySQL. De momento estas credenciales no podemos utilizarlas.

Al acceder al otro repositorio llamado developer/flask.app, nos encontramos con el siguiente contenido. Revisando el README.md, parece ser que este repositorio es el de la página de http://titanic.htb, con lo cual, revisando su código fuente, quizás podríamos localizar alguna vulnerabilidad.

Dado que este repositorio dispone de más contenido que el resto, decidimos en descargarnos el repositorio en un comprimido para disponerlo localmente.

Descomprimiremos el archivo .zip y visualizamos la estructura del repositorio.
Al analizar los archivos JSON que se encontraban en tickets, no logramos visualizar contenido sensible ni nada, simplemente nombres de usuarios que quizás nos pudieran servir más adelante.
Analizaremos el archivo app.py que al parecer, parecer ser el archivo de la función donde en la página web nos descargaba el JSON a través del formulario.eeeeeeeeeeeeeeeeee
Initial Access
Path Traversal in the download_ticket function on a web site
Revisando posibles vulnerabilidades en el código del archivo app.py, nos encontramos que existe la posibilidad de realizar un Path Traversal. Esto debido al parámetro ticket que no se encuentra validado correctamente en la función download_ticket.

Probaremos de explotar dicha vulnerabilidad para listar el contenido del /etc/passwd del equipo objetivo. Logramos visualizar el contenido, con lo cual confirmamos que somos capaces de leer archivos arbitrarios del sistema vulnerable.
También logramos visualizar directamente la flag de user.txt
En este punto, intentamos enumerar varios archivos sin obtener resultado ninguno.
Recordando que Gitea se encontraba montado en el volumen /home/developer/gitea/data/, lo que pensamos es que en quizás dentro de este directorio hubiese algún archivo de configuración o base de datos que pudiéramos revisar.
Por lo tanto, revisamos la documentación de Gitea el cual nos menciona exactamente lo mismo.
Después de varias pruebas, logramos obtener el contenido del archivo de la base de datos de Gitea.
SQL Enumeration
Abriremos el archivo gitea.db para realizar una enumeración de las tablas, entre las cuales nos encontramos la tabla user.
Comprobamos el contenido de la tala user, en el cual se nos proporcionaban 2 usuarios de Gitea con sus credenciales en formato hash PBKDF2.
Revisaremos las columnas y el formato en el que se encuentran los datos.
Probamos de intentar crackear los hashes obtenidos, pero no obtuvimos resultado, esto debido que el hash no era válido como tal.
A través de sqlitebrowser, podemos verificar el contenido de la tabla user de manera más visual.

Cracking Gitea Hashes (PBKDF2)
Realizando una búsqueda por Internet de cómo intentar crackear el hash pbkdf2, nos encontramos con la siguiente página web en la cual 0xdf en una máquina de HTB al parecer realizó algo parecido.

Al acceder al contenido de ese writeup, nos encontramos del proceso que se realizó para crackear el hash de Gitea.

El formato que espera hashcat es el siguiente, el modo 10900.
A través del siguiente foro, se proporciona información de como intentar crackear estos hashes de Gitea de PBKDF2.

En este caso, hemos obtenido unos hashes de una base de datos de Gitea que utiliza el algoritmo PBKDF2 para la protección de contraseñas. El hash está compuesto por un digest y una sal (salt), y el campo passwd_hash_algo indica que se utiliza el esquema pbkdf2$50000$50, lo que sugiere que se aplican 50,000 rondas de iteración. Los valores de la sal y el digest están codificados en base64, lo cual facilita la manipulación con herramientas estándar para intentar crackear la contraseña.
Una vez obtenemos el hash, lo convertimos de base64 a su formato original en bytes utilizando el siguiente comando.
Esto nos permite obtener el formato adecuado para proceder con el cracking. Con el hash y la sal ya listos, utilizamos herramientas como hashcat o John the Ripper para intentar crackear el hash. El proceso puede ser bastante intensivo debido al alto número de rondas (50,000), pero es factible si se tiene el poder computacional necesario.
Para obtener un formato más adecuado para usar con herramientas como Hashcat, podemos modificar el proceso que seguimos anteriormente. En este caso, estamos obteniendo los valores de las contraseñas y las sales de la base de datos de Gitea, y luego formateamos la salida para que se ajuste al formato de Hashcat, que es username:sha256:iterations:salt:digest.
Este comando extrae cada campo passwd (contraseña), salt (sal) y name (nombre de usuario) de la base de datos de Gitea, los convierte de hexadecimal a binario, luego los codifica en base64, y finalmente organiza todo en el formato adecuado para Hashcat.
De esta forma, tenemos los datos listos para ser procesados por Hashcat o cualquier otra herramienta que utilice este formato. Este formato sigue el patrón de Hashcat, donde se indica el algoritmo de hash (sha256), el número de iteraciones (50000), la sal (salt) y el digest de la contraseña.
Con el formato correcto y la herramienta adecuada, como Hashcat, podemos proceder con el cracking de los hashes de Gitea. En este caso, estamos utilizando el modo de ataque -a 0 para un ataque de diccionario, y el tipo de hash -m 10900 para PBKDF2-SHA256.
Este comando hace lo siguiente:
-a 0: Modo de ataque de diccionario (ataque basado en un archivo de palabras, comorockyou.txt).-m 10900: Especifica el tipo de hash, que en este caso es PBKDF2 con SHA256 (esto es crucial porque le dice a Hashcat cómo manejar los hashes).gitea.hashes: El archivo que contiene los hashes en el formato correcto para Hashcat./usr/share/wordlists/rockyou.txt: El archivo de palabras (diccionario) que Hashcat utilizará para intentar crackear las contraseñas.--user: Este argumento se utiliza porque los hashes incluyen el nombre de usuario, lo que significa que Hashcat debe reconocerlo como parte de la entrada.
Finalmente logramos obtener la contraseña en texto plano del usuario developer.
Intentamos conectarnos mediante SSH con las credenciales del usuariodeveloper. Logramos obtener acceso al equipo y visualizar la flag de user.txt.
Privilege Escalation
Basic Enumeration
Realizaremos una enumeración básica para comprobar si disponemos de privilegios en algún grupo o de algún permiso sudoers, en este caso, no obtuvimos resultado.
Por lo tanto, para realizar una enumeración inicial para escalar nuestros privilegios, decidimos usar linpeas.sh el cual compartiremos a través de un servidor web.
Desde el equipo comprometido, nos descargaremos el script y le daremos los permisos de ejecución correspondientes.
Después del análisis, verificamos que nos marca posible PrivEsc mediante un Path. Realizamos algunas pruebas intentando escalar privilegios mediante lo que se nos indicaba pero no obtuvimos resultado.

Analyzing Root Script
Enumerando el directorio /opt, nos encontramos con un script llamado identify_images.sh que se encontraba en /opt/scripts.
Este script se encarga de generar un informe sobre las imágenes JPEG presentes en el directorio /opt/app/static/assets/images. A continuación te detallo lo que hace cada parte del script para que lo puedas incluir en el write-up:
cd /opt/app/static/assets/images: Cambia al directorio donde se encuentran las imágenes JPEG.truncate -s 0 metadata.log: Vacía (o crea si no existe) el archivometadata.log, dejándolo con un tamaño de 0 bytes. Esto se hace para asegurarse de que el archivo esté vacío antes de generar nuevos datos.find /opt/app/static/assets/images/ -type f -name "*.jpg": Busca todos los archivos con la extensión.jpgdentro del directorio/opt/app/static/assets/images/y sus subdirectorios.| xargs /usr/bin/magick identify: Usa la salida del comandofind(una lista de archivos.jpg) y pasa cada archivo como argumento al comandomagick identify, que es una herramienta de ImageMagick para obtener metadatos de las imágenes (como tamaño, tipo de archivo, resolución, etc.).>> metadata.log: Redirige la salida del comandomagick identifyal archivometadata.log, agregando la información de las imágenes al final del archivo, de manera que se acumule la metadata de todas las imágenes encontradas.
En resumen, este script busca todas las imágenes JPEG en un directorio específico, obtiene sus metadatos usando magick identify y los guarda en un archivo de registro (metadata.log). Esto puede ser útil para examinar detalles como la resolución, los perfiles de color o posibles metadatos adicionales que las imágenes puedan contener.
Accedimos al directorio /opt/app/static/assets/images y verificamos si teníamos capacidad de escritura copiando una imagen de las que ya había en el repositorio.
Verificamos que logramos copiar la imagen, con lo cual confirmamos de los permisos de escritura en dicho directorio.
ImageMagick 7.1.1-35 Exploitation - Arbitraty Code Execution (CVE-2024-41817)
Volviendo a analizar el script identify_images.sh, nos dimos cuenta de que utilizaba la herramienta de magick. Revisamos que el binario se encontraba instalado y utilizaba la versión 7.1.1-35.
ImageMagick es un complemento de software para crear, editar, componer o convertir imágenes de mapa de bits. Puede leer y escribir imágenes en varios formatos (más de 200), incluidos PNG, JPEG, JPEG-2000, GIF, TIFF, DPX, EXR, WebP, Postscript, PDF y SVG.14 jul 2024
Revisando posibles vulnerabilidades de esta versión de Magick, nos encontramos con el siguiente CVE-2024-41817.

ImageMagick es un paquete de software libre y de código abierto que se utiliza para editar y manipular imágenes digitales. La versión AppImage ImageMagick podría utilizar una ruta vacía al configurar las variables de entorno MAGICK_CONFIGURE_PATH y LD_LIBRARY_PATH durante la ejecución, lo que podría provocar la ejecución de código arbitrario al cargar archivos de configuración maliciosos o bibliotecas compartidas en el directorio de trabajo actual mientras se ejecuta ImageMagick. La vulnerabilidad se corrigió en 7.11-36.
En el siguiente repositorio de GitHub, se nos proporcionaba un PoC de cómo explotar esta vulnerabilidad.

Decidimos realizar una prueba para verificar si la versión de Magick instalada en el equipo era vulnerable. Para ello, inyectamos un código que ejecutaba el comando id, lo cual, al compilarlo, creaba un archivo libxcb.so.1 en el directorio donde se ejecutaba el código. Al ejecutar magick, observamos que se mostraba la ejecución del comando realizado y, además, el archivo libxcb.so.1 se eliminaba.
Con esta prueba, nos surgió la idea de realizar un payload malicioso en el directorio /opt/app/static/assets/images. Suponiendo que el usuario root tuviera alguna tarea programada que detectara la llegada de un nuevo archivo .jpg en dicho directorio (lo cual es posible si copiamos un archivo previamente creado ya que tenemos permisos de escritura), si se ejecutara el script correspondiente, el sistema podría cargar nuestro archivo malicioso libxcb.so.1. Esto podría permitirnos ejecutar comandos como usuario root, ya que el magick invocado en el script cargaría nuestro payload.
Realizamos el siguiente payload, el cual copiaba el contenido de root.txt en /tmp/root.txt. Luego, copiamos un archivo de imagen para simular la detección de un nuevo .jpg en el directorio.
Tras listar los archivos, notamos que libxcb.so.1 desapareció del directorio, lo que indica que fue cargado y eliminado tras su ejecución. Finalmente, verificamos en /tmp y confirmamos que root.txt había sido copiado con éxito.
Esto sugiere que el usuario root, al detectar la presencia de un nuevo .jpg (el que copiamos), ejecutó el script que contenía magick vulnerable, lo que permitió la ejecución de nuestro payload malicioso con privilegios elevados.
Shell as root
Una vez confirmado que podemos ejecutar código arbitrario como root a través de ImageMagick, podemos aprovechar esta vulnerabilidad para obtener una shell interactiva. La estrategia es copiar nuestra clave pública SSH al archivo /root/.ssh/authorized_keys, lo que nos permitirá autenticarnos como root sin necesidad de conocer su contraseña.
Para ello, primero generaremos en nuestro equipo una clave pública.
Copiaremos el contenido de nuestra clave pública SSH.
El payload que usaremos reemplazará el contenido de authorized_keys con nuestra clave pública. Ejecutamos la misma técnica que utilizamos anteriormente para cargar la biblioteca maliciosa y activamos la vulnerabilidad.
Probaremos de acceder con el usuario root a través de SSH y verificamos que no requiere de credenciales debido que disponemos de nuestra clave pública en el archivo /root/.ssh/authorized_keys. Finalmente, logramos obtener la flag de root.txt.
Última actualización
¿Te fue útil?