1. 缘起:一次意外的系统卡顿
那天下午我正在写代码,突然发现笔记本风扇狂转,敲个命令都要卡两三秒。作为常年把笔记本当服务器使的老油条,我第一反应是Chrome又吃内存了,但任务管理器里那个叫"kworker/0:3+events"的进程引起了我的注意——CPU占用率稳定在87%,这明显不正常。
经验之谈:Linux下名为kworker的内核线程本应是动态创建的短期进程,如果某个kworker持续高占用且带有奇怪后缀,八成是挖矿木马在作妖。
随手查了下进程树,这个挂着events后缀的kworker居然是个套壳进程。真正的元凶藏在/proc/pid/exe指向的/tmp/.X11-unix/.rsync/...目录下,路径深度堪比俄罗斯套娃。更诡异的是,用ls查看这个目录时报错"No such file or directory",但ps和top却明明白白显示着进程信息——典型的rootkit特征。
2. 初阶排查:那些容易被忽略的蛛丝马迹
2.1 系统基础状态检查
先从基础命令开始收集证据。用dmesg看到一堆segfault报错,指向libcrypto.so.1.1这个OpenSSL库。正常系统调用绝不会频繁段错误,这明显是动态库被劫持的迹象。接着发现:
# 查看异常网络连接 ss -tulnp | grep -E '127.0.0.1|::1' # 检查计划任务 crontab -l ; ls -la /etc/cron* # 查看最近修改的可执行文件 find /usr/bin /usr/sbin -type f -mtime -7发现三个可疑点:
- 本地回环地址上有非常规端口通信
- /etc/cron.daily里多了个名为logrotate的脚本(正经logrotate应该放在/etc/cron.hourly)
- /usr/bin/curl的修改时间比系统安装时间还新
2.2 动态链接器的小把戏
用ldd检查可疑进程的依赖库时,发现加载顺序异常:
ldd /proc/$(pidof kworker)/exe linux-vdso.so.1 => (0x00007ffd5a3f0000) /tmp/.X11-unix/.libs/libcrypto.so.1.1 => /lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007f3a5a3f0000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f3a5a3f1000)注意第二行的绝对路径写法!正常动态库加载应该是libcrypto.so.1.1 => /lib/x86_64-linux-gnu/libcrypto.so.1.1,这里却插入了/tmp下的路径。这是典型的LD_PRELOAD劫持变种——通过修改动态链接器的库搜索路径实现注入。
3. 进阶对抗:与rootkit的斗智斗勇
3.1 BusyBox的黑暗面
在/tmp下发现了个精简版busybox,这玩意儿堪称黑客瑞士军刀。攻击者用它实现了:
- 替换系统命令(netstat、ps等)
- 搭建简易HTTP服务器传输数据
- 通过tar+gzip打包窃取文件
最阴险的是,他们修改了busybox的源码,让ps auxf命令自动过滤掉挖矿进程的关键词。验证方法是用原始ps查看:
# 使用全路径调用系统命令 /bin/ps auxf | grep -E 'xmr|mine|pool|monero'3.2 内核模块的把戏
执行lsmod发现有个叫videobuf2_core的模块,名字看着像视频驱动,但实际是rootkit:
- 通过
dmesg | grep videobuf发现该模块在异常时间加载 modinfo videobuf2_core显示的作者邮箱是乱码cat /proc/kallsyms | grep videobuf显示该模块hook了系统调用表
临时应对方案是手动卸载模块并锁定:
rmmod videobuf2_core echo 'blacklist videobuf2_core' > /etc/modprobe.d/blacklist.conf4. 根治手段:从清理到防护的全套方案
4.1 彻底清理四步走
断网取证
ip link set eth0 down # 断开网络 dd if=/dev/sda1 of=/mnt/backup/infected_disk.img bs=1M # 磁盘全量备份关键文件清理
# 查找所有含矿池地址的文件 grep -rE 'xmr.*pool|monero.*mine' /tmp /var /etc 2>/dev/null # 清除异常定时任务 rm -f /etc/cron.*/*logrotate*系统命令修复
# 通过包管理器重新安装被篡改命令 apt install --reinstall coreutils procps net-tools内核级检查
# 检查系统调用表是否被hook grep -q '__x64_sys_' /proc/kallsyms || echo "System call table compromised!"
4.2 防护加固五件套
文件完整性监控
# 监控系统关键目录 apt install aide aideinit && mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db系统调用过滤
# 禁止非常规的execve调用 echo '-a always,exit -F arch=b64 -S execve -F uid!=0 -k suspicious_exec' >> /etc/audit/rules.d/audit.rules网络层防护
# 禁止出站连接到已知矿池 iptables -A OUTPUT -m string --string "xmrpool" --algo bm -j DROP用户空间限制
# 禁止普通用户执行tmp目录文件 echo 'none /tmp tmpfs nosuid,nodev,noexec 0 0' >> /etc/fstab行为监控脚本
# 监控异常CPU使用 while true; do [ $(top -bn1 | awk '/kworker/ && $9>30 {print $1}' | wc -l) -gt 2 ] && \ echo "Alert: Suspicious kworker detected at $(date)" >> /var/log/guardian.log sleep 30 done &
5. 事后复盘:那些教科书不会告诉你的经验
关于动态链接器劫持:现代Linux发行版的ld.so已经支持
--inhibit-cache选项,排查时应该这样用:LD_DEBUG=files /lib64/ld-linux-x86-64.so.2 --inhibit-cache /path/to/suspected_binary关于rootkit检测:当
lsmod也不可信时,可以直接读取/proc/modules,这个伪文件较难被篡改:awk '{print $1}' /proc/modules | sort | comm -23 - <(lsmod | awk 'NR>1{print $1}' | sort)关于进程隐藏:/proc目录下的进程信息其实有三重保障:
- 直接访问
/proc/pid目录 - 通过
/proc/pid/task/tid查看线程 - 使用
cat /proc/pid/status查看进程状态
- 直接访问
关于日志清理:高级攻击者会删除
/var/log下的日志,但别忘了检查:journalctl --since "3 days ago" | grep -i segfault dmesg --time-format ctime | grep -i 'error\|warning'
这次排查让我深刻体会到,现代挖矿木马早已不是简单的crontab定时任务+curl下载脚本了。从动态库注入到内核模块rootkit,从busybox工具链到内存驻留技术,攻击者正在用APT组织的手法玩转挖矿木马。保持系统更新固然重要,但培养"异常感知能力"才是根本——当你的电脑突然开始发烫,别急着怪Chrome,也许正有人用你的CPU在区块链上掘金呢。