Linux 挖矿病毒深度排查与修复实录

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 (系统参数配置被修改)

这解释了为什么 topps 看不到高 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 操作时。

  • 检查文件类型:

    bash 复制代码
    busybox 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

最终确认:

  1. dpkg -V 再次检查无报错 ✓
  2. top, ps, ls 恢复正常 ✓
  3. 系统 CPU 占用率恢复正常 ✓

此时以为修复完成。


第六阶段:发现持久化机制

6.1 重启后病毒重生

重启机器后,运行 unhide 进行验证:

bash 复制代码
unhide proc

结果显示大量隐藏进程再次出现(PID 1489 等)。

执行文件名变为随机 8 位 16 进制字符串(如 /ebc626c2),文件位于根目录 / 且处于 (deleted) 状态。

/etc/sysctl.conf 再次被篡改。

分析:

  • 之前的修复清除了"驻留内存的进程"和"被篡改的命令",但没有找到真正的启动源(Loader/Dropper)。
  • 病毒利用某种持久化机制在系统启动时再次释放并运行。

结论:问题不光在系统命令,还有定时任务或服务在自动启动病毒。

6.2 排查持久化机制

开始系统性地排查所有可能的持久化机制:

  1. 动态链接库劫持:

    bash 复制代码
    cat /etc/ld.so.preload

    不存在(干净)✓

  2. 配置文件分析:

    bash 复制代码
    tail -n 20 /etc/sysctl.conf

    发现异常配置 fs.file-max = 2097152

    将文件描述符限制调至 200 万,这是典型的挖矿/僵尸网络特征

  3. Cron 的漏网之鱼:

    bash 复制代码
    ls -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 最终核查

确保万无一失:

  1. 服务文件确认:

    bash 复制代码
    find /etc/systemd /lib/systemd -name "*tmuxinfo*"

    应无输出 ✓

  2. SSH 后门确认:

    bash 复制代码
    cat /root/.ssh/authorized_keys

    确保只包含你自己的公钥 ✓

  3. 传统启动目录:

    bash 复制代码
    ls -lt /etc/init.d/ | head

    未发现最近生成的异常脚本 ✓


第八阶段:最终验证

8.1 重启验证

重启系统:

bash 复制代码
reboot

验证清除结果:

  • unhide proc: 未发现隐藏进程
  • top: CPU 占用率恢复正常 ✓
  • dpkg -V: 核心文件完整性校验通过 ✓
  • /etc/sysctl.conf: 未被篡改 ✓

至此,病毒已被彻底清除。


经验总结

核心难点与对策

  1. 常规命令不可信

    • 现象: ps, top, ls 都被篡改
    • 对策: 使用 busybox, unhide 等独立工具
  2. 文件被加锁且解锁工具被毁

    • 现象: +i 属性锁定,chattr 被替换
    • 对策: Python ioctl 内核调用 + 文件重命名
  3. 杀进程后无限重生

    • 现象: 清除进程和系统命令后重启仍然复发
    • 对策: 深度排查 Systemd 服务,找到伪装的 .service 文件

总结 : 这是一次典型的 Rootkit 对抗。病毒通过替换 ps/top 隐藏 CPU 占用,替换 ls 隐藏文件,替换 chattr 防止被删,并利用 +i 属性构筑防御工事,最后通过 Systemd 服务实现持久化。破局的关键在于不信任系统命令 ,使用 busybox 和原生语言(Python)直接调用内核接口,以及深度排查 Systemd 服务。

相关推荐
一个有温度的技术博主6 小时前
网安实验系列七:域名收集
linux·运维·服务器
我爱学习好爱好爱6 小时前
Ansible 环境搭建
linux·运维·ansible
人工智能训练6 小时前
从 1.1.3 到 1.13.2!Ubuntu 24.04 上 Dify 升级保姆级教程(零数据丢失 + 一键迁移)
linux·运维·人工智能·windows·ubuntu·dify
我要成为嵌入式大佬7 小时前
正点原子MP157--问题详解--四(关于根文件系统驱动模块指令的注意事项)
linux·运维·服务器
feng68_7 小时前
Redis架构实践
linux·运维·redis·架构·bootstrap
欧云服务器7 小时前
宝塔计划任务怎么自动删除多少个以外的文件?
linux·运维·服务器
XXOOXRT7 小时前
零基础掌握Linux常用命令
linux·运维·服务器
迷海8 小时前
Linux g++编译与GDB调试完整流程(文末附图)
linux·gdb调试工具·g++编译器
softbangong8 小时前
815-批量Excel文件合并工具,批量excel文件、工作表合并软件
linux·windows·excel·文件合并·excel合并·数据整理
123过去8 小时前
responder使用教程
linux·网络·测试工具·安全·哈希算法