Linux 挖矿病毒深度排查与修复实录
记录时间 : 2026-02-12
环境 : Ubuntu
事件概述 : 服务器异常卡顿,遭遇挖矿病毒入侵,创建大量挖矿进程,系统核心命令 (ps, ls, chattr, apt) 被篡改以隐藏行踪。
第一阶段:发现异常
1.1 服务器卡顿
服务器 CPU 占用率持续飙高,SSH 连接响应极其缓慢。第一反应是查看进程:
bash
top
ps -ef
然而出现了异常情况------所有进程的 CPU 占用率加起来不到 20%。
这明显不对。系统监控显示 CPU 使用率在 90% 以上,但进程列表里却找不到对应的高占用进程。这种现象通常意味着存在隐藏进程,系统监控命令可能已被篡改。
1.2 尝试安装检测工具
既然常规手段看不到,准备安装 unhide 工具进行暴力枚举检测:
bash
apt-get install unhide
然而 apt 报错了:
dpkg: error processing archive ...
unable to make backup link of './usr/bin/chattr' before installing new version: Operation not permitted
Operation not permitted?
这个错误通常意味着文件被加了不可变属性(+i)。
第二阶段:发现 chattr 被篡改
2.1 尝试解锁 chattr
查看文件属性:
bash
lsattr /usr/bin/chattr
显示 ----i---------e-----,文件被锁死了。
尝试解锁:
bash
chattr -i /usr/bin/chattr
命令执行后,屏幕上出现了一堆乱码,然后显示:
Usage: vmlinux1 ...
vmlinux1? 这个名字引起了注意。vmlinux 通常是 Linux 内核的可执行文件名,但它不应该出现在 chattr 的输出里。
chattr 命令本身也被病毒替换了。 病毒把自己伪装成 vmlinux1(模仿内核文件名),然后替换了系统的 chattr 命令。
病毒的防御策略非常完善------不仅用 +i 属性锁定了文件,还把解锁工具 chattr 也替换成了假的。
2.2 Python 强制解锁
既然系统工具已经不可信,直接用 Python 调用 Linux 内核接口(ioctl)修改文件属性,绕过被篡改的 chattr 命令。
编写代码(fix_chattr.py):
python
import os, fcntl, struct
# 直接操作文件描述符,绕过坏掉的 chattr 命令
fd = os.open('/usr/bin/chattr', os.O_RDONLY)
op = 0x40086602 # FS_IOC_SETFLAGS 魔数
val = struct.pack('L', 0) # 清除所有标志
fcntl.ioctl(fd, op, val)
os.close(fd)
运行:
bash
python3 fix_chattr.py
成功。
2.3 删除被篡改的 chattr 和vmlinux1
删除被篡改的 chattr:
bash
rm -f /usr/bin/chattr
重新安装:
bash
apt --fix-broken install
删除 vmlinux1:
bash
rm -f /usr/bin/vmlinux1
第三阶段:发现隐藏进程
3.1 使用 unhide 检测
现在 apt 可以正常工作了,安装并运行 unhide:
bash
apt-get install unhide
unhide proc
果然,扫出了隐藏进程 PID 1954(以及 1949 等子进程)。
这下确认了------这是一个典型的 Rootkit 行为,它不仅在挖矿,还把自己从进程列表里隐藏了。
3.2 尝试查看进程信息
想查看进程的可执行文件信息,但发现文件已经被删除(显示 (deleted))。
那就查看 /proc 下的进程信息:
bash
ls -ld /proc/1954
结果:
ls: cannot access '/proc/1954': No such file or directory
unhide 刚扫出来的进程,/proc 目录却不存在。再次尝试:
bash
ls -l /proc/ | grep 1954
仍然没有。
这不可能------进程确实存在,但 ls 看不到。这引发了一个疑问:ls 命令本身是否也被篡改了?
第四阶段:发现系统命令被劫持
4.1 使用 busybox 验证
使用 busybox(一个静态编译的工具集,不依赖系统库)进行验证:
bash
busybox ls -ld /proc/1954
结果:
dr-xr-xr-x 9 root root 0 Feb 12 10:23 /proc/1954
目录确实存在。这证实了猜测------系统自带的 ls 命令已被篡改。
这不是普通的挖矿病毒,而是一个精心设计的 Rootkit。它不仅隐藏了进程,还修改了系统最基础的查看命令,在输出时自动过滤掉特定 PID 的目录。
4.2 查看进程详细信息
使用 busybox 查看进程信息:
bash
busybox cat /proc/1954/status | grep PPid
busybox ls -l /proc/1954/exe
发现:
- 父进程是 1 (init/systemd):病毒已经完全"守护进程化",或者是由系统服务直接启动的。
- 进程名是随机字符串 :
/usr/bin/a9213172,每次重启都会变。 - 执行文件显示
(deleted):病毒启动后立即删除了自身文件,只驻留在内存中。
这是典型的"无文件攻击"(Fileless Attack)。
4.3 怀疑整个核心包被污染
既然 ls 被篡改了,那么其他核心命令很可能也被污染了。运行 dpkg --verify 进行全面检查:
bash
dpkg --verify coreutils systemd init procps bash
结果显示大量核心工具的 MD5 校验失败:
/bin/ls,/bin/dir(文件查看命令被篡改)/bin/systemctl(服务管理命令被篡改)/usr/bin/uptime,/usr/bin/w(负载查看命令被篡改,用于伪造低 CPU 占用)/etc/sysctl.conf(系统参数配置被修改)
这解释了为什么 top 和 ps 看不到高 CPU 进程------这些监控命令都被修改了,在输出时会自动隐藏病毒进程的资源占用。
结论:必须先修复系统命令,否则后面即使找到了病毒位置也看不到,无法删除。
第五阶段:修复系统命令
5.1 尝试重装核心包
试图重装这些核心工具:
bash
apt-get install --reinstall coreutils systemd procps
又报错了:
unable to make backup link of './bin/dir' ... Operation not permitted
病毒极其狡猾,它不仅篡改了这些核心文件,还给它们也加了 +i 锁。
5.2 Python 批量解锁失败
尝试用之前成功的 Python 脚本方法批量解锁:
python
import os, fcntl, struct
files = ['/bin/dir', '/bin/ls', '/bin/systemctl', '/usr/bin/uptime', '/usr/bin/w']
for f in files:
try:
fd = os.open(f, os.O_RDONLY)
op = 0x40086602 # FS_IOC_SETFLAGS
val = struct.pack('L', 0)
fcntl.ioctl(fd, op, val)
os.close(fd)
print(f"Unlocked {f}")
except Exception as e:
print(f"Failed {f}: {e}")
运行后发现部分文件报错:
Failed /bin/dir: [Errno 95] Operation not supported
Failed /bin/ls: [Errno 95] Operation not supported
分析原因:
-
[Errno 95] Operation not supported通常出现在对软链接或特殊文件类型执行ioctl操作时。 -
检查文件类型:
bashbusybox ls -l /bin/dir /bin/ls发现这些文件可能是软链接,或者病毒使用了特殊的文件系统属性,导致
ioctl调用失败。
这意味着之前的 Python 内核调用方法在这些文件上失效了。
5.3 文件重命名破局
既然无法原位解锁,采用了另一个方案:直接把被篡改的文件重命名,为新文件腾出位置。
编写脚本(fix_core.py):
python
import os, fcntl, struct
# 目标文件列表 (包含 /bin 和 /usr/bin 两种可能)
targets = [
'/bin/dir', '/usr/bin/dir',
'/bin/ls', '/usr/bin/ls',
'/bin/systemctl', '/usr/bin/systemctl',
'/usr/bin/uptime',
'/usr/bin/w'
]
# 解锁指令
op = 0x40086602
val = struct.pack('L', 0)
for f in targets:
if not os.path.exists(f):
continue
print(f"Processing: {f}")
# 1. 尝试解锁 (忽略不支持的错误)
try:
fd = os.open(f, os.O_RDONLY)
fcntl.ioctl(fd, op, val)
os.close(fd)
print(" Unlock: OK")
except Exception as e:
print(f" Unlock: {e}")
# 2. 尝试改名 (备份移走)
try:
os.rename(f, f + ".virus")
print(" Rename: OK")
except Exception as e:
print(f" Rename: {e}")
# 3. 如果改名失败,尝试删除
try:
os.unlink(f)
print(" Delete: OK")
except Exception as e:
print(f" Delete: {e}")
print("Done. Now try apt-get install again.")
运行后,成功将所有被锁定的病毒文件移走。
5.4 重新安装核心包
然后重新安装:
bash
apt-get install --reinstall coreutils systemd procps
这次安装成功了。通过文件重命名绕过了 +i 属性的限制,因为重命名操作不需要修改文件内容,只需要修改目录项。
5.5 补救遗漏的配置文件
校验:
bash
dpkg --verify coreutils systemd init procps bash
发现遗漏:提示 missing c /etc/sysctl.conf。
强制恢复缺失的配置文件:
bash
apt-get -o Dpkg::Options::="--force-confmiss" install --reinstall procps
最终确认:
dpkg -V再次检查无报错 ✓top,ps,ls恢复正常 ✓- 系统 CPU 占用率恢复正常 ✓
此时以为修复完成。
第六阶段:发现持久化机制
6.1 重启后病毒重生
重启机器后,运行 unhide 进行验证:
bash
unhide proc
结果显示大量隐藏进程再次出现(PID 1489 等)。
执行文件名变为随机 8 位 16 进制字符串(如 /ebc626c2),文件位于根目录 / 且处于 (deleted) 状态。
/etc/sysctl.conf 再次被篡改。
分析:
- 之前的修复清除了"驻留内存的进程"和"被篡改的命令",但没有找到真正的启动源(Loader/Dropper)。
- 病毒利用某种持久化机制在系统启动时再次释放并运行。
结论:问题不光在系统命令,还有定时任务或服务在自动启动病毒。
6.2 排查持久化机制
开始系统性地排查所有可能的持久化机制:
-
动态链接库劫持:
bashcat /etc/ld.so.preload不存在(干净)✓
-
配置文件分析:
bashtail -n 20 /etc/sysctl.conf发现异常配置
fs.file-max = 2097152。将文件描述符限制调至 200 万,这是典型的挖矿/僵尸网络特征。
-
Cron 的漏网之鱼:
bashls -la /etc/cron.d/ ls -la /var/spool/cron/crontabs/目录正常,无明显恶意任务 ✓
6.3 检查最近改动的服务
既然 Cron 和动态库劫持都没问题,病毒极有可能注册了一个伪装的 Systemd 服务。
查找最近 7 天内被修改过的服务文件:
bash
find /etc/systemd/system /lib/systemd/system -name "*.service" -mtime -7
找到了可疑文件:
/etc/systemd/system/multi-user.target.wants/tmuxinfo2d09ef78.service
查看内容:
ini
[Service]
ExecStart=/usr/bin/tmuxinfo2d09ef78c6c1c63c tmuxinfo2d09ef78
Restart=always
这就是持久化的源头。
一个伪装成 tmux 相关服务的病毒守护进程,配置为 Restart=always,这解释了为什么杀掉进程后它会立即重启,以及为什么重启后病毒会再次出现。
第七阶段:彻底清除
7.1 清除持久化服务
停止并禁用服务:
bash
systemctl stop tmuxinfo2d09ef78.service
systemctl disable tmuxinfo2d09ef78.service
删除服务文件:
bash
rm /etc/systemd/system/multi-user.target.wants/tmuxinfo2d09ef78.service
systemctl daemon-reload
查找并删除残留的 service 文件:
bash
find /etc/systemd /lib/systemd -name "tmuxinfo2d09ef78.service" -delete
systemctl daemon-reload
7.2 清除病毒主程序
检查是否有锁:
bash
lsattr /usr/bin/tmuxinfo2d09ef78c6c1c63c
解锁并删除:
bash
chattr -i /usr/bin/tmuxinfo2d09ef78c6c1c63c
rm -f /usr/bin/tmuxinfo2d09ef78c6c1c63c
杀掉残留进程:
bash
killall -9 tmuxinfo2d09ef78c6c1c63c
kill -9 1489 1490 1491
7.3 清理其他后门
删除 SSH 后门:
bash
cat /root/.ssh/authorized_keys
# 删除其中被添加的恶意公钥
7.4 最终核查
确保万无一失:
-
服务文件确认:
bashfind /etc/systemd /lib/systemd -name "*tmuxinfo*"应无输出 ✓
-
SSH 后门确认:
bashcat /root/.ssh/authorized_keys确保只包含你自己的公钥 ✓
-
传统启动目录:
bashls -lt /etc/init.d/ | head未发现最近生成的异常脚本 ✓
第八阶段:最终验证
8.1 重启验证
重启系统:
bash
reboot
验证清除结果:
unhide proc: 未发现隐藏进程 ✓top: CPU 占用率恢复正常 ✓dpkg -V: 核心文件完整性校验通过 ✓/etc/sysctl.conf: 未被篡改 ✓
至此,病毒已被彻底清除。
经验总结
核心难点与对策
-
常规命令不可信
- 现象:
ps,top,ls都被篡改 - 对策: 使用
busybox,unhide等独立工具
- 现象:
-
文件被加锁且解锁工具被毁
- 现象:
+i属性锁定,chattr被替换 - 对策: Python
ioctl内核调用 + 文件重命名
- 现象:
-
杀进程后无限重生
- 现象: 清除进程和系统命令后重启仍然复发
- 对策: 深度排查 Systemd 服务,找到伪装的
.service文件
总结 : 这是一次典型的 Rootkit 对抗。病毒通过替换 ps/top 隐藏 CPU 占用,替换 ls 隐藏文件,替换 chattr 防止被删,并利用 +i 属性构筑防御工事,最后通过 Systemd 服务实现持久化。破局的关键在于不信任系统命令 ,使用 busybox 和原生语言(Python)直接调用内核接口,以及深度排查 Systemd 服务。