冷行
冷行
发布于 2026-06-20 / 9 阅读
0
0

Nezha 监控系统入侵事件应急响应实录

一次真实的 40 台 VPS 批量入侵事件全记录:从漏洞发现到后门清理、根因定位、复发处置、自动化加固的完整过程。

事件时间:2026-06-19 至 2026-06-20 影响范围:40 台服务器,主控 Nezha dashboard 2.2.3,34 台 agent 被植入后门 事件性质:利用 Nezha 低版本安全漏洞投放持久化后门


一、事件背景

我有 40 台 VPS 分布在多个云服务商(腾讯云、阿里云、华为云等),全部接入同一套 Nezha 监控面板。主控运行 dashboard v2.2.3。

2026-06-19,我注意到 Nezha 官方发布了多个安全公告(security advisories),涉及低版本的远程命令执行、路径穿越泄露密钥等严重漏洞。我需要确认:

  1. 我的 dashboard 和 40 台 agent 是否受影响?

  2. 攻击者是否已经利用漏洞入侵了我的服务器?

  3. 如果被入侵了,植入了什么后门?怎么清理?


二、漏洞分析

受影响版本

Nezha 官方安全公告显示,关键修复分界点是 2.2.0

  • Dashboard/Agent < 2.2.0:受多个中危漏洞影响

  • 更老版本叠加高危/严重漏洞

关键 CVE

GHSA

CVE

严重性

概述

GHSA-99gv-2m7h-3hh9

CVE-2026-46716

严重

低版本 RoleMember 可通过 cron 接口在 Agent 节点执行 shell 命令

GHSA-5c25-7vpj-9mqh

CVE-2026-53519

严重

低版本 Dashboard 预认证路径穿越泄露 jwt_secret_key

攻击链路

攻击者获取面板访问权限
  ├─ 方式1:利用 CVE-2026-53519 路径穿越泄露 jwt_secret_key → 伪造管理员 JWT
  ├─ 方式2:利用 CVE-2026-46716 cron 接口直接执行命令
  └─ 方式3:弱口令 / 泄露的面板账号
        ↓
通过面板的远程命令能力(cron / terminal / force-update)
在 Agent 节点上执行任意命令
        ↓
植入持久化后门

三、版本排查

Dashboard 版本

主控 dashboard 是 Docker 部署,版本确认:

docker exec nezha-dashboard /dashboard/app -v
# 输出:2.2.3

dashboard 2.2.3 > 2.2.0,不受 advisory 影响。

Agent 版本(40 台)

这里踩了一个大坑:公开 WebSocket 返回的 host.version 在访客视图下是 null,必须用管理员 JWT 才能看到真实版本。

最终通过以下步骤获取 40 台 agent 版本:

  1. 从主控 SQLite 数据库读取 jwt_secret_key 和未过期 session 的 key_id

  2. 用 Go + sqids-go 生成管理员 JWT(Nezha 用 idcodec 对 user_id 做 sqids 编码)

  3. 用 JWT 连接管理员 WebSocket 读取 host.version

结果:

  • 主控 agent:2.2.2(最新)

  • 31 台在线 agent:2.2.2(最新)

  • 5 台在线 agent:1.9.7(受漏洞影响)

  • 4 台离线无版本

5 台旧版 agent:狗云-MG-V6、hostyun-us、绿云-日本大版、狗云-MG-V4、racknerd-DC02。


四、第一轮清理:sysmon 后门

发现

对主控做深度只读检查时,发现 /etc/systemd/system/sysmon.servicesysmon-guard.timer,进一步排查发现完整的后门体系:

后门结构

/usr/local/sysmon/              ← 伪装 Nezha agent 的假二进制 + config.yml
  └─ config.yml                 ← server: 51.254.44.35:8008(攻击者面板)
/usr/local/.sysmon-guard/       ← 守护进程
/usr/local/lib/libsysmon.so     ← preload 注入库
/etc/systemd/system/sysmon.service
/etc/systemd/system/sysmon-guard.service
/etc/systemd/system/sysmon-guard.timer   ← 30 秒触发自恢复
/etc/ld.so.preload              ← 加载 libsysmon.so

