
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.
Advertencia: Este repositorio contiene información y código relacionado con vulnerabilidades de seguridad. Úsalo únicamente con fines educativos o en entornos autorizados.
Se han identificado dos vulnerabilidades críticas en la configuración de clúster de Wazuh (versiones ≥ 4.0.0). Estas fallas afectan a despliegues que utilizan múltiples nodos para escalabilidad horizontal, balanceo de carga y alta disponibilidad. Esta configuración permite la gestión de varios agentes sin que el servidor Wazuh sufra.
Permite la comunicación entre el master y el worker a través de una solicitud DAPi. El worker envía un objeto utilizando el módulo LocalClient del worker; el master acepta el mensaje y deserializa el objeto con la función vulnerable as_wazuh_object(), lo que permite ejecutar comandos en el master.
Esta vulnerabilidad complementa a la anterior, permitiendo ejecutar comandos mediante las etiquetas <command> y <localfile>. Un atacante puede ejecutar comandos cada vez que se carga el archivo de configuración .
/var/ossec/etc/ossec.confAmbas permiten [impacto general: escalada de privilegios, ejecución remota, etc.] en entornos que utilizan la funcionalidad de clúster.
Wazuh manager ≥ 4.0.0 (hasta la versión parcheada X.Y.Z)
Todos los nodos con rol master o worker que tengan habilitada la comunicación entre nodos.
La configuración de clúster es utilizada en despliegues con un gran número de agentes. Permite:
Escalado horizontal: agregar más nodos workers para distribuir la carga.
Alta disponibilidad: si un nodo worker falla, los demás siguen operando mientras el nodo se restaura.
Balanceo de carga: Los agentes se distribuyen entre los workers.
Esta arquitectura, si no está adecuadamente asegurada, puede exponer vectores de ataque como los aquí documentados.
El máster llama a esta función, donde permite crear el proceso subprocess que ejecuta arbitrariamente comandos.
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)
El Protocolo de Clúster Wazuh (TCP/1516) sincroniza archivos entre nodos utilizando el proceso. Este proceso se ejecuta como usuario no privilegiado, aceptando direcciones relativas.
"""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"
Usando esta configuración, el atacante podría sobrescribir el directorio de configuración y llegar a ejecutar comandos.
Un atacante podría:
Afectar la confidencialidad, integridad, disponibilidad, escalada de privilegios.
Comprometer la integridad de toda la infraestructura monitoreada.
Los PoCs originales fueron desarrollados por vikman90 y sirvieron como base para este análisis. A continuación se muestra un ejemplo de explotación:
# 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
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 until 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