Silentium
(To be completed) (To be completed) (To be completed) (To be
Scenario
Silentium attack path
(To be completed) (To be completed) (To be completed) (To be
Objective
Machine walkthrough focused on Machines evidence, validation, and reusable operator lessons.
Walkthrough flow
Port scan: 22 (SSH), 80 (nginx) -- only two ports open
HTTP redirects to silentium.htb
Vhost fuzz: staging.silentium.htb (Flowise 3.0.5)
: credential reset session material leaked via POST...
API Key auth: Bearer session material...
Source coverage
High source coverage
Status: complete. This article is generated from 5 sanitized Markdown sources and keeps raw flags, credentials, keys, cookies, and reusable secrets out of the rendered blog.
High confidence: the page is reconstructed from a primary walkthrough plus multiple supporting notes or evidence sources. Treat the chain as source-backed, while still checking the listed source files for sensitive values.
- <TARGET>-Silentium/walkthrough.md
- HTB/<TARGET>-Silentium/notes.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/machine__<TARGET>-Silentium__notes.md.0b4bc85710.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/machine__<TARGET>-Silentium__session-resume.md.053b08d15b.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/machine__<TARGET>-Silentium__notes.md.6af1f5972a.md
Technical Walkthrough
Silentium - Walkthrough
Machine Info
- Target: <TARGET>
- OS: Linux
- Difficulty: Easy
Attack Chain Summary
(To be completed)
Phase 1: Reconnaissance
(To be completed)
Phase 2: Foothold
(To be completed)
Phase 3: User Flag
(To be completed)
Phase 4: Privilege Escalation
(To be completed)
Phase 5: Root Flag
(To be completed)
Lessons Learned
(To be completed)
Source-Backed Dossier
The sections below are merged from companion Markdown notes for the same case. They are rendered after sanitization so the article stays precise without publishing raw flags, credentials, or target-specific secrets.
Notes
Scope
- Target: <TARGET> (Silentium)
- OS: Linux
- Difficulty: Easy
- Pwnbox: <TARGET> (profex0r)
- Attacker VPN IP: <TARGET>
- Domain hypothesis: silentium.htb
- Started: 2026-05-06
Credentials Found
- Flowise User: <email redacted> (admin role)
- Flowise Basic Auth (env vars): ben:F1l3_d0ck3r
- Flowise API Key: hWp_8jB76zi0VtKSr2d9TfGK1fm6NuNPg1uA-8FsUJc
- API Key Secret: <redacted>
- User bcrypt hash (current, unknown pw): $2a$05$CMpktMTSWWt7mEOtWnx9h.hneP3dIXD/Ujnb9TBQzaiSXZKT5LHTi (cost=5)
- User bcrypt hash (original): $2a$05$6o1ngPjXiRj.EbTK33PhyuzNBn2CLo8.b0lyys3Uht9Bfuos2pWhG (cost=5)
- Docker container hostname: c78c3cceb7ba
- Docker host IP: <TARGET>
- Encryption key path: /root/.flowise/encryption.key
- Database path: /root/.flowise/database.sqlite
Environment Variables (from container)
<secret redacted>=ben
<secret redacted>=<redacted>
<secret redacted>=/root/.flowise
PORT=3000
HOME=/root
HOSTNAME=c78c3cceb7ba
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
<secret redacted>=<redacted>
<secret redacted>=<redacted> SET (uses machine-id derived key)Attack Chain
- Port scan: 22 (SSH), 80 (nginx) -- only two ports open
- HTTP redirects to silentium.htb
- Vhost fuzz: staging.silentium.htb (Flowise 3.0.5)
- <secret redacted>: Password reset token leaked via POST /api/v1/account/forgot-password
- API Key auth: Bearer token
hWp_8jB76zi0VtKSr2d9TfGK1fm6NuNPg1uA-8FsUJcgrants access to management APIs - RCE via Chatflow Prediction (Session 2 breakthrough):
- Create CHATFLOW with customFunction node (version 3, with inputParams array)
- Output set to "EndingNode"
- POST to /api/v1/internal-prediction/{chatflowId} with API key auth
- JS executes in NodeVM sandbox
- require("flowise-components/dist/src/utils").getEnvironmentVariable() reads real env vars
- require("typeorm").DataSource gives full SQLite database access
- require("axios") / require("node-fetch") / require("http") / require("net") for network access
Key Findings from Container RCE
Database Access (TypeORM DataSource)
- Tables: migrations, chat_message, user, organization, role, workspace, apikey, chat_flow, tool, credential, variable, login_sessions, login_activity, etc.
- User table: only 1 user (<email redacted>)
- Credential table: EMPTY
- Variable table: EMPTY
- Login sessions: many valid sessions exist (passport session cookies)
Network Scan from Container
- Docker host <TARGET>: Only ports 22 (SSH) and 80 (nginx) open
- Ports 3000, 5432, 3306, 6379, 8080, etc. all CLOSED on Docker host
- Container localhost: Only port 3000 (Flowise itself)
- Docker socket: NOT mounted (/var/run/docker.sock absent)
Auth Architecture
- Basic auth header (Authorization: Basic) ALWAYS returns 401
- Even with correct env var creds ben:F1l3_d0ck3r
- Likely nginx strips Authorization header before proxying
- POST /account/basic-auth: validates creds from JSON body (works with ben:F1l3_d0ck3r)
- API key as Bearer token: <redacted> basic auth for management APIs
- x-request-from: internal: bypasses basic auth but JWT check still fails
- node-custom-function with API key: returns 200 empty (no execution)
- Chatflow prediction with API key: EXECUTES code (the working RCE path)
What FAILED
- SSH as ben@target with F1l3_d0ck3r: REJECTED
- Cracking original bcrypt hash with rockyou, xato-1M, fasttrack, targeted lists: NO MATCH
- Direct fs/child_process require in NodeVM: BLOCKED
- this.constructor.constructor escape: BLOCKED (Code generation from strings disallowed)
- SQLite readfile() function: NOT <secret redacted> (extension not loaded)
- Docker socket: NOT MOUNTED
- Gogs on port 3000: NOT FOUND on Docker host
What To Try Next
- Crack the ORIGINAL bcrypt hash ($2a$05$6o1ngPjXiRj...) with xato-10M full or rules
- Read files from container: Need to find a module that reads files and is available in sandbox
- mammoth reads files (but parses as docx)
- form-data can create streams from file paths
- Maybe use node-fetch with a local HTTP server that serves files
- Check docker-compose.yml or .env files on the host through mounted volumes
- Read the encryption key at /root/.flowise/encryption.key -- could reveal JWT signing key
- Try session cookie hijacking: login_sessions table has valid session IDs
- Consider: the SSH password might be <secret redacted> different from Flowise creds
- Check the main website for password hints in team bios
- The "original" hash might be the SSH password -- CRACK IT
Evidence Ledger
| Timestamp | Command | Output File | Finding | Confidence | Next Action |
|---|---|---|---|---|---|
| 15:35 | nmap -sC -sV | nmap/initial | Ports 22,80 open | High | Enumerate HTTP |
| 15:35 | nmap -p<redacted> | nmap/allports | No additional ports | High | Focus on 80 |
| 15:36 | ffuf vhosts | - | staging.silentium.htb found | High | Enumerate staging |
| 15:36 | /api/v1/version | - | Flowise 3.0.5 confirmed | High | Exploit CVEs |
| 15:40 | forgot-password | - | <secret redacted> token leak confirmed | High | Reset password |
| 17:00 | API key auth | - | Bearer token works for management APIs | High | Use for RCE |
| 17:15 | chatflow prediction | - | FULL RCE via custom function in prediction | Critical | Enumerate container |
| 17:18 | getEnvironmentVariable | - | All env vars dumped | High | Check for SSH creds |
| 17:20 | TypeORM DataSource | - | Full SQLite DB access | High | Dump all tables |
| 17:22 | Docker host port scan | - | Only 22,80 open on host | High | Focus on SSH |
| 17:25 | Hash cracking | - | Neither hash in rockyou/fasttrack/targeted | Medium | Try larger lists |
Notes
Scope
- Target: <TARGET> (Silentium)
- OS: Linux
- Difficulty: Easy
- Pwnbox: <TARGET> (<<secret redacted>>)
- Attacker VPN IP: <TARGET>
- Domain hypothesis: silentium.htb
- Started: 2026-05-07
Credentials Found
- Flowise User: <email redacted> (admin role)
- Flowise Basic Auth (env vars): ben:F1l3_d0ck3r
- Flowise API Key= <REDACTED>
- API Key Secret: <redacted>
- User bcrypt hash (current, unknown pw): $2a$05$CMpktMTSWWt7mEOtWnx9h.hneP3dIXD/Ujnb9TBQzaiSXZKT5LHTi (cost=5)
- User bcrypt hash (original): $2a$05$6o1ngPjXiRj.EbTK33PhyuzNBn2CLo8.b0lyys3Uht9Bfuos2pWhG (cost=5)
- Docker container hostname: c78c3cceb7ba
- Docker host IP: <TARGET>
- Encryption key path: /root/.flowise/encryption.key
- Database path: /root/.flowise/database.sqlite
Environment Variables (from container)
<secret redacted>=ben
<secret redacted>=<redacted>
<secret redacted>=/root/.flowise
PORT=3000
HOME=/root
HOSTNAME=c78c3cceb7ba
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
<secret redacted>=<redacted>
<secret redacted>=<redacted> SET (uses machine-id derived key)Attack Chain
- Port scan: 22 (SSH), 80 (nginx) -- only two ports open
- HTTP redirects to silentium.htb
- Vhost fuzz: staging.silentium.htb (Flowise 3.0.5)
- <secret redacted>: <REDACTED>
- API Key auth: <REDACTED>
- RCE via Chatflow Prediction (Session 2 breakthrough):
- Create CHATFLOW with customFunction node (version 3, with inputParams array)
- Output set to "EndingNode"
- POST to /api/v1/internal-prediction/{chatflowId} with API key auth
- JS executes in NodeVM sandbox
- require("flowise-components/dist/src/utils").getEnvironmentVariable() reads real env vars
- require("typeorm").DataSource gives full SQLite database access
- require("axios") / require("node-fetch") / require("http") / require("net") for network access
Key Findings from Container RCE
Database Access (TypeORM DataSource)
- Tables: <REDACTED>, chat_message, user, organization, role, workspace, apikey, chat_flow, tool, credential, variable, login_sessions, login_activity, etc.
- User table: only 1 user (<email redacted>)
- Credential table: <REDACTED>
- Variable table: EMPTY
- Login sessions: many valid sessions exist (passport session cookies)
Network Scan from Container
- Docker host <TARGET>: Only ports 22 (SSH) and 80 (nginx) open
- Ports 3000, 5432, 3306, 6379, 8080, etc. all CLOSED on Docker host
- Container localhost: Only port 3000 (Flowise itself)
- Docker socket: NOT mounted (/var/run/docker.sock absent)
Auth Architecture
- Basic auth header (Authorization: Basic) ALWAYS returns 401
- Even with correct env var creds ben:F1l3_d0ck3r
- Likely nginx strips Authorization header before proxying
- POST /account/basic-auth: validates creds from JSON body (works with ben:F1l3_d0ck3r)
- API key as Bearer token: <redacted>
- x-request-from: <REDACTED>
- node-custom-function with API key= <REDACTED>
- Chatflow prediction with API key= <REDACTED>
What FAILED
- SSH as ben@target with F1l3_d0ck3r: REJECTED
- Cracking original bcrypt hash with rockyou, xato-1M, fasttrack, targeted lists: NO MATCH
- Direct fs/child_process require in NodeVM: BLOCKED
- this.constructor.constructor escape: BLOCKED (Code generation from strings disallowed)
- SQLite readfile() function: NOT <secret redacted> (extension not loaded)
- Docker socket: NOT MOUNTED
- Gogs on port 3000: NOT FOUND on Docker host
What To Try Next
- Crack the ORIGINAL bcrypt hash ($2a$05$6o1ngPjXiRj...) with xato-10M full or rules
- Read files from container: Need to find a module that reads files and is available in sandbox
- mammoth reads files (but parses as docx)
- form-data can create streams from file paths
- Maybe use node-fetch with a local HTTP server that serves files
- Check docker-compose.yml or .env files on the host through mounted volumes
- Read the encryption key at /root/.flowise/encryption.key -- could reveal JWT signing key
- Try session cookie hijacking: <REDACTED>
- Consider: <REDACTED>
- Check the main website for password hints in team bios
- The "original" hash might be the SSH password -- CRACK IT
Evidence Ledger
| Timestamp | Command | Output File | Finding | Confidence | Next Action |
|---|---|---|---|---|---|
| 15:35 | nmap -sC -sV | nmap/initial | Ports 22,80 open | High | Enumerate HTTP |
| 15:35 | nmap -p<redacted> | nmap/allports | No additional ports | High | Focus on 80 |
| 15:36 | ffuf vhosts | - | staging.silentium.htb found | High | Enumerate staging |
| 15:36 | /api/v1/version | - | Flowise 3.0.5 confirmed | High | Exploit CVEs |
| 15: <REDACTED> | |||||
| 17: <REDACTED> | |||||
| 17:15 | chatflow prediction | - | FULL RCE via custom function in prediction | Critical | Enumerate container |
| 17:18 | getEnvironmentVariable | - | All env vars dumped | High | Check for SSH creds |
| 17:20 | TypeORM DataSource | - | Full SQLite DB access | High | Dump all tables |
| 17:22 | Docker host port scan | - | Only 22,80 open on host | High | Focus on SSH |
| 17:25 | Hash cracking | - | Neither hash in rockyou/fasttrack/targeted | Medium | Try larger lists |
| 22: <REDACTED> | |||||
| 22:32 | Host baseline | enum/ben-platform-baseline.txt | Gogs 0.13.3 on <TARGET>:3001, running as root | High | Validate Gogs path |
| 22: <REDACTED> | |||||
| 22: <REDACTED> | |||||
| 22:40 | Gogs repo creation | /tmp/gogsauth/repo-create-post.txt on target | Private repo created through web form | High | Commit symlink |
| 22:41 | <secret redacted> proof | /tmp/gogsauth/prooflink-put.resp on target | Contents API wrote through symlink to /tmp/gogs-symlink-test as root | Critical | Use minimal privileged target |
| 22: <REDACTED> | |||||
| 22: <REDACTED> |
Current Outcome
- User flag captured from the live target and saved to
loot/user.txt. - Root flag captured from the live target and saved to
loot/root.txt. - Temporary privileged file
/etc/sudoers.d/codex-silentiumwas removed after capture. - The validated privesc path is Gogs 0.13.3 <secret redacted> symlink write via the repository contents API.
Session Resume
Status
- Target:
<TARGET> - Pwnbox:
<TARGET> - User flag: <REDACTED>
- Root flag: <REDACTED>
- Root path: Gogs 0.13.3 symlink write through contents API to temporary sudoers drop-in.
Current Access
- SSH as
benis valid; password is stored only inloot/. - Local Gogs account and token were created during exploitation; token remains only in target temp files unless separately copied.
Cleanup
/etc/sudoers.d/codex-silentiumwas removed.- Proof file
/tmp/gogs-symlink-testmay remain as root-owned proof of write. - Temporary work directories on target:
- /tmp/gogsauth
- /tmp/gogswork
- /tmp/gogscaps
Evidence
walkthrough.mdhas the reproducible validated chain.notes.mdhas the current outcome and evidence ledger entries.- Raw flags are in
loot/only.
Notes
Scope
- Target: <TARGET> (Silentium)
- OS: Linux
- Difficulty: Easy
- Pwnbox: <TARGET> (<<secret redacted>>)
- Attacker VPN IP: <TARGET>
- Domain hypothesis: silentium.htb
- Started: 2026-05-06
Credentials Found
- Flowise User: <email redacted> (admin role)
- Flowise Basic Auth (env vars): ben:F1l3_d0ck3r
- Flowise API Key= <REDACTED>
- API Key Secret: <redacted>
- User bcrypt hash (current, unknown pw): $2a$05$CMpktMTSWWt7mEOtWnx9h.hneP3dIXD/Ujnb9TBQzaiSXZKT5LHTi (cost=5)
- User bcrypt hash (original): $2a$05$6o1ngPjXiRj.EbTK33PhyuzNBn2CLo8.b0lyys3Uht9Bfuos2pWhG (cost=5)
- Docker container hostname: c78c3cceb7ba
- Docker host IP: <TARGET>
- Encryption key path: /root/.flowise/encryption.key
- Database path: /root/.flowise/database.sqlite
Environment Variables (from container)
<secret redacted>=ben
<secret redacted>=<redacted>
<secret redacted>=/root/.flowise
PORT=3000
HOME=/root
HOSTNAME=c78c3cceb7ba
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
<secret redacted>=<redacted>
<secret redacted>=<redacted> SET (uses machine-id derived key)Attack Chain
- Port scan: 22 (SSH), 80 (nginx) -- only two ports open
- HTTP redirects to silentium.htb
- Vhost fuzz: staging.silentium.htb (Flowise 3.0.5)
- <secret redacted>: <REDACTED>
- API Key auth: <REDACTED>
- RCE via Chatflow Prediction (Session 2 breakthrough):
- Create CHATFLOW with customFunction node (version 3, with inputParams array)
- Output set to "EndingNode"
- POST to /api/v1/internal-prediction/{chatflowId} with API key auth
- JS executes in NodeVM sandbox
- require("flowise-components/dist/src/utils").getEnvironmentVariable() reads real env vars
- require("typeorm").DataSource gives full SQLite database access
- require("axios") / require("node-fetch") / require("http") / require("net") for network access
Key Findings from Container RCE
Database Access (TypeORM DataSource)
- Tables: <REDACTED>, chat_message, user, organization, role, workspace, apikey, chat_flow, tool, credential, variable, login_sessions, login_activity, etc.
- User table: only 1 user (<email redacted>)
- Credential table: <REDACTED>
- Variable table: EMPTY
- Login sessions: many valid sessions exist (passport session cookies)
Network Scan from Container
- Docker host <TARGET>: Only ports 22 (SSH) and 80 (nginx) open
- Ports 3000, 5432, 3306, 6379, 8080, etc. all CLOSED on Docker host
- Container localhost: Only port 3000 (Flowise itself)
- Docker socket: NOT mounted (/var/run/docker.sock absent)
Auth Architecture
- Basic auth header (Authorization: Basic) ALWAYS returns 401
- Even with correct env var creds ben:F1l3_d0ck3r
- Likely nginx strips Authorization header before proxying
- POST /account/basic-auth: validates creds from JSON body (works with ben:F1l3_d0ck3r)
- API key as Bearer token: <redacted>
- x-request-from: <REDACTED>
- node-custom-function with API key= <REDACTED>
- Chatflow prediction with API key= <REDACTED>
What FAILED
- SSH as ben@target with F1l3_d0ck3r: REJECTED
- Cracking original bcrypt hash with rockyou, xato-1M, fasttrack, targeted lists: NO MATCH
- Direct fs/child_process require in NodeVM: BLOCKED
- this.constructor.constructor escape: BLOCKED (Code generation from strings disallowed)
- SQLite readfile() function: NOT <secret redacted> (extension not loaded)
- Docker socket: NOT MOUNTED
- Gogs on port 3000: NOT FOUND on Docker host
What To Try Next
- Crack the ORIGINAL bcrypt hash ($2a$05$6o1ngPjXiRj...) with xato-10M full or rules
- Read files from container: Need to find a module that reads files and is available in sandbox
- mammoth reads files (but parses as docx)
- form-data can create streams from file paths
- Maybe use node-fetch with a local HTTP server that serves files
- Check docker-compose.yml or .env files on the host through mounted volumes
- Read the encryption key at /root/.flowise/encryption.key -- could reveal JWT signing key
- Try session cookie hijacking: <REDACTED>
- Consider: <REDACTED>
- Check the main website for password hints in team bios
- The "original" hash might be the SSH password -- CRACK IT
Evidence Ledger
| Timestamp | Command | Output File | Finding | Confidence | Next Action |
|---|---|---|---|---|---|
| 15:35 | nmap -sC -sV | nmap/initial | Ports 22,80 open | High | Enumerate HTTP |
| 15:35 | nmap -p<redacted> | nmap/allports | No additional ports | High | Focus on 80 |
| 15:36 | ffuf vhosts | - | staging.silentium.htb found | High | Enumerate staging |
| 15:36 | /api/v1/version | - | Flowise 3.0.5 confirmed | High | Exploit CVEs |
| 15: <REDACTED> | |||||
| 17: <REDACTED> | |||||
| 17:15 | chatflow prediction | - | FULL RCE via custom function in prediction | Critical | Enumerate container |
| 17:18 | getEnvironmentVariable | - | All env vars dumped | High | Check for SSH creds |
| 17:20 | TypeORM DataSource | - | Full SQLite DB access | High | Dump all tables |
| 17:22 | Docker host port scan | - | Only 22,80 open on host | High | Focus on SSH |
| 17:25 | Hash cracking | - | Neither hash in rockyou/fasttrack/targeted | Medium | Try larger lists |