
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][1])
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][1])
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][1])
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][1])
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][1])
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][1])
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().