后门行为

  • 伪装成 sysmon 系统监控服务,实际运行类似 Nezha Agent 的二进制

  • 配置文件 server: 指向攻击者控制的 Nezha 面板 51.254.44.35:8008

  • sysmon-guard.timer 每 30 秒检查一次,如果 sysmon 被杀就重新拉起

  • /etc/ld.so.preload 加载 libsysmon.so 做全局钩子(可能用于隐藏进程/文件)

  • 日志显示守护进程每 30 秒执行 SELF-HEAL: Re-installing cron

环境变量泄露的后门设计

STEALTH_NAME=sysmon
INSTALL_DIR=/usr/local/sysmon
GUARD_DIR=/usr/local/.sysmon-guard
LIB_PATH=/usr/local/lib/libsysmon.so
PRELOAD_FILE=/etc/ld.so.preload

清理

清理顺序非常重要(顺序错了守护器会重建文件):

  1. 停止并禁用 sysmon-guard.timersysmon-guard.servicesysmon.service

  2. kill -9 杀掉所有 sysmon 相关进程

  3. 删除 systemd unit 文件

  4. 清理 /etc/ld.so.preload 中的 libsysmon.so 引用

  5. 删除 /usr/local/lib/libsysmon.so

  6. 删除 /usr/local/sysmon/usr/local/.sysmon-guard 目录

  7. systemctl daemon-reload

清理后复查:主控 sysmon 后门已彻底删除,无残留进程/文件/外连。


五、批量清理 40 台

用 paramiko 线程池(10 并发)批量清理所有服务器,密码只在内存中不落盘。

清理结果

  • 主控 + 大部分感染节点:sysmon 后门已清理

  • 3 台 SSH 超时:raksmart-圣何塞、云曦幻境、geelinx-b,需手动处理

  • Agent 版本升级:通过面板 force-update API + 手动 SSH 升级,5 台 1.9.7 升级到 2.2.2

升级 Agent 的坑

  • force-update API 对 disable_force_update: true 的 agent 无效

  • 主控显示旧版本不一定是二进制旧,可能是进程没重启

  • 有些机器有多个 nezha-agent 服务,只重启了一个

  • hostyun-us 的 IP 从 45.155.222.112 换到了 207.57.137.18


六、复发!发现真正的根因

清理 sysmon 后做全量复查,发现 sysmon 后门 0 复发,但发现了更危险的东西。

第二份 config 后门

34 台服务器的 /opt/nezha/agent/ 目录下,除了合法的 config.yml,还存在随机命名的 config-XXXXX.yml

字段

恶意配置 (config-XXXXX.yml)

合法配置 (config.yml)

server

207.58.173.192:8088

ip:8008

disable_command_execute

false(远程命令开启)

true(已加固)

文件名

随机 5 位后缀

无后缀

关键证据

  1. IP (我的主控),确认 config.yml 是合法配置

  2. 207.58.173.192:8088 当前无法连接,但配置和进程仍在

  3. 主控上恶意 agent 进程(PID 911,config-etp0h.yml → 207.58.173.192:8088)一直在运行

  4. 34 台的恶意配置文件名都是随机 5 位后缀,说明是自动化批量投放

为什么这比 sysmon 更危险

维度

sysmon 后门

第二份 config 后门

二进制

独立假 agent (/usr/local/sysmon)

合法 nezha-agent

配置

独立 config.yml

config-XXXXX.yml 混在合法配置目录

守护

sysmon-guard.timer 30 秒

systemd nezha-agent-XXX.service

注入

ld.so.preload

隐蔽性

低(独立路径明显)

高(混在合法 agent 目录里)

命令执行

通过 C2 面板

通过攻击者 nezha 面板

这是真正的复发根因:攻击者不植入独立二进制,而是利用合法 nezha-agent 二进制 + 额外配置文件。即使清理了 sysmon,攻击者仍可通过合法 nezha-agent + 恶意配置维持对 34 台服务器的远程命令执行能力。


七、第二轮清理:第二份 config 后门

清理逻辑

# 1. 找出所有 config-*.yml(带随机后缀的恶意配置)
for cfg in /opt/nezha/agent/config-*.yml; do
  # 2. 找对应 service 并停用
  for svc in $(systemctl list-units | grep nezha-agent-); do
    svc_cfg=$(systemctl cat "$svc" | grep -oE "/opt/nezha/agent/config[^ ]*\.yml")
    if [ "$svc_cfg" = "$cfg" ]; then
      systemctl stop "$svc"
      systemctl disable "$svc"
      rm -f "/etc/systemd/system/$svc"
    fi
  done
  # 3. 杀进程
  pkill -9 -f "$(basename $cfg .yml)"
  # 4. 删配置
  rm -f "$cfg"
