
Cacti 1.2.22 injeção de comando não autenticada
| Campo | Detalhes |
|---|
| Produto | Cacti |
| Versão afetada | 1.2.22 |
| Vulnerabilidade | Injeção de comandos do sistema operacional não autenticada |
| CVE | CVE-2022-46169 |
| CWE | CWE-77 — Injeção de Comandos |
| Severidade | Crítica |
| CVSS v3.1 | 9.8 |
| Vetor de ataque | Rede |
| Autenticação | Nenhuma |
| Interação do usuário | Nenhuma |
| Impacto | Confidencialidade / Integridade / Disponibilidade |
| Versão corrigida | 1.2.23 |
| Componente vulnerável | remote_agent.php |
| Componente adicional | lib/functions.php |
| Ação vulnerável principal | polldata |
O vetor CVSS publicado é:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
O aviso oficial classifica como 9.8 Crítica. (GitHub)
Na verdade, existem dois bugs encadeados.
Estágio 1 — Bypass de autorização
O remote_agent.php do Cacti aceita solicitações sem autenticação normal, mas tenta determinar se o solicitante é um poller autorizado.
O fluxo de autorização efetivamente faz:
HTTP request
│
▼
remote_agent.php
│
▼
remote_client_authorized()
│
▼
get_client_addr()
│
▼
gethostbyaddr()
│
▼
poller table hostname comparison
O problema é get_client_addr().
Na versão 1.2.22, ela examina diversas variáveis de servidor derivadas de HTTP, incluindo cabeçalhos de IP de cliente encaminhado. O aviso explica que valores HTTP_* controlados pelo atacante podem influenciar o IP retornado por essa função. (GitHub)
Isso significa que o aplicativo pode ser enganado para acreditar:
Atacante
↓
"meu IP é o servidor Cacti"
↓
gethostbyaddr()
↓
hostname do servidor Cacti
↓
corresponde à tabela de pollers
↓
AUTORIZADO
Portanto, o atacante não precisa de uma conta legítima no Cacti.
Após contornar a verificação de autorização, a funcionalidade interessante do endpoint é a ação polldata.
O caminho de execução relevante é aproximadamente:
remote_agent.php
│
▼
polldata
│
▼
poll_for_data()
│
├── host_id
├── local_data_ids
└── poller_id
│
▼
poller_item lookup
│
▼
POLLER_ACTION_SCRIPT_PHP
│
▼
proc_open()
│
▼
OS command execution
O erro importante é o tratamento de poller_id.
O aplicativo o recupera usando:
get_nfilter_request_var()
em vez de garantir que seja um inteiro.
Esse valor controlado pelo atacante eventualmente se torna parte de um comando passado para proc_open() do PHP. O aviso oficial identifica explicitamente isso como a primitiva de injeção de comandos. (GitHub)
Conceitualmente:
entrada controlada pelo atacante
↓
poller_id
↓
concatenação de strings
↓
proc_open()
↓
comando do sistema operacional
Esta é a parte crítica da vulnerabilidade.
O interessante para sua análise de PoC é que nenhum dos bugs isoladamente conta a história completa.
É uma cadeia de vulnerabilidades:
┌──────────────────────────┐
│ Atacante não autenticado │
└────────────┬─────────────┘
│
▼
remote_agent.php
│
▼
Bypass de autorização
via lógica de IP do cliente
│
▼
polldata
│
▼
poller_item lookup
│
▼
POLLER_ACTION_SCRIPT_PHP
│
▼
entrada do atacante
→ poller_id
│
▼
proc_open()
│
▼
Execução de comandos
│
▼
RCE
Essa é uma distinção muito importante para fazer em seu relatório:
CVE-2022-46169 não é simplesmente "um parâmetro ruim em remote_agent.php". É uma vulnerabilidade encadeada de bypass de autorização + injeção de comandos.
O aviso oficial confirma que a condição de execução vulnerável requer um poller_item cuja ação seja POLLER_ACTION_SCRIPT_PHP. (GitHub)
Seu PoC deve documentar isso explicitamente porque é um detalhe analítico importante.
O alvo precisa de um poller_item adequado configurado com:
POLLER_ACTION_SCRIPT_PHP
O aviso do Cacti observa que isso é comum em instalações de produção porque modelos predefinidos como Device - Uptime e Device - Polling Time podem criar essas entradas. (GitHub)
Portanto, não escreva:
"Toda instalação do Cacti 1.2.22 é automaticamente explorável."
Uma declaração tecnicamente mais precisa é:
O Cacti 1.2.22 é vulnerável, e a execução bem-sucedida de comandos depende da presença de uma configuração
poller_itemapropriada.
host_id e local_data_id importampoll_for_data() não executa simplesmente o poller_id fornecido.
Primeiro, ela consulta poller_item usando valores correspondentes a:
host_id
local_data_id
Em seguida, examina a ação do item resultante.
A condição vulnerável é efetivamente:
host_id
+
local_data_id
↓
poller_item
↓
action == POLLER_ACTION_SCRIPT_PHP
↓
caminho de execução vulnerável
O aviso original observa que esses identificadores podem ser descobertos porque as entradas relevantes existem no banco de dados do aplicativo, e que entradas adequadas provavelmente existem em instalações produtivas. (GitHub)
Para um PoC público, eu demonstraria esse pré-requisito explicitamente em vez de ocultá-lo.
Para algo que você vai publicar, recomendo fazer o PoC demonstrar execução de comandos sem dar aos leitores um payload de reverse shell armamentado.
Por exemplo, estruture sua demonstração como:
1. Implante o Cacti 1.2.22 em uma VM isolada
2. Configure um poller_item usando POLLER_ACTION_SCRIPT_PHP
3. Confirme que remote_agent.php está acessível
4. Demonstre a decisão de autorização sendo influenciada
5. Alcance o caminho de execução do polldata
6. Use um marcador inofensivo de execução de comandos
7. Capture as evidências resultantes do aplicativo/log
8. Atualize para 1.2.23
9. Repita o teste
10. Demonstre que a vulnerabilidade não é mais explorável
Isso oferece uma demonstração legítima de vulnerabilidade sem transformar o relatório em uma arma de RCE pronta para a Internet.
Você pode dividir o código vulnerável em três áreas.
remote_agent.phpResponsável por expor a funcionalidade do agente remoto e despachar a ação solicitada.
remote_agent.php
│
└── action = polldata
│
▼
poll_for_data()
lib/functions.phpContém get_client_addr().
O design problemático é confiar em valores derivados de HTTP ao decidir o endereço de rede real do solicitante.
O aviso oficial lista múltiplas variáveis relacionadas a HTTP que são inspecionadas antes de recorrer ao endereço remoto real. (GitHub)
proc_open()O sink perigoso final é a construção do comando PHP executado via proc_open().
O aviso identifica o fluxo vulnerável como:
poller_id
↓
get_nfilter_request_var()
↓
construção do comando
↓
proc_open()
(GitHub)
O aviso do Cacti identifica duas mudanças importantes de remediação.
Primeiro, poller_id deve ser tratado como um inteiro:
get_nfilter_request_var()
↓
get_filter_request_var()
Segundo, o valor também deve ser escapado para shell antes de ser incorporado ao comando:
escapeshellarg($poller_id)
O aviso recomenda especificamente ambas as medidas. (GitHub)
O lado da autorização também precisa parar de permitir que um atacante influencie arbitrariamente o IP do cliente usado para autorização. (GitHub)
Cacti 1.2.22
│
├── vulnerável
├── bypass de autorização
├── injeção de comandos
└── potencial RCE não autenticado
Cacti 1.2.23
│
└── CVE-2022-46169 corrigido
O aviso do fornecedor lista 1.2.22 como afetada e 1.2.23 como a versão 1.2.x corrigida. (GitHub)
O aviso de segurança da Amazon descreve independentemente o problema como permitindo que um atacante não autenticado execute comandos arbitrários e atribui uma pontuação CVSS de 9.8. (AWS Training and Certification)
Eu usaria algo como:
CVE-2022-46169 — Injeção de Comandos Não Autenticada / RCE no Cacti 1.2.22
Ou mais técnico:
CVE-2022-46169: Análise da Cadeia de Bypass de Autorização e Injeção de Comandos do Agente Remoto do Cacti 1.2.22
E seu resumo da vulnerabilidade pode dizer:
O Cacti 1.2.22 contém uma cadeia de vulnerabilidades crítica na funcionalidade do agente remoto. Um atacante pode manipular a lógica de determinação do endereço do cliente para contornar a verificação de autorização do agente remoto. Uma vez alcançada a funcionalidade
polldata, a validação insuficiente do parâmetropoller_idpermite que dados controlados pelo atacante alcancem um comando executado viaproc_open(). Em configurações contendo um item de pollerPOLLER_ACTION_SCRIPT_PHP, isso pode resultar em execução remota de comandos não autenticada. O problema foi corrigido no Cacti 1.2.23. (GitHub)
Uma correção importante para sua pesquisa: não confunda isso com CVE-2023-39362. Esse RCE posterior do Cacti afeta 1.2.24 e foi corrigido na 1.2.25, portanto não é a vulnerabilidade que você quer para um PoC da 1.2.22. (NVD)