教程:记一次“systemd helper”挖矿病毒的深度分析与清除实战

大家好,这是一份关于Linux服务器安全的技术分享。如果你在服务器上通过 htoptop 命令发现一个名为 systemd helper.systemd-helper 的进程持续占用高额CPU(通常是100%或更高),那么你的服务器很可能被入侵了。

本文将复盘一次真实的清除过程,详细分析这个恶意软件的“狡猾”之处,并提供一套完整的、可复现的清除步骤。


🐛 一、问题分析:我究竟遇到了什么?

我们遇到的不是一个简单的病毒,而是一个精心设计、具有多层防护机制的恶意软件(大概率是加密货币挖矿程序)。

🚨 初始症状

  • htop 中显示一个名为 systemd helper 的进程,由 ubuntu(或其他普通用户)或 root 启动,CPU 占用率拉满。
  • 尝试 kill -9 <PID> 进程,进程会立刻自动重启。

🕵️ 对方做了什么(攻击手段分析)

这个恶意软件为了“活下去”并持续地压榨你服务器的CPU,至少做了四件事:

1. 伪装 (Masquerading)

  • 它将进程命名为 systemd helper,并将恶意服务文件命名为 systemd-journald.service
  • systemdjournald 是Linux最核心的系统服务(初始化系统和日志服务)。攻击者故意使用相似的名字,就是为了混淆视听,让你误以为这是正常系统进程而不敢随意终止它。

2. 隐藏 (Obfuscation)

  • 它没有把可执行文件放在 /usr/bin 等常规路径,而是放在了一个非常规的隐藏目录下。
  • 在我们的案例中,路径是:/usr/lib/.sysd/.bin/.systemd-helper。在Linux中,以 . 开头的都是隐藏文件/目录,ls 默认不显示,增加了排查难度。

3. 持久化与劫持 (Persistence & Hijacking)

  • 攻击者在 /etc/systemd/system/ 目录下创建了一个恶意的 systemd-journald.service 文件。
  • Linux会优先加载 /etc/systemd/system/ 目录下的服务配置,而不是系统默认的 /lib/systemd/system/
  • 这相当于它“劫持”了系统正常的日志服务,让 systemd 以为这个恶意程序就是“官方”的日志服务。

4. 多层守护(最关键的对抗手段)

  • 第一层守护 - Socket Activation (套接字激活):
    • 我们发现,kill 进程无效,systemctl stop systemd-journald.service 也无效,服务会马上重启。
    • 原因: 攻击者利用了系统原有的 systemd-journald.socket。这是一个合法文件,它负责监听日志请求。一旦有任何程序想写日志,socket 就会被触发,然后自动去启动 systemd-journald.service。由于服务已经被劫持,socket 启动的自然是那个恶意程序。
  • 第二层守护 - File Locking (文件锁定):
    • 当我们试图 rm -f /etc/systemd/system/systemd-journald.service 删除恶意服务文件时,即使是 root 用户也收到了 Operation not permitted (操作不允许) 的错误。
    • 原因: 攻击者给这个文件上了一个“锁”。通过 chattr +i 命令(i 代表 immutable,不可变),这个文件变得无法被删除、修改或重命名,即使是 root 也不行。这是恶意软件防止自身被清除的终极手段。

🛡️ 二、解决过程:如何“拆弹”

我们必须像拆除定时炸弹一样,按照正确的顺序解除它的多层守护。

核心思路: 必须先拆除“自动重启”机制,再解除“文件锁定”,最后才能删除文件本体。

拆解步骤

  1. 识别元凶
    通过 htop 找到高CPU进程的 PID(例如 2725)。

    # 查看该PID属于哪个服务systemctl status 2725

    输出会暴露恶意软件的两个关键信息:

    • 服务文件路径: Loaded: loaded (/etc/systemd/system/systemd-journald.service; ...)
    • 可执行文件路径: ... /usr/lib/.sysd/.bin/.systemd-helper
  2. 打破“套接字激活”循环(关键)
    stop 服务本身是没用的,必须先停止触发它的 socket

    # 停止所有相关的合法套接字sudo systemctl stop systemd-journald.socketsudo systemctl stop systemd-journald-dev-log.socketsudo systemctl stop systemd-journald-audit.socket

    这一步切断了自动重启的源头。

  3. 停止并禁用恶意服务
    现在 socket 被关了,我们可以安全地停止并禁用服务了。

    # 停止当前还在运行的恶意进程sudo systemctl stop systemd-journald.service# 禁用该服务,防止开机自启sudo systemctl disable systemd-journald.service
  4. 解除“文件锁定”(关键)
    此时直接 rm 依然会失败。我们需要先“解锁”。

    # 1. 检查文件属性,会看到 'i' 属性lsattr /etc/systemd/system/systemd-journald.service

    输出示例:
    ----i--------- /etc/systemd/system/systemd-journald.service

    # 2. 移除不可变(immutable)属性sudo chattr -i /etc/systemd/system/systemd-journald.service
  5. 彻底清除恶意文件
    现在所有的防护都已被解除,可以收尾了。

    # 1. 删除被劫持的服务文件sudo rm -f /etc/systemd/system/systemd-journald.service# 2. 删除恶意程序的老巢(整个.sysd目录)sudo rm -rf /usr/lib/.sysd/
  6. 恢复系统
    最后,让 systemd 重新加载配置,并重启我们需要的正常服务。

    # 重新加载systemd配置,让它忘记被删除的恶意服务sudo systemctl daemon-reload# (可选)重启正常的日志服务sudo systemctl start systemd-journald.servicesudo systemctl start systemd-journald.socket

    此时再次运行 htop,世界清静了。


💡 三、反思:我的服务器是如何被入侵的?

清除了病毒,更要思考漏洞在哪里。这类挖矿程序最常见的入侵途径有:

  1. SSH 弱密码/泄露
    攻击者通过自动化工具爆破了你的 root 或其他用户的登录密码。

  2. 暴露的危险端口(最常见)

    • Docker API (2375/2376): 很多人图方便,把 Docker API 暴露在公网且未加任何认证。攻击者可以直接通过 API 在你的服务器上创建并运行一个挖矿容器。
    • Redis (6379): 未设置密码认证的 Redis 数据库暴露在公网,攻击者可以利用它写入 crontabssh 密钥。
    • Hadoop / YARN (8088): 未授权访问的 YARN,允许攻击者提交恶意任务。
  3. 系统或应用漏洞
    你的服务器上部署的网站、管理面板(如宝塔)或系统组件(如 sshd)存在未修复的漏洞。

🔐 解决(安全建议)

  • SSH 安全

    • 禁用密码登录! 只使用密钥(ssh-key)登录。
    • 如果必须使用密码,请确保它是16位以上的超复杂密码。
    • 禁止 root 用户直接登录。
  • 防火墙

    • 配置 ufwfirewalld 或云服务商的安全组。
    • 白名单原则: 只开放你明确需要对外提供服务的端口(如 80, 443, 22),其他端口一律禁止公网访问。
  • 及时更新

    • 定期执行 sudo apt update && sudo apt upgrade(或 yum update)来修补系统漏洞。