Remote code execution in Wazuh server
Corrige ahora. Ella está bajo explotación confirmada por CISA y tiene exploit funcional público.
Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.
Resumen
Falha de desserialização insegura (CWE-502) no servidor Wazuh que permite execução remota de código ao injetar um dicionário JSON malicioso em requisições/respostas da DistributedAPI (DAPI). Afeta a arquitetura de cluster Wazuh (master/worker) e, em certas configurações, pode ser disparada por um agente comprometido — não exige acesso de administrador, apenas acesso à API ou controle de um agente gerenciado. Está no catálogo KEV da CISA com exploração confirmada e possui módulo Metasploit, template Nuclei e PoC pública, o que eleva bastante a urgência prática além do que a CVSS isolada sugere.
Detalle técnico
O ponto vulnerável é a função `as_wazuh_object`, em `framework/wazuh/core/cluster/common.py`, usada para desserializar parâmetros JSON trocados pela DistributedAPI entre nós do cluster Wazuh (master e workers) e, indiretamente, entre servidor e agentes. Essa função reconhece chaves especiais dentro do JSON, entre elas `__unhandled_exc__`, criada originalmente para propagar exceções não tratadas entre nós do cluster. Um atacante que consiga injetar um dicionário controlado nesse fluxo pode forjar um objeto `__unhandled_exc__` cujo conteúdo é interpretado e avaliado como código Python arbitrário no processo do servidor.
O vetor mais direto documentado pelo pesquisador usa o endpoint `run_as` da API de segurança (`run_as_login`, em `api/api/controllers/security_controller.py`). O parâmetro `auth_context` desse endpoint é totalmente controlado pelo cliente e é encaminhado do worker para o master via DAPI sem sanitização adequada — nesse trajeto ele passa por `as_wazuh_object`. Isso permite que uma requisição autenticada contra um worker execute código no master.
Um segundo vetor, mais indireto, explora requisições de configuração de agente (`/agents/{agent_id}/config/{component}/{configuration}`, tratada por `get_agent_config`). Quando o agente-alvo é gerenciado por um servidor diferente daquele que recebeu a requisição original, o servidor original repassa um `getconfig` via DAPI ao servidor que gerencia o agente, e este por sua vez consulta o agente. Um agente comprometido pode responder com um JSON malicioso contendo o payload `__unhandled_exc__`; a desserialização insegura ocorre no servidor que originou a requisição, não no que gerencia o agente — ou seja, o compromisso de um único agente pode levar a RCE em um servidor Wazuh que nunca teve contato direto com ele.
O próprio advisory do fornecedor observa que `as_wazuh_object` provavelmente tem outros caminhos de alcance ainda não mapeados, e que a mesma classe de bug permite execução via outras chaves reconhecidas pelo desserializador (como `__callable__`) ou por gadgets em classes de exceção, `wresults` e módulos internos do Wazuh — a superfície é maior do que os dois vetores documentados.
Cómo se explota
A exploração documentada exige acesso à API do servidor Wazuh — seja via um dashboard comprometido, um servidor de cluster já comprometido (worker atacando master), ou, em topologias com agentes distribuídos entre múltiplos servidores gerenciadores, um agente comprometido que responda a requisições `getconfig` com payload malicioso. O PoC publicado pelo fornecedor demonstra o vetor `run_as` usando as credenciais padrão do usuário de API `wazuh-wui` contra o endpoint `/security/user/authenticate/run_as`, enviando um corpo JSON com a chave `__unhandled_exc__` — no exemplo do advisory isso apenas encerra o processo do master (prova de conceito de execução, não de payload destrutivo), mas o mecanismo permite avaliação arbitrária de código Python, logo RCE completo.
A condição real de exposição varia bastante: instalações com a API exposta à rede e credenciais padrão não alteradas (o próprio PoC usa a senha padrão documentada do usuário `wazuh-wui`) são triviais de atacar por qualquer cliente autenticado com privilégio mínimo na API. Ambientes com múltiplos servidores em cluster e agentes gerenciados por servidores diferentes do que recebe a requisição de configuração ampliam a superfície ao vetor de agente comprometido, sem exigir credenciais de API. A CVSS calculada pelo NVD (9.9, PR:L) diverge da calculada pelo próprio fornecedor no advisory (9.0, PR:H) — o fornecedor considera que é necessário privilégio alto para acionar via API, enquanto o NVD pontua privilégio baixo; isso reflete incerteza sobre o nível de acesso mínimo real, dependendo do vetor usado.
A CISA confirma exploração ativa (entrada no KEV desde 10/06/2025, prazo de mitigação até 01/07/2025) e existem módulo Metasploit, template Nuclei e PoC pública, o que reduz a barreira de entrada para atacantes menos sofisticados a partir da divulgação. O resultado final da exploração é execução arbitrária de código no processo do servidor Wazuh — tipicamente com privilégios do serviço `wazuh-manager`, que costuma ter acesso amplo à infraestrutura monitorada, tornando o servidor comprometido um ponto de pivotagem sobre toda a base de agentes gerenciados.
Versiones
Cómo protegerse
Atualizar para Wazuh 4.9.1 ou posterior, que contém a correção do fornecedor. A correção ataca a causa raiz na função de desserialização (`as_wazuh_object`), não apenas os vetores de exploração descritos, já que o próprio pesquisador alertou que sanitizar apenas os pontos de entrada conhecidos deixaria outros caminhos abertos.
Se a atualização imediata não for possível, reduza a superfície de exposição: restrinja o acesso à porta da API do servidor (55000/tcp, e a porta de comunicação de cluster) apenas a hosts de gerenciamento confiáveis, nunca exponha a API do Wazuh diretamente à Internet, e troque imediatamente as credenciais padrão de usuários de API (incluindo `wazuh-wui`), já que o PoC público depende delas. Em ambientes com múltiplos servidores gerenciando agentes distintos, avaliar se a topologia permite isolar quais servidores podem originar requisições `getconfig` para agentes fora de sua gestão direta reduz o vetor via agente comprometido, mas não elimina o problema — é paliativo de rede, não correção da falha de desserialização.
Trocar apenas a senha padrão ou bloquear só o endpoint `run_as` não mitiga a vulnerabilidade de forma confiável: o próprio advisory indica que existem outros caminhos até `as_wazuh_object` e outras chaves de desserialização exploráveis (`__callable__`, gadgets em classes internas). Qualquer controle compensatório que não seja a atualização de versão deve ser tratado como redução de exposição temporária, não como remediação.
Cómo detectar
Monitore logs da API do Wazuh (`api.log` / logs de acesso à porta 55000) por requisições ao endpoint `/security/user/authenticate/run_as` (ou outros endpoints de autenticação) cujo corpo contenha as chaves JSON `__unhandled_exc__`, `__callable__` ou estruturas com `__class__`/`__args__` — esse é o padrão de payload documentado no PoC público. Reinícios ou crashes inesperados do processo `wazuh-manager` no nó master, sem correlação com manutenção programada, são indício de tentativa de exploração usando o payload de prova de conceito (que aciona `exit()`).
Em topologias de cluster, verifique tráfego DAPI anômalo entre workers e master, e respostas de `getconfig` vindas de agentes com conteúdo JSON fora do formato esperado de configuração. Não há assinatura única e confiável para todas as variantes de exploração, já que a falha permite múltiplos gadgets de desserialização — a ausência de sinal não indica ausência de exposição, apenas que o vetor específico monitorado não foi usado.