
Proof-of-concept exploits for Wazuh cluster vulnerabilities CVE-2026-25769 and CVE-2026-25770, demonstrating remote code execution and privilege escalation via insecure deserialization and file overwrite.
Warning: This repository contains information and code related to security vulnerabilities. Use it only for educational purposes or in authorized environments.
Two critical vulnerabilities have been identified in the Wazuh cluster configuration (versions ≥ 4.0.0). These flaws affect deployments that use multiple nodes for horizontal scalability, load balancing, and high availability. This configuration allows the management of multiple agents without impacting the Wazuh server.
Allows communication between the master and the worker through a DAPi request. The worker sends an object using the LocalClient module of the worker; the master accepts the message and deserializes the object with the vulnerable function as_wazuh_object(), which allows commands to be executed on the master.
This vulnerability complements the previous one, allowing command execution using the <command> and <localfile> tags. An attacker can execute commands every time the /var/ossec/etc/ossec.conf configuration file is loaded.
Both allow [general impact: privilege escalation, remote execution, etc.] in environments that use cluster functionality.
Wazuh manager ≥ 4.0.0 (up to patched version X.Y.Z)
All nodes with the master or worker role that have inter-node communication enabled.
Cluster configuration is used in deployments with a large number of agents. It allows:
Horizontal scaling: adding more worker nodes to distribute the load.
High availability: if a worker node fails, the others continue operating while the node is restored.
Load balancing: agents are distributed among the workers.
This architecture, if not properly secured, can expose attack vectors such as those documented here.
The master calls this function, which allows the creation of a subprocess that executes arbitrary commands.
def as_wazuh_object(dct: Dict):
try:
if '__callable__' in dct:
encoded_callable = dct['__callable__']
funcname = encoded_callable['__name__'] #getoutput
if '__wazuh__' in encoded_callable:
# Encoded Wazuh instance method.
wazuh = Wazuh()
return getattr(wazuh, funcname)
else:
# Encoded function or static method.
qualname = encoded_callable['__qualname__'].split('.') # getoutput
classname = qualname[0] if len(qualname) > 1 else None
module_path = encoded_callable['__module__'] # subprocess
module = import_module(module_path) # ARBITRARY IMPORT
if classname is None:
return getattr(module, funcname) # RETURNS ARBITRARY FUNCTION
else:
return getattr(getattr(module, classname), funcname)
The Wazuh Cluster Protocol (TCP/1516) synchronizes files between nodes using the process. This process runs as an unprivileged user, accepting relative addresses.
"""Create a file descriptor to store the incoming file.
Parameters
----------
data : bytes
Relative path to the file.
Returns
-------
bytes
Result.
bytes
Response message.
"""
# VULNERABLE LINE: No validation of 'data', no checking for '../', direct file open.
self.in_file[data] = {'fd': open(common.WAZUH_PATH + data.decode(), 'wb'), 'checksum': hashlib.sha256()}
return b"ok ", b"Ready to receive new file"
Using this configuration, an attacker could overwrite the configuration directory and execute commands.
An attacker could:
Affect confidentiality, integrity, availability, and privilege escalation.
Compromise the integrity of the entire monitored infrastructure.
The original PoCs were developed by vikman90 and served as the basis for this analysis. An exploit example is shown below:
# 1. init docker compose
docker compose up -d
# 2. wait init all clusters
# 3. Verify cluster is connected
docker exec poc-master /var/ossec/bin/cluster_control -l
# Expected output should show worker01 connected:
# worker01 172.28.0.11 active
# 4. Execute exploit from worker
docker exec poc-worker /var/ossec/framework/python/bin/python3 /scripts/poc.py
# 5. Verify RCE on master
docker exec poc-master cat /var/ossec/etc/ossec.conf