HackTheBox - Facts
Writeup de la máquina Facts de HackTheBox
Dificultad
easyTiempo aprox.
~2.5hDatos 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.htba/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é eraHeaders 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 relevantesrobots: robots.txt, solo apuntaba asitemapadmin, que redirige aadmin/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-2304.
Este CVE tiene varios PoC públicos, uno de ellos 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
awsconvierte los parámetros que se le pasan por la terminal en una solicitud HTTP con el formato del API S3.awsnormalmente 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 crowbar 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