done
systemctl daemon-reload

# 5. 加固合法 config.yml
sed -i 's/^disable_command_execute:.*/disable_command_execute: true/' /opt/nezha/agent/config.yml
systemctl restart nezha-agent.service

清理结果

  • 37 台成功清理:删除 35 个恶意配置 + 35 个恶意服务

  • 3 台超时:raksmart-圣何塞、云曦幻境、geelinx-b

  • 所有成功清理的服务器:AFTER 状态只剩 config.yml + nezha-agent.service,网络检查全部 CLEAN


八、深度复查

清理后对 40 台服务器做 19 项深度 IOC 扫描:

  1. sysmon 后门文件

  2. ld.so.preload 注入

  3. 第二份 config 后门

  4. 合法 config 加固状态

  5. nezha 服务列表

  6. 挖矿木马进程

  7. sysmon 相关进程

  8. 攻击者网络连接

  9. cron 持久化

  10. systemd 可疑服务

  11. SSH authorized_keys

  12. 登录记录

  13. SUID 文件

  14. /tmp 隐藏文件

  15. 可疑定时器

  16. CPU 占用

  17. 异常监听端口

  18. rc.local/profile.d

  19. 内核模块

结果

检查项

结果

sysmon 后门残留

0

第二份 config 后门

0

挖矿木马进程

0

到攻击者面板连接

0

ld.so.preload libsysmon

0

可疑 cron/systemd

2 台(腾讯云官方 stargate,已核实非恶意)

完全干净

34/36

结论:sysmon 后门和第二份 config 后门均无复发,未发现新的木马或黑客遗留。


九、自动化加固

1. 关闭远程命令能力

所有 34 台 nezha 节点的 config.yml 已设置:

disable_command_execute: true   # 关闭远程命令执行(terminal/webssh)
disable_nat: true               # 关闭 NAT 穿透

2. Dashboard 自动更新(Watchtower)

部署 Watchtower 容器实现 dashboard 自动更新:

docker run -d \
  --name watchtower \
  --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower \
  --cleanup \
  --interval 3600 \
  nezha-dashboard
  • 每小时检查 ghcr.io/nezhahq/nezha:latest 是否有新镜像

  • 有新版自动拉取并重启 nezha-dashboard 容器

  • 只监控 nezha-dashboard,不影响其他容器

  • GitHub 发布新版后,最多 1 小时内自动更新,无需手动介入

3. Agent 自动更新

修改 agent 配置:

disable_auto_update: false      # 开启自动更新
disable_force_update: false     # 允许主控下发强制更新
disable_command_execute: true   # 保持远程命令关闭

GitHub 发布新版 agent 后,各节点自动更新,无需手动介入。


十、复发根因分析

后门清理后再次出现,通常是以下原因之一:

  1. ★第二份 config 后门未清理(最隐蔽):清理了 sysmon 但没检查 config-XXXXX.yml,攻击者通过合法 nezha-agent + 恶意配置维持控制。这是本次事件复发的真正根因。

  2. 残留自恢复链路:sysmon-guard.timer / cron / ld.so.preload / 隐藏脚本任一残留

  3. 攻击者仍有登录入口:root 密码、SSH key、面板账号、Agent Secret、JWT Secret 任一泄露

  4. Nezha 远程命令未及时关闭:低版本暴露期间攻击者拿到面板 token,能继续下发命令

  5. 同机其他面板漏洞:1Panel / 宝塔 / x-ui / MCSManager / phpMyAdmin / MySQL / Redis 暴露公网

  6. 清理顺序错误:先删文件没先停守护 → 守护器重建文件

  7. 密码未轮换:清理后没换 root 密码 / SSH key


十一、经验教训

1. 不要只查一种后门

sysmon 后门特征明显(独立路径 + ld.so.preload),容易发现也容易清理。但第二份 config 后门极隐蔽(合法二进制 + 混在配置目录),清理完 sysmon 后必须复查是否有 config-XXXXX.yml

2. 清理顺序很重要

停守护 → 杀进程 → 删文件 → 清 ld.so.preload → daemon-reload

顺序错了,守护器会重建文件,等于白清理。

3. Nezha 版本读取的坑

