Hack The Box · Lab
EasyLinuxWebPrivilege Escalation

IP: 10.129.16.27 | Domain: kobold.htb


Environment Setup

export IP=10.129.16.27
export VPN=<YOUR-VPN-IP>
echo "10.129.16.27 kobold.htb mcp.kobold.htb bin.kobold.htb" | sudo tee -a /etc/hosts

Step 1 — Port Scanning

Why: Before doing anything, we need to map the attack surface. Open ports and services tell us what attack angles are available.

nmap -sV -sC -p- --min-rate 5000 $IP -oA kobold_full

Output:

PORT     STATE SERVICE  VERSION
22/tcp   open  ssh      OpenSSH 9.6p1 Ubuntu 3ubuntu13.15
80/tcp   open  http     nginx 1.24.0 → redirect to https://kobold.htb/
443/tcp  open  ssl/http nginx 1.24.0 — "Kobold Operations Suite"
                        SSL SAN: kobold.htb, *.kobold.htb
3552/tcp open  http     Golang net/http server (Arcane Docker Management)

Key findings:

  • Port 80 — redirects to HTTPS, nothing to do here directly
  • Port 443 — "Kobold Operations Suite", wildcard cert *.kobold.htb confirms subdomains exist
  • Port 3552 — Golang HTTP server, Arcane Docker Management — primary attack surface
  • Port 8080 — PrivateBin, not visible in nmap, discovered later via enumeration
  • No SMB/WinRM/AD ports — this is a Linux web box

Step 2 — Subdomain Enumeration

Why: The wildcard SSL cert (*.kobold.htb) confirms subdomains exist. We need to find which ones are real by filtering out the wildcard response size.

ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
  -u https://kobold.htb/ \
  -H "Host: FUZZ.kobold.htb" \
  -fs 154 -mc 200,301,302,401,403 -k

Output:

mcp   [Status: 200, Size: 466, Words: 57, Lines: 15, Duration: 41ms]

Key findings:

  • All other results were wildcard FPs (302, Size: 154) — filtered with -fs 154
  • mcp.kobold.htb is the only real subdomain — confirmed live with 200 OK
  • Add to /etc/hosts: echo "10.129.16.27 kobold.htb mcp.kobold.htb" | sudo tee -a /etc/hosts
  • bin.kobold.htb (PrivateBin) not in wordlist — discovered later via enumeration

Step 3 — API Surface Mapping

Why: mcp.kobold.htb serves a React SPA (MCPJam Inspector). The OpenAPI endpoint 404s on the subdomain but responds on port 3552 directly. Extracting API paths from the JS bundle gives us the full attack surface without guessing.

curl -sk https://mcp.kobold.htb/assets/index-DRYhT9Xb.js | grep -oE '"/api/[^"]+' | sort -u

Output:

"/api/mcp/connect"
"/api/mcp/tools/execute"
"/api/mcp/tools/list"
"/api/mcp/servers"
"/api/mcp/servers/reconnect"
"/api/mcp/list-tools"
"/api/mcp/resources/list"
"/api/mcp/resources/read"
"/api/mcp/prompts/list"
"/api/mcp/chat"
"/api/mcp/export/server"
"/api/mcp/evals/run"
"/api/mcp-cli-config"
"/api/mcp/oauth/proxy"
... (full list from bundle)

Key findings:

  • /api/mcp/connectprimary target, this is where CVE-2026-23520 lives (command injection via serverConfig.command)
  • /api/mcp/tools/execute — secondary attack surface worth probing
  • /api/mcp/servers — may leak server configuration
  • OpenAPI spec at /api/openapi.json returns 404 on mcp.kobold.htb but responds on http://10.129.16.27:3552 directly
  • No auth headers required on any endpoint — unauthenticated access confirmed

Writeup restricted

This machine is currently active. The full writeup will be published once the box retires, in accordance with HTB's NDA policy.

Status — Active