githubEditar

HackTheBox - Facts

Writeup de la máquina Facts de HackTheBox

  • Dificultad easy

  • Tiempo aprox. ~2.5h

  • Datos Iniciales: 10.129.1.12

Nmap Scan

Tras realizar un escaneo nmap completo, se encuentran los siguientes puertos abiertos:

PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 9.9p1 Ubuntu 3ubuntu3.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 4d:d7:b2:8c:d4:df:57:9c:a4:2f:df:c6:e3:01:29:89 (ECDSA)
|_  256 a3:ad:6b:2f:4a:bf:6f:48:ac:81:b9:45:3f:de:fb:87 (ED25519)
80/tcp    open  http    nginx 1.26.3 (Ubuntu)
|_http-server-header: nginx/1.26.3 (Ubuntu)
|_http-title: Did not follow redirect to http://facts.htb/
54321/tcp open  http    Golang net/http server
|_http-title: Did not follow redirect to http://10.129.1.12:9001
...

Añadimos facts.htb a /etc/hosts

  • TCP/22: SSH, versión no vulnerable.

  • TCP/80: HTTP, el potencial vector de entrada

  • TCP/54321: Servidor golang? Redirige a 10.129.1.12:9001

Puerto 54321

Antes de entrar al servidor web del puerto 80, probamos a ver qué hay en el 54321.

Si nos fijamos en el análisis de nmap, veremos lo siguiente:

De aquí podemos sacar la siguiente información:

  • Servidor MinIO. En su momento no sabía qué era

  • Headers HTTP "Amz", posiblemente relacionado con Amazon?

  • Respuesta del server al test de nmap: InvalidRequest, posiblemente necesite otro tipo o sintaxis de solicitud.

Tras una búsqueda, encuentro info relevante sobre MinIO, S3 y los buckets:

S3 (Simple Storage Service) es un sistema de almacenamiento de objetos pensado para guardar datos no estructurados (imágenes, backups, logs, etc.) de forma duradera, segura y altamente disponible. La API de S3 permite gestionar buckets, objetos, ACLs, metadatos, etc.

Un bucket es un "directorio" de alto nivel, el contenedor raíz donde se almacenan los objetos. Un objeto en S3 es un archivo más sus metadatos. En un bucket NO hay subdirectorios, tiene una estructura plana, las rutas en las que están los objetos forman parte de la propia clave que define al objeto. "2026/enero/database.db.bak" es en sí el nombre (clave) del archivo "2026/enero/database.db.bak", no hay un directorio "2026" ni otro "enero" dentro de este.

Dado que la API S3 de AWS se lanzó tempranamente (2006) y es muy simple y escalable, la industria la ha adoptado como estándar de facto, p.ej en Google Cloud, Azure, y en software open source como MinIO.

Finalmente, MinIO es un servidor de almacenamiento de objetos open-source compatible con la API de S3. La principal diferencia es que AWS S3 es gestionado por Amazon en una nube pública, mientras que MinIO puede instalarse en servidores privados como servicio, aunque funciona de forma idéntica.

De momento, como más allá de la teoría no sé enumerar buckets S3, paso al puerto 80.

Puerto 80, nginx

Al entrar, nos encontramos un blog en el que el administrador sube datos curiosos:

Planteo varias opciones:

  • SQLi en campo de búsqueda -> No vulnerable

  • XSS en campo de búsqueda -> No vulnerable

  • XSS en comentarios -> No se pueden comentar posts

Así que decido hacer fuzzing de directorios:

De aquí destacan varias cosas:

  • sitemap: posible mapa del contenido del servidor. Al final no hay muchas cosas relevantes

  • robots: robots.txt, solo apuntaba a sitemap

  • admin, que redirige a admin/login, entramos a ver.

En http://facts.htb/admin/login vemos lo siguiente:

Aprovechando que podemos crear una cuenta, la creamos. Desde el panel de admin vemos que se está usando Camaleon CMS v2.9.0. Tras una búsqueda rápida encontramos que esta versión es vulnerable a CVE-2025-2304arrow-up-right.

Este CVE tiene varios PoC públicos, uno de ellosarrow-up-right listando que además puede conseguir un S3 Config Leak, relacionado directamente con el server MinIO visto antes.

Buscando una visión general ahora, podemos deducir que, dado que CamaleonCMS es (casualmente) un CMS (que sirve contenido), es muy probable que los archivos e imágenes que sirve o los datos del backend (usuarios, contraseñas, etc.) estén almacenados en el servidor MinIO.

Haciendo uso del PoC:

Puerto 54321, MinIO

Ahora que tenemos las claves, podemos usar la herramienta de cli aws y conectarnos al server MinIO. Primero creamos un perfil que almacena las credenciales y configuraciones:

La herramienta aws convierte los parámetros que se le pasan por la terminal en una solicitud HTTP con el formato del API S3. aws normalmente se usaría con servidores de AWS reales, pero como la API S3 funciona con MinIO también, podemos usar la herramienta indistintamente en ambos.

Ahora, usando el perfil, listamos buckets:

Aunque es bastante probable que lo interesante esté en el bucket internal, vamos primero a randomfacts por si hay algo:

Como imaginábamos, no hay nada relevante, vamos a internal:

Tras ordenar todo un poco, tenemos los siguientes archivos disponibles:

Y estamos a nada de poder entrar, tenemos una clave privada de SSH: id_ed25519. La descargamos:

Clave Privada SSH

Tenemos la clave privada, solo necesitamos saber el nombre de usuario. Puede estar en muchos sitios, así que vamos enumerando el bucket.

Tras un rato mirando, veo que no hay comentarios en las claves ni en authorized_keys, que no hay una ruta (p.ej /home/...) especificada en el .bashrc y que no hay nada que contenga home, user, passwd o config útil en el bucket.

Dedido usar crowbararrow-up-right para hacer "sshkey-spraying" contra una serie de usuarios.

Tras un rato probando con más wordlists, empiezo a plantearme si verdaderamente la clave privada que tengo corresponde a la pública que aparece en authorized_keys, así que intento sacar la pública a partir de la privada:

Necesitamos contraseña, probamos a ver si coinciden el fingerprint de la clave privada y el de la de authorized_keys:

El de la privada es CaxvNj...[SNIP]...VQ5Kw

El de la pública es CaxvNj...[SNIP]...VQ5Kw, así que sí, la clave privada tiene que funcionar para algún usuario (si el authorized_keys está en uso en algún sitio realmente).

Crackeando contraseña

Al haber confirmado que al menos la clave privada nos va a ser útil y corresponde a la pública de authorized_keys, probamos a conseguir la contraseña que la cifraba (porque igual se reutiliza en algún sitio).

Una vez tenemos la contraseña dragonballz:

Tenemos el usuario: trivia.

Conexión inicial por SSH

Nos conectamos por ssh:

PrivEsc

Inmediatamente al entrar comprobamos permisos sudo:

Tras mirar, resulta que facter es un programa que permite recolectar y ver datos del sistema. Al mirar el manpage veo varias opciones curiosas como --debug, y todo me apunta a que hay que hacer que facter "escupa" todo a pantalla para que se abra el paginador (p.ej less) y desde ahí podamos abrir un shell (como en Devvortex), pero, desgraciadamente, no es el caso.

De todas formas, podemos crear un archivo .rb que engañe a facter haciéndole creer que es una función para calcular un dato nuevo, cuando en realidad es un shell:

Y somos root.

Última actualización