HTB: Silentium

Note

I put this writeup in my security research section, thats just for convince. Later on I will create a section for all my writeups to come.

Overview

AttributeValue
OSLinux
DifficultyEasy
CategoryWeb + Privilege Escalation
Key CVEsCVE-2026-40933, CVE-2025-8110
TechniquesAuth Bypass, MCP RCE, Symlink
Abuse, Git Hooks

Silentium is a two-stage exploitation box combining web application authentication weaknesses with a privilege escalation chain through Git hook manipulation. The path to user involves bypassing Flowise authentication and exploiting an MCP (Model Context Protocol) server vulnerability. Root escalation leverages Gogs repository management running with elevated privileges.

Reconnaissance

Port & Service Discovery

A straightforward nmap scan reveals two services:

  • SSH (22/tcp) — OpenSSH 9.6p1 on Ubuntu
  • HTTP (80/tcp) — nginx serving the Silentium corporate site

The HTTP response redirects to silentium.htb, requiring local DNS resolution or /etc/hosts entry.

Key observation: The main site exposes team member names (Marcus Thorne, Ben, Elena Rossi), which become useful for credential testing later.

Virtual Host Enumeration

Standard vhost scanning (gobuster or ffuf) against silentium.htb uncovers:

  • staging.silentium.htb (200 OK, ~3KB response)

This staging environment hosts a different application (Flowise) and becomes the primary attack surface.

Foothold: Flowise Authentication Bypass

Phase 1: Identify the Vulnerability

The staging vhost presents a login page for Flowise, a visual LLM application builder. Rather than brute-forcing credentials, examine the password reset functionality.

Flowise’s password reset endpoint is a known attack vector. The implementation leaks sensitive information in the response, including:

  • Temporary password reset tokens
  • User metadata (ID, email, internal names, credential hashes)

Send a POST to /api/v1/account/forgot-password with a target email (e.g., ben@silentium.htb, whose name appeared on the public site). The response includes a tempToken field.

Phase 2: Exploit the Leaked Token

The tempToken can be used to reset the password without validating proper ownership. Use this token to establish authenticated API access to Flowise.

This grants access to the Flowise canvas (chatflow builder) and triggers the secondary vulnerability.

Phase 3: MCP RCE Exploitation

Flowise supports Custom MCP (Model Context Protocol) server nodes. The vulnerability lies in how it handles the MCP server configuration.

The key insight: MCP configurations accept a command and args field. When the Flowise backend attempts to instantiate the MCP server, it executes the command via subprocess without sufficient input validation.

Configure a Custom MCP node with a malicious payload:

  • command: npx
  • args: Point to a URL that serves a package.json designed to execute arbitrary code

Trigger the MCP instantiation (either via the UI or by re-submitting the API request through Burp). A reverse shell callback is delivered to your listener.

Result: User-level access inside a Docker container running the Flowise application.

Accessing Host Credentials

Inside the container, environment variables expose:

  • FLOWISE_USERNAME and FLOWISE_PASSWORD
  • Additional credentials (SMTP, JWT secrets)

More importantly, check /root/.flowise and related paths for database or configuration files that might contain host-level credentials.

One specific credential pair from the environment can be used for SSH authentication to the host system.

Result: SSH access as ben user. User flag obtained.

Privilege Escalation: Gogs Git Hook Manipulation

Discovery

Post-enumeration reveals a Gogs installation in /opt, running as root. Gogs is a lightweight Git service, and the root privilege here is significant.

The attack surface: Git repositories have hooks (pre-receive, post-receive, update) that execute arbitrary scripts during push events. If we can manipulate a hook, and the service runs as root, we achieve RCE as root.

Vulnerability Overview

CVE-2025-8110 (referenced as CVE-2024-39930 in some sources) exploits a symlink race condition combined with Git hook handling in Gogs.

The attack chain:

  1. Create an empty Git repository via the Gogs API
  2. Push a symlink (named evil_link) pointing to the location of a Git hook (e.g., .git/hooks/pre-receive)
  3. Use the Gogs API to overwrite the symlink target with malicious script content
  4. Trigger the hook by pushing new commits to the repository