公开 WebSocket 的 host.version 在访客视图下是 null,必须用管理员 JWT 才能看到真实版本。这会导致误判"所有 agent 版本未知",延迟发现旧版节点。

4. Windows SSH 中文路径

Windows 上 OpenSSH 对含中文/空格的私钥路径处理不可靠,必须复制到 ASCII 临时路径 + icacls 收紧 ACL + 用系统自带 C:\Windows\System32\OpenSSH\ssh.exe

5. 批量操作用 paramiko

系统无 sshpass/expect 时,paramiko 是批量 SSH 的最佳选择。密码只在内存中,绝不落盘。

6. 自动更新很重要

这次事件根因是低版本漏洞被利用。部署 Watchtower + 开启 agent 自动更新后,未来 GitHub 发新版会自动更新,不再需要手动介入。

7. 安全加固清单

  • 升级 Dashboard 到最新版(2.2.3)

  • 升级所有 Agent 到最新版(2.2.2)

  • 清理 sysmon 后门

  • 清理第二份 config 后门

  • 关闭远程命令执行(disable_command_execute: true)

  • 部署 Watchtower 实现 Dashboard 自动更新

  • 开启 Agent 自动更新

  • 轮换 root 密码

  • 轮换 SSH key

  • 轮换 Nezha 面板密码

  • 轮换 Agent Secret

  • 轮换 JWT Secret

  • 关闭非必要公网面板入口


十二、开源工具

本次事件中开发的清理脚本已开源:

一键使用

curl -fsSL https://raw.githubusercontent.com/motao123/clean_malware_and_harden_nezha/main/clean_malware_and_harden_nezha.sh -o /root/clean.sh
bash /root/clean.sh

群发排查命令

如果你也想检查自己的服务器是否中招:

# sysmon 后门排查
ls -ld /usr/local/sysmon /usr/local/.sysmon-guard /usr/local/lib/libsysmon.so /etc/systemd/system/sysmon* /etc/ld.so.preload 2>/dev/null

# 第二份 config 后门排查
ls /opt/nezha/agent/config-*.yml 2>/dev/null && echo "WARNING: second config backdoor detected"

# 挖矿木马排查
ps auxww | grep -Ei "sysmon|kworker|kdevtmpfsi|kinsing|xmrig" | grep -v grep

# 攻击者连接排查
ss -tnp | grep -E "51.254.44.35|207.58.173.192"

十三、事件时间线

2026-06-19  攻击者利用低版本漏洞植入 sysmon 后门 + 第二份 config 后门
2026-06-20 00:30  发现 Nezha 安全公告,开始排查
2026-06-20 00:45  确认主控 dashboard 2.2.3 不受影响,5 台 agent 为 1.9.7
2026-06-20 00:51  发现主控 sysmon 后门,开始清理
2026-06-20 01:00  sysmon 后门清理完成(主控)
2026-06-20 01:15  批量清理 40 台 sysmon 后门
2026-06-20 01:30  批量升级旧版 agent 到 2.2.2
2026-06-20 02:00  hostyun-us IP 变更,手动修复
2026-06-20 10:25  第一次复发复查:sysmon 0 复发,但发现 34 台第二份 config 后门
2026-06-20 11:00  定位复发根因:第二份 config 后门(config-XXXXX.yml → 207.58.173.192:8088)
2026-06-20 11:47  批量清理第二份 config 后门(37 台成功)
2026-06-20 11:52  更新清理脚本并推送 GitHub
2026-06-20 12:00  深度复查 40 台(19 项检查全部通过)
2026-06-20 12:07  部署 Watchtower + 开启自动更新
2026-06-20 12:13  撰写本文档

总结

这次事件的核心教训:清理了一种后门不等于清理了所有后门。sysmon 后门特征明显容易被发现,但第二份 config 后门利用合法二进制 + 混在配置目录里,隐蔽性极强。如果不是做了深度复查,攻击者仍可通过 34 台服务器的合法 nezha-agent 维持远程命令执行能力。

安全是一个持续的过程,不是一次性的操作。清理后门只是第一步,还需要:升级版本、关闭远程能力、开启自动更新、轮换凭据、关闭非必要公网入口。只有全链路加固,才能避免再次被入侵。


本文档基于真实事件整理,相关清理工具已开源:https://github.com/motao123/clean_malware_and_harden_nezha


评论