
Cacti 1.2.22 inyección de comandos no autenticada
| Campo | Detalles |
|---|
| Producto | Cacti |
| Versión afectada | 1.2.22 |
| Vulnerabilidad | Inyección de comandos del sistema operativo no autenticada |
| CVE | CVE-2022-46169 |
| CWE | CWE-77 — Inyección de comandos |
| Severidad | Crítica |
| CVSS v3.1 | 9.8 |
| Vector de ataque | Red |
| Autenticación | Ninguna |
| Interacción del usuario | Ninguna |
| Impacto | Confidencialidad / Integridad / Disponibilidad |
| Versión corregida | 1.2.23 |
| Componente vulnerable | remote_agent.php |
| Componente adicional | lib/functions.php |
| Acción vulnerable principal | polldata |
El vector CVSS publicado es:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
El aviso oficial lo califica como 9.8 Crítico. (GitHub)
En realidad hay dos errores encadenados.
Etapa 1 — Omisión de autorización
El remote_agent.php de Cacti acepta solicitudes sin autenticación normal, pero intenta determinar si el solicitante es un poller autorizado.
El flujo de autorización efectivamente hace:
HTTP request
│
▼
remote_agent.php
│
▼
remote_client_authorized()
│
▼
get_client_addr()
│
▼
gethostbyaddr()
│
▼
poller table hostname comparison
El problema es get_client_addr().
En 1.2.22 examina numerosas variables de servidor derivadas de HTTP, incluidos los encabezados de IP de cliente reenviados. El aviso explica que los valores HTTP_* controlados por el atacante pueden influir en la IP devuelta por esta función. (GitHub)
Eso significa que la aplicación puede ser engañada para que crea:
Atacante
↓
"mi IP es el servidor Cacti"
↓
gethostbyaddr()
↓
nombre de host del servidor Cacti
↓
coincide con la tabla de pollers
↓
AUTORIZADO
Por lo tanto, el atacante no necesita una cuenta legítima de Cacti.
Después de omitir la verificación de autorización, la funcionalidad interesante del endpoint es la acción polldata.
La ruta de ejecución relevante es 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
El error importante es el manejo de poller_id.
La aplicación lo recupera usando:
get_nfilter_request_var()
en lugar de imponer que sea un entero.
Ese valor controlado por el atacante eventualmente se convierte en parte de un comando pasado a proc_open() de PHP. El aviso oficial identifica explícitamente esto como la primitiva de inyección de comandos. (GitHub)
Conceptualmente:
entrada controlada por el atacante
↓
poller_id
↓
concatenación de cadenas
↓
proc_open()
↓
comando del sistema operativo
Esta es la parte crítica de la vulnerabilidad.
Lo interesante para tu análisis de PoC es que ninguno de los dos errores por sí solo es toda la historia.
Es una cadena de vulnerabilidades:
┌──────────────────────────┐
│ Atacante no autenticado │
└────────────┬─────────────┘
│
▼
remote_agent.php
│
▼
Omisión de autorización
mediante lógica de IP de cliente
│
▼
polldata
│
▼
poller_item lookup
│
▼
POLLER_ACTION_SCRIPT_PHP
│
▼
entrada del atacante
→ poller_id
│
▼
proc_open()
│
▼
Ejecución de comandos
│
▼
RCE
Esa es una distinción muy importante que hacer en tu informe:
CVE-2022-46169 no es simplemente "un parámetro malo en remote_agent.php". Es una vulnerabilidad encadenada de omisión de autorización + inyección de comandos.
El aviso oficial confirma que la condición de ejecución vulnerable requiere un poller_item cuya acción sea POLLER_ACTION_SCRIPT_PHP. (GitHub)
Tu PoC debería documentar esto explícitamente porque es un detalle analítico importante.
El objetivo necesita un poller_item adecuado configurado con:
POLLER_ACTION_SCRIPT_PHP
El aviso de Cacti señala que esto es común en instalaciones de producción porque plantillas predefinidas como Device - Uptime y Device - Polling Time pueden crear estas entradas. (GitHub)
Así que no escribas:
"Toda instalación de Cacti 1.2.22 es automáticamente explotable."
Una declaración técnicamente más precisa es:
Cacti 1.2.22 es vulnerable, y la ejecución exitosa de comandos depende de la presencia de una configuración
poller_itemadecuada.
host_id y local_data_idpoll_for_data() no simplemente ejecuta el poller_id proporcionado.
Primero consulta poller_item usando valores correspondientes a:
host_id
local_data_id
Luego examina la acción del elemento resultante.
La condición vulnerable es efectivamente:
host_id
+
local_data_id
↓
poller_item
↓
action == POLLER_ACTION_SCRIPT_PHP
↓
ruta de ejecución vulnerable
El aviso original señala que estos identificadores pueden descubrirse porque las entradas relevantes existen en la base de datos de la aplicación, y que es probable que existan entradas adecuadas en instalaciones productivas. (GitHub)
Para un PoC público, demostraría este requisito previo explícitamente en lugar de ocultarlo.
Para algo que publiques, recomiendo hacer que el PoC demuestre ejecución de comandos sin dar a los lectores un payload de reverse-shell armado.
Por ejemplo, estructura tu demostración como:
1. Desplegar Cacti 1.2.22 en una VM aislada
2. Configurar un poller_item usando POLLER_ACTION_SCRIPT_PHP
3. Confirmar que remote_agent.php es accesible
4. Demostrar que la decisión de autorización es influenciada
5. Alcanzar la ruta de ejecución de polldata
6. Usar un marcador de ejecución de comandos inofensivo
7. Capturar la evidencia resultante de la aplicación/registros
8. Actualizar a 1.2.23
9. Repetir la prueba
10. Demostrar que la vulnerabilidad ya no es explotable
Eso te da una demostración legítima de vulnerabilidad sin convertir el informe en un arma RCE lista para Internet.
Puedes dividir el código vulnerable en tres áreas.
remote_agent.phpResponsable de exponer la funcionalidad del agente remoto y despachar la acción solicitada.
remote_agent.php
│
└── action = polldata
│
▼
poll_for_data()
lib/functions.phpContiene get_client_addr().
El diseño problemático es confiar en valores derivados de HTTP al decidir la dirección de red real del solicitante.
El aviso oficial enumera múltiples variables relacionadas con HTTP que se inspeccionan antes de recurrir a la dirección remota real. (GitHub)
proc_open()El sumidero peligroso final es la construcción del comando PHP ejecutado a través de proc_open().
El aviso identifica el flujo vulnerable como:
poller_id
↓
get_nfilter_request_var()
↓
construcción del comando
↓
proc_open()
(GitHub)
El aviso de Cacti identifica dos cambios de remediación importantes.
Primero, poller_id debe tratarse como un entero:
get_nfilter_request_var()
↓
get_filter_request_var()
Segundo, el valor también debe escaparse para shell antes de incorporarse al comando:
escapeshellarg($poller_id)
El aviso recomienda específicamente ambas medidas. (GitHub)
El lado de la autorización también debe dejar de permitir que un atacante influya arbitrariamente en la IP de cliente utilizada para la autorización. (GitHub)
Cacti 1.2.22
│
├── vulnerable
├── omisión de autorización
├── inyección de comandos
└── posible RCE no autenticado
Cacti 1.2.23
│
└── CVE-2022-46169 parcheado
El aviso del proveedor lista 1.2.22 como afectada y 1.2.23 como la versión 1.2.x parcheada. (GitHub)
El aviso de seguridad de Amazon describe independientemente el problema como que permite a un atacante no autenticado ejecutar comandos arbitrarios y le otorga una puntuación CVSS de 9.8. (AWS Training and Certification)
Yo usaría algo como:
CVE-2022-46169 — Inyección de comandos no autenticada / RCE en Cacti 1.2.22
O más técnico:
CVE-2022-46169: Análisis de la cadena de omisión de autorización e inyección de comandos del agente remoto de Cacti 1.2.22
Y tu resumen de vulnerabilidad puede decir:
Cacti 1.2.22 contiene una cadena de vulnerabilidades crítica en la funcionalidad del agente remoto. Un atacante puede manipular la lógica de determinación de la dirección del cliente para omitir la verificación de autorización del agente remoto. Una vez que se alcanza la funcionalidad
polldata, la validación insuficiente del parámetropoller_idpermite que datos controlados por el atacante lleguen a un comando ejecutado a través deproc_open(). En configuraciones que contienen un elemento pollerPOLLER_ACTION_SCRIPT_PHP, esto puede resultar en ejecución remota de comandos no autenticada. El problema se corrigió en Cacti 1.2.23. (GitHub)
Una corrección importante para tu investigación: no confundas esto con CVE-2023-39362. Ese RCE posterior de Cacti afecta a 1.2.24 y se corrigió en 1.2.25, por lo que no es la vulnerabilidad que quieres para un PoC de 1.2.22. (NVD)