Exploitation Steps

  1. Authentication: Obtain Gogs API credentials (attacker account, or brute-force if available)

  2. Create Empty Repository: Use the Gogs API endpoint /api/v1/user/repos with auto_init: false to create a repository without automatic initialization. This leaves the hooks directory manipulable.

  3. Push Symlink:

    • Initialize a local Git repository
    • Add the target Gogs repo as remote
    • Create a symlink named evil_link pointing to .git/hooks/pre-receive
    • Commit and push to the empty repo
    • Retrieve the SHA of the symlink object
  4. Overwrite via API:

    • Use /api/v1/repos/{user}/{repo}/contents/evil_link endpoint (PUT)
    • Provide base64-encoded malicious script as the content
    • The API treats the symlink as a file and overwrites its content
  5. Trigger Execution:

    • Make a final push (any content change)
    • The pre-receive hook (now containing your malicious code) is executed as root
    • Payload options: reverse shell or SUID binary creation

Result: RCE as root. Root flag obtained.

Key Technical Details

  • The vulnerability relies on Gogs not properly validating symlink targets in its API file editor
  • The hooks directory permissions allow the unprivileged Git user to indirectly execute code as root
  • The force push (-f) is necessary because the local repo history does not match the remote state

Detection & Lessons Learned

What Went Wrong (Defense Perspective)

  1. Flowise Auth Bypass: Password reset endpoints should:

    • Verify email ownership via token sent to registered address
    • Not leak tokens or user metadata in response bodies
    • Implement rate limiting and token expiration
  2. MCP RCE: Custom tool execution should:

    • Sandbox subprocess calls (chroot, seccomp, containers)
    • Implement an allow-list for commands
    • Validate URLs/sources before execution
  3. Gogs Hook Manipulation:

    • Disable symlink writes via API in file editor
    • Validate hook target paths; prevent traversal outside /hooks/
    • Run Git hooks with minimal privilege (not as root)

Mitigations for Similar Environments

  • Implement centralized authentication (OAuth2, SAML) to bypass application-level auth flaws
  • Use container security scanning (Trivy, Grype) to identify vulnerable dependencies
  • Enforce privilege separation: never run SCM services as root
  • Apply code review to API endpoints handling sensitive operations

Tools & References

CVEs Referenced

Tools Used

  • ffuf / gobuster (vhost enumeration)
  • Burp Suite (request inspection & modification)
  • Git (local repo initialization & pushing)
  • netcat (reverse shell listener)

Detection Resources

Timeline

StageMethodResult
Reconnmap, vhost scanningstaging vhost
Authforgot-password token leakAPI access
FootholdMCP RCE via Custom nodeContainer shell
HostEnv var credentials + SSHben user access
PrivEscGogs symlink + hook overwriteroot access

Appendix: Manual Exploitation (No PoC Script)

If running the Gogs exploit manually:

# 1. Create local test repo
mkdir /tmp/gogs_test && cd /tmp/gogs_test
git init
git remote add origin \
  http://attacker:password@gogs.target/attacker/test_repo.git

# 2. Create symlink to target hook
ln -s /root/gogs-repositories/attacker/test_repo.git/hooks/pre-receive \
  evil_link

# 3. Commit & push
git add .
git commit -m "init"
git push -u origin master

# 4. Retrieve symlink SHA
# Use Gogs API: GET /api/v1/repos/attacker/test_repo/contents?ref=master

# 5. Overwrite with malicious payload
# Use Gogs API: PUT /api/v1/repos/attacker/test_repo/contents/evil_link
# Payload: {"message":"update", "content":"BASE64_ENCODED_SCRIPT",
#           "sha":"...", "branch":"master"}

# 6. Trigger by pushing a new file
touch dummy && git add dummy && git commit -m "trigger"
git push -f origin master

Note: This writeup avoids direct flag values. It assumes the reader understands basic Linux/Git concepts and has a testable environment.