-
Defect (Security)
-
Resolution: Fixed
-
Critical
-
None
-
None
-
S24-W8/9, S24-W10/11, S24-W12/13
-
2
Summary:
Zabbix server can perform command execution for configured scripts. After command is executed, audit entry is added to "Audit Log". Due to "clientip" field is not sanitized, it is possible to injection SQL into "clientip" and exploit time based blind SQL injection.
Steps To Reproduce:
I will provide 3 variations of steps to reproduce, 1st one is real exploitation running attached exploit, it will extract admin session_id and session_key to sign zbx_session, this data together can be used to generate correct admin zbx_session. 2nd is easier version which will simply make PoC of time based SQL injection, you will see 3 requests and how backend sleeps for 1,5, and 10 seconds. 3rd is another simple PoC which you can verify via zabbix_server.log
Steps To Exploit
1. Login to low privileged user. User should have access to at least 1 host to be able to run command against it, like here on screenshot
Image F3064173: image.png 87.24 KiB
2. Extract logged in user "sessionid" from zbx_session cookie(decode it as base64 and grab sessionid from json)
3. Extract any hostid available to this user (open Monitoring->Hosts, host id will be in response)
4. Execute attached exploit zabbix_server_time_based_blind_sqli.py, use --help if needed. In standard case "ip", "sessionid" and "hostid" should be enough:
python3 zabbix_server_time_based_blind_sqli.py --ip 192.168.223.128 --sid a6094b4f052fd133adc335382f0297f6 --hostid 10607 | grep "(+)"
Exploit time execution can take ~10 mins, but you will see progress update every few secs. Exploit takes that much time because of time based SQLi, it require to sleep() for a while on each guess(see exploit code). Pipe to grep "" is just to filter output, otherwise pwntools prints too many debug data. As a result you will get admin session_id and session_key used to sign zbx_session cookie, so you can generate admin token now.
Steps to PoC if Time Based Blind SQLi
1. Perform steps 1-3 from "Steps To Exploit" (extract low priv user sessionid and any available hostid)
2. Execute Exploit (replace ip, sessionid and hostid with yours from previous step)
python3 zabbix_server_time_based_blind_sqli.py LOG_LEVEL=error --ip 192.168.223.128 --sid a6094b4f052fd133adc335382f0297f6 --hostid 10607 --poc
You will see 3 requests and backend sleeps for 1,5 and 10 secs before response. You will see request/response packets to understand that sleep happens on backend.
Steps to PoC to Generate Error in Zabbix Logs
1. Perform steps 1-3 from "Steps To Exploit" (extract low priv user sessionid and any available hostid)
2. Execute Exploit (replace ip, sessionid and hostid with yours from previous step)
python3 zabbix_server_time_based_blind_sqli.py LOG_LEVEL=error --ip 192.168.223.128 --sid a6094b4f052fd133adc335382f0297f6 --hostid 10607 --poc2
3. Check zabbix_server.log, you will see that query is failed but injected ' + version() + ' and its result is in place
Technical Details:
SQL injection is in audit.c, function zbx_auditlog_global_script:
... 2225: if (ZBX_DB_OK > zbx_db_execute("insert into auditlog (auditid,userid,username,clock,action,ip,resourceid," 3226: "resourcename,resourcetype,recordsetid,details) values ('%s'," ZBX_FS_UI64 ",'%s',%d,'%d','%s'," 4227: ZBX_FS_UI64 ",'%s',%d,'%s','%s')", auditid_cuid, userid, username, (int)time(NULL), 5228: ZBX_AUDIT_ACTION_EXECUTE, clientip, hostid, hostname, AUDIT_RESOURCE_SCRIPT, auditid_cuid, 6229: details_esc)) 7230: { 8231: ret = FAIL; 9232: }
clientip is NOT sanitized and controlled by attacker, as a result we can put SQL query here. Only time based SQLi will work(see exploit code).
Exploit Output
Impact
Allows to dump any values from database. As an example of exploit above allows privilege escalation from user to admin. In some cases SQL injection leads to RCE.