Facts Writeup - HackTheBox
Last updated June 16, 2026 • 2 min read
Discovery
PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 54321/tcp open unknown
Adding facts.htb to /etc/hosts based on the redirect from port 80, then running service detection:
22/tcp open ssh OpenSSH 9.9p1 Ubuntu 3ubuntu3.2 80/tcp open http nginx 1.26.3 (Ubuntu) |_http-title: Did not follow redirect to http://facts.htb/ 54321/tcp open http Golang net/http server |_http-server-header: MinIO
Port 54321 identifies as MinIO — a self-hosted S3-compatible object storage server. The XML error responses confirm the S3 API behavior. Port 80 redirects to facts.htb.
The site is a facts/trivia CMS. Page source reveals camaleon_cms in an OG image path. VHost enumeration returns nothing useful. The attack surface is: the CMS on port 80 and the MinIO API on port 54321.
Initial Access
Camaleon CMS — File Read and Admin Takeover (CVE-2024-46987)
Registration is open at http://facts.htb/admin/register. After creating an account, CVE-2024-46987 provides arbitrary file read for authenticated users. The exploit from github.com/Goultarde/CVE-2024-46987 handles authentication and the path traversal automatically.
[*] Récupération du token sur http://facts.htb/admin/login [*] Authentification réussie. root:x:0:0:root:/root:/bin/bash <snip> trivia:x:1000:1000:facts.htb:/home/trivia:/bin/bash william:x:1001:1001::/home/william:/bin/bash <snip>
Two non-root login shells: trivia and william. Reading /root/root.txt returns HTTP 500 — root isn't reachable directly via this vector.
The same CVE release includes a separate privilege escalation within the CMS itself — a CSRF-based account takeover that promotes a registered user to admin by submitting a crafted password change request targeting a privileged user's profile:
[+] Login successful [i] Version detected: 2.9.0 (< 2.9.1) - appears to be vulnerable version [+] authenticity_token: hl5NCx3zaGccGsrK1wcad6... [+] Submit successful, you should be admin
MinIO Credential Extraction
Navigating to the admin panel at http://facts.htb/admin/settings/site exposes the S3 backend configuration in plaintext:
Aws s3 access key: $MINIO_ACCESS_KEY
Aws s3 secret key: $MINIO_SECRET_KEY
Aws s3 bucket name: randomfacts
Aws s3 region: us-east-1
Aws s3 bucket endpoint: http://localhost:54321
Configuring the AWS CLI against the MinIO endpoint:
2025-09-11 14:06:52 internal 2025-09-11 14:06:52 randomfacts
Two buckets. randomfacts holds the CMS media files. internal is unexpected:
PRE .bundle/
PRE .cache/
PRE .ssh/
2026-01-08 19:45:13 220 .bash_logout
2026-01-08 19:45:13 3900 .bashrc
2026-01-08 19:47:17 807 .profile
This is a user's home directory synced to S3. The .ssh/ prefix means there's a keypair inside. Syncing the entire bucket locally:
download: s3://internal/.ssh/authorized_keys to .ssh/authorized_keys download: s3://internal/.ssh/id_ed25519 to .ssh/id_ed25519
SSH Key Cracking
The private key is passphrase-protected:
dragonballz (id_ed25519) 1g 0:00:00:52 DONE
Strip the passphrase and connect as trivia — the user whose home directory was exposed in the internal bucket:
trivia@facts:~$
Privilege Escalation
User trivia may run the following commands on facts:
(ALL) NOPASSWD: /usr/bin/facter
facter is a Ruby-based system facts tool. It supports loading custom fact definitions via --custom-dir, and those definitions are executed as Ruby code. With sudo, custom Ruby runs as root.
Creating the payload in the home directory:
root@facts:/home/trivia#
facter loads every .rb file in the custom directory before processing the requested fact. The script checks euid == 0 to confirm it's running with root privileges, then execs a root bash session.
References
-
Camaleon CMS 2.9.0 arbitrary file read
-
www.exploit-db.comwww.exploit-db.com/exploits/51734 (opens in new tab)
MinIO admin API reconnaissance
-
gtfobins.github.iogtfobins.github.io/gtfobins/facter (opens in new tab)
facter sudo privilege escalation
-
MinIO server documentation