修复React2Shell漏洞导致服务器权限泄露 之二

参考这篇分析报告,重新做一轮检查修复 https://www.huntress.com/blog/peerblight-linux-backdoor-exploits-react2shell

核心相似点:

  1. 伪装系统文件: 文章提到恶意软件会将自己伪装成看似合法的系统进程。你遇到的 /bin/systemd-daemon 正是这种典型手段(真正的 systemd 不在这个位置,也不叫这个名字)。
  2. 持久化机制: 利用 Systemd 服务(Service)进行驻留,确保杀不死、重启自愈。
  3. 行为模式: 作为“加载器(Dropper)”,定期从 C2 服务器(你的案例中是 185.196.9.41)下载并执行新的恶意脚本(um2)。

既然暂时不能重装系统,我们需要制定一个“外科手术式” 的深度清理方案。请务必按照以下步骤,一次性、连贯地执行,不要中断,以防病毒利用时间差复活。


深度清理方案 (无重装版)

第一阶段:切断通讯与锁定现场

在动手杀进程之前,先切断它与外界的联系,防止它接收指令或上传数据。

  1. 封锁恶意 IP (防火墙) 除了刚才的 IP,建议封锁整个网段(如果业务允许),或者只封锁该特定 IP。

    # 封锁你在日志中看到的恶意 IP
    iptables -I INPUT -s 185.196.9.41 -j DROP
    iptables -I OUTPUT -d 185.196.9.41 -j DROP
    
    # 如果有其他可疑 IP,继续添加。
    # 比如文章中提到的 C2 域名,如果有解析出 IP,也一并封锁。
    
  2. 修改 DNS (防止解析恶意域名) 暂时将服务器 DNS 修改为公共 DNS(如 8.8.8.8),防止被本地被篡改的 DNS 劫持。

    echo "nameserver 8.8.8.8" > /etc/resolv.conf
    

第二阶段:定位并移除服务 (关键步骤)

单纯 kill 进程没用,必须找到守护它的 Systemd 服务文件。

  1. 通过 PID 反查服务名 你之前的日志显示恶意进程 PID 是 729。运行以下命令找出它对应的服务文件:

    systemctl status 729
    
    • 观察输出: 寻找 Loaded: loaded (/etc/systemd/system/xxxx.service; ...) 这一行。
    • 记下: 那个 .service 文件的完整路径和名字(例如 system-daemon.servicesys-update.service)。
  2. 停止并禁用服务 假设服务名叫 malicious-service (请替换为你查到的名字):

    systemctl stop malicious-service
    systemctl disable malicious-service
    

第三阶段:解除锁定并删除文件

恶意软件通常使用 chattr +i (immutable) 属性锁定文件,导致 root 用户也无法直接删除。

  1. 处理母体文件 (/bin/systemd-daemon)

    # 解锁
    chattr -i /bin/systemd-daemon
    # 删除
    rm -f /bin/systemd-daemon
    
  2. 处理服务配置文件 (替换为你第二阶段查到的服务文件路径)

    chattr -i /etc/systemd/system/malicious-service.service
    rm -f /etc/systemd/system/malicious-service.service
    systemctl daemon-reload
    
  3. 处理临时目录残留 清理下载器脚本。

    rm -rf /tmp/um2
    rm -rf /tmp/xxvvxx
    # 检查 /var/tmp 是否有异常
    ls -al /var/tmp
    
  4. 处理之前的残留 (/etc/sshd) 如果你之前没删掉,现在一并处理:

    chattr -i /etc/sshd
    rm -f /etc/sshd
    

第四阶段:全盘扫描与清理定时任务

  1. 检查 Crontab (定时任务) 黑客可能在 Cron 里留了后手,每分钟检查一次文件是否存在,不存在就重新下载。

    # 检查所有用户的 cron
    cat /etc/crontab
    ls -la /etc/cron.d/
    ls -la /var/spool/cron/crontabs/
    
    # 重点查看 root 用户的
    crontab -l
    

    发现任何包含 wget, curl, base64, 或奇怪 IP 的行,立即删除。

  2. 检查 SSH 密钥 (再次强调) 这是黑客回来的大门。

    cat /root/.ssh/authorized_keys
    cat /home/admin/.ssh/authorized_keys
    

    只要不是你亲手放进去的 Key,全部删掉。

  3. 检查启动项 rc.local

    cat /etc/rc.local
    

    确保里面是空的,或者只有你认识的命令。

第五阶段:查找入侵入口 (防止再次感染)

文章中提到 React2Shell 往往利用 Web 应用漏洞(如 Redis 未授权访问、WebLogic 漏洞等)进入。

  1. 检查开放端口

    netstat -antlp
    
    • 看是否有 Redis (6379), Docker (2375), WebLogic (7001) 等端口对外开放?
    • 如果有,必须立即配置防火墙禁止外网访问这些端口,或者设置强密码。
  2. 检查最近修改的文件 查找最近 24 小时内被修改过的可执行文件,防止系统命令(如 ls, ps)被替换。

    find /bin /usr/bin /usr/sbin -type f -mtime -1
    

    如果发现 ls, ps, netstat 最近被修改过,说明系统命令被替换了(Rootkit),这时候不重装几乎无法修复。

总结

  1. 参考价值: 那篇文章确认了这是一次有组织、自动化的恶意软件攻击,利用 Systemd 进行持久化。
  2. 核心操作: systemctl status <PID> 找到服务 -> 停止服务 -> chattr -i 解锁文件 -> 删除文件 -> 清理 SSH Key。
  3. 最后防线: 如果执行完上述步骤,CPU 依然高占用,或者不明进程依然出现,说明可能植入了内核级 Rootkit。在那之后,除了重装系统,别无他法。

请按照上述步骤操作,并随时反馈任何新的报错或发现。

使用nft防火墙屏蔽IP

使用 nftables (nft) 屏蔽特定 IP 的逻辑是:在 inet (同时支持 IPv4/IPv6) 地址族的 filter 表中,分别在 input (入口) 和 output (出口) 链添加 drop 规则。

鉴于服务器正在遭受攻击,我们需要双向阻断该 IP (185.196.9.41)。

请按以下步骤操作:

1. 确认表和链是否存在

首先,我们需要确保你有一个可以承载规则的表。大多数系统默认使用 inet filter

运行以下命令查看当前配置:

nft list ruleset
  • 如果你看到 table inet filter 以及其中的 chain inputchain output,直接跳到步骤 3
  • 如果输出为空,或者没有这两个链,请先执行步骤 2

2. 创建基础表和链 (如果步骤1为空)

如果你的 nftables 是空的,需要先初始化:

# 创建一个名为 filter 的表,类型为 inet
nft add table inet filter

# 创建 input 链 (处理入站流量)
nft add chain inet filter input { type filter hook input priority 0 \; }

# 创建 output 链 (处理出站流量)
nft add chain inet filter output { type filter hook output priority 0 \; }

3. 添加屏蔽规则 (核心步骤)

执行以下命令,立即切断与恶意 IP 的所有连接。

屏蔽入站 (防止黑客再次连接你):

# 语法:在 inet filter 表的 input 链中,源 IP (saddr) 为恶意 IP 时,丢弃 (drop)
nft add rule inet filter input ip saddr 185.196.9.41 drop

屏蔽出站 (防止病毒下载后续木马或回传数据):

# 语法:在 inet filter 表的 output 链中,目的 IP (daddr) 为恶意 IP 时,丢弃 (drop)
nft add rule inet filter output ip daddr 185.196.9.41 drop

4. 验证规则是否生效

再次查看规则集,确认规则已添加:

nft list ruleset

你应该能看到类似这样的输出:

table inet filter {
    chain input {
        ...
        ip saddr 185.196.9.41 drop
    }
    chain output {
        ...
        ip daddr 185.196.9.41 drop
    }
}

5. (进阶) 屏蔽整个网段

黑客经常拥有同一个网段的多个 IP。如果你发现它换了个尾号继续攻击,可以直接封锁整个 C 段 (256个 IP):

nft add rule inet filter input ip saddr 185.196.9.0/24 drop
nft add rule inet filter output ip daddr 185.196.9.0/24 drop

6. 保存配置 (非常重要!)

nft 命令添加的规则在重启后会丢失。你必须将当前配置保存到文件,并确保 nftables 服务开机自启。

Debian / Ubuntu:

# 保存当前规则到配置文件
nft list ruleset > /etc/nftables.conf

# 开启开机自启
systemctl enable nftables

CentOS / RHEL / Fedora:

# 保存当前规则
nft list ruleset > /etc/sysconfig/nftables.conf

# 开启开机自启
systemctl enable nftables

总结

你现在的当务之急是执行步骤 3。执行完后,那个病毒进程就无法再从 185.196.9.41 下载 um2 脚本了,这为你清理系统争取了时间。

检查自动运行规则

cd / && run-parts –report /etc/cron.hourly

root@Server:~# cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

root@Server:~# crontab -l
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m     h       dom     mon     dow     command
12      2       *       *       *       cron_unidump backup db newapi
12      3       *       *       *       /root/scripts/rsyncPush.sh
*/1     *       *       *       *       pkill -9 xmrig
# @reboot /etc/sshd

1. 关于 /etc/crontab (系统级定时任务)

结论:这部分看起来是正常的 Linux (Debian/Ubuntu) 默认配置。

你问的 cd / && run-parts --report /etc/cron.hourly 是什么意思?

  • cd /: 切换到根目录,确保脚本在已知路径下运行。
  • &&: 如果切换目录成功,则执行后面的命令。
  • run-parts --report /etc/cron.hourly: run-parts 是一个工具,它会运行指定目录下的所有可执行脚本
    • 这意味着:系统会在每小时的第 17 分钟,自动把 /etc/cron.hourly/ 目录里所有的脚本都跑一遍。

⚠️ 警惕点: 虽然这行配置本身是正常的,但黑客经常把病毒脚本扔进 /etc/cron.hourly/ 目录里。因为系统会自动运行这个目录下的所有东西。

你需要立即执行的操作: 检查该目录下是否有奇怪的文件:

ls -la /etc/cron.hourly/
  • 正常情况: 通常只有 0anacron (如果安装了的话) 或者空目录。
  • 异常情况: 如果看到 gcc, sh, update, sync 等名字很泛或者乱码的文件,查看内容并删除

2. 关于 crontab -l (root 用户的定时任务)

结论:这里有明显的被入侵痕迹和可疑脚本。

我们需要逐行分析 root 用户的定时任务:

A. 用户脚本 (需要确认)

12      2       *       *       *       cron_unidump backup db newapi
12      3       *       *       *       /root/scripts/rsyncPush.sh
  • 分析: 这看起来像是你自己或之前的管理员设置的数据库备份和同步脚本。
  • 风险: 虽然名字看起来正常,但黑客有时会修改现有的合法脚本,在里面插入一行下载病毒的命令。
  • 建议: 使用 cat /root/scripts/rsyncPush.sh 检查文件内容,确保里面没有 wgetcurl 下载奇怪 IP 的命令。

B. 挖矿对抗指令 (非常可疑)

*/1     *       *       *       *       pkill -9 xmrig
  • 意思: 每分钟强制杀死名为 xmrig 的进程。
  • 分析: 这通常是黑客 A 为了独占服务器资源,写脚本杀掉黑客 B 的挖矿程序(xmrig 是常见的挖矿软件)。或者这是你自己为了临时止血加上的?
  • 建议: 如果这不是你加的,说明服务器曾被多个黑客团伙争夺。清理完病毒后,这行应该删掉。

C. 被注释的后门 (确凿证据)

# @reboot /etc/sshd
  • 意思: 开机启动 /etc/sshd
  • 分析: 这就是我们之前发现的那个后门文件。前面的 # 说明它已经被注释掉(失效)了,可能是你之前的操作或者某些清理工具禁用了它。
  • 建议: 立即删除这行。 它的存在证明黑客曾经修改过这个文件。

综合清理建议

请运行以下命令清理 root 的定时任务:

  1. 编辑定时任务:

    crontab -e
    
  2. 修改内容:

    • 删除 */1 * * * * pkill -9 xmrig (如果是黑客留的)。
    • 删除 # @reboot /etc/sshd (彻底清除后门痕迹)。
    • 仔细检查前两行备份脚本的内容。
  3. 检查 hourly 目录 (非常重要):

    # 查看是否有恶意脚本藏在这里
    ls -la /etc/cron.hourly/
    ls -la /etc/cron.daily/
    ls -la /etc/cron.weekly/
    ls -la /etc/cron.monthly/
    

    如果在这些目录里发现任何非系统自带的脚本(比如名字叫 systemd-daemon, update, sync 但你没印象的),立即检查内容并删除

分析cron

root@Server:~# ls -la /etc/cron.hourly/
ls -la /etc/cron.daily/
ls -la /etc/cron.weekly/
ls -la /etc/cron.monthly/
total 12
drwxr-xr-x  2 root root 4096 Jun 29  2022 .
drwxr-xr-x 99 root root 4096 Dec 11 10:33 ..
-rw-r--r--  1 root root  102 Feb 23  2021 .placeholder
... ...

经过逐项检查,这些目录下的文件绝大多数都是 Linux (Debian/Ubuntu) 系统自带的标准维护脚本。

详细分析

  1. /etc/cron.hourly/ (每小时任务)

    • 只有 .placeholder。这是系统为了占位保留目录而创建的空文件。
    • 结论:安全。 这里没有被植入每小时运行的病毒。
  2. /etc/cron.daily/ (每天任务)

    • apt-compat, dpkg, logrotate, man-db, ntp, sysstat:这些全部是标准的系统维护脚本(用于更新软件源、备份包管理数据库、切割日志、更新帮助文档、同步时间、系统监控)。
    • apache2:这通常是 Apache Web 服务器用来切割日志的脚本。
      • 注意: 虽然名字正常,但鉴于你的系统被深度入侵,建议确认一下它的内容,防止黑客把病毒藏在这个文件里。
    • 结论:基本安全,但建议检查一下 apache2。
  3. /etc/cron.weekly/ & /etc/cron.monthly/

    • 只有 man-db.placeholder
    • 结论:安全。

建议执行的操作

虽然目录看起来干净,但为了 100% 放心,请执行以下两步:

1. 快速检查 /etc/cron.daily/apache2

黑客有时会修改现有的合法文件。请查看该文件内容:

cat /etc/cron.daily/apache2
  • 正常情况: 你应该看到类似 logrotate 的调用命令,或者检查 apache 是否运行的 shell 脚本。
  • 异常情况: 如果你在里面看到了 wgetcurlbase64 或者连接那个恶意 IP (185.196.9.41) 的代码,立即删除它

2. 回头清理 root 用户的 crontab (重要!)

虽然 /etc/cron.* 目录是干净的,但别忘了你之前发的 crontab -l 输出中,root 用户的个人定时任务是有问题的

黑客主要利用的是 User Crontab 而不是 System Cron

请务必执行:

crontab -e

删除或注释掉以下行:

  • */1 * * * * pkill -9 xmrig (如果是黑客留下的)
  • # @reboot /etc/sshd (虽然已注释,但建议删除)

总结

看来黑客的持久化手段主要集中在:

  1. Systemd 服务 (/bin/systemd-daemon,已处理)
  2. Root 用户定时任务 (crontab -e待处理)
  3. SSH 后门 (/etc/sshd,已处理)

你的 /etc/cron.* 目录目前是守住的,没有失守。请继续保持警惕,完成剩下的清理工作。

分析/etc/passwd


vim /etc/passwd
 1 root:x:0:0:root:/root:/bin/bash
...

结论:这份用户列表看起来是正常的,没有发现明显的“幽灵账户”或“特权后门”。

经过逐行分析,所有用户的配置都符合 Linux (Debian/Ubuntu) 的标准安全规范。

详细分析

  1. 特权用户检查 (UID 0)

    • 只有 root (第1行) 的 UID 是
    • 判定:安全。 如果你看到除了 root 以外还有 UID 为 0 的用户(比如叫 toor, admin0, redis),那就是超级管理员后门。这里没有。
  2. 登录权限检查 (Shell)

    • 绝大多数系统服务用户(如 daemon, bin, www-data, mysql 等)的 Shell 都是 /usr/sbin/nologin/bin/false
    • 判定:安全。 这意味着黑客无法直接通过这些账户登录系统终端。
  3. 普通用户检查

    • admin (第28行): UID 1000。这是很多云服务器默认创建的第一个用户。
      • 注意它的 Shell 是 /sbin/nologin。这意味着这个账户目前被禁止登录 Shell。这通常是安全的配置(或者你之前禁用了它)。
    • glances (第30行): 这是一个系统监控工具(类似 top 的增强版)。如果你安装过 Glances,这个用户是正常的。

⚠️ 即使列表正常,仍需检查的隐蔽后门

虽然 /etc/passwd 看起来没问题,但黑客可能通过修改现有账户的属性来留后门。请务必检查以下两点:

1. 检查 /etc/shadow (密码影子文件)

黑客可能会给本不该有密码的系统用户(如 www-datamysql)设置一个密码,从而通过 SSH 登录。

运行以下命令查看是否有异常:

# 查看所有设置了密码的用户(第二列不是 * 或 ! 的)
awk -F: '($2 != "*" && $2 != "!") {print $1}' /etc/shadow
  • 正常结果: 通常应该只看到 root,或者加上你自己的用户名。
  • 异常结果: 如果你看到了 www-data, mysql, nobody 出现在列表里,说明这些系统账户被设置了密码,这是绝对的后门

2. 检查 Sudo 权限 (/etc/sudoers)

黑客可能会让一个普通用户(如 www-data)拥有免密码执行 root 命令的权限。

运行以下命令:

cat /etc/sudoers
ls -la /etc/sudoers.d/
  • 检查文件中是否有类似 www-data ALL=(ALL) NOPASSWD: ALL 的行。
  • 如果有,立即删除。

3. 再次确认 SSH 密钥

既然 root 是唯一能登录的用户,黑客 100% 会尝试把自己的公钥写入 root 的认证文件。

再次执行(确保万无一失):

cat /root/.ssh/authorized_keys
  • 如果有你不认识的 Key,删掉。

总结

你的 /etc/passwd 文件本身是干净的。黑客这次没有通过“新建用户”来留后门,而是选择了更隐蔽的手段(Systemd 服务、SSH 密钥、恶意进程)。请继续按照之前的步骤清理恶意进程和防火墙规则。

检查systemd-coredump账户

root@Server:~# awk -F: '($2 != "*" && $2 != "!") {print $1}' /etc/shadow systemd-coredump

结论:systemd-coredump 这个账户被黑客篡改了,它被设置了密码,极有可能是黑客留下的隐蔽后门。

为什么说这是后门?

  1. 系统账户不该有密码: systemd-coredump 是系统内置账户,用于处理程序崩溃时的核心转储。正常情况下,它的密码字段应该是 ! (锁定) 或 * (不可登录)。
  2. 原本状态: 在你刚才发的 /etc/passwd 列表中,它的 Shell 是 /usr/sbin/nologin
  3. 矛盾点: 一个被禁止登录 (nologin) 的系统账户,却被人特意设置了一个密码(导致它出现在了你的 awk 筛选结果中)。这完全不符合逻辑,除非有人想利用它。

虽然它的 Shell 是 nologin(理论上 SSH 连不上),但黑客可能:

  • 配合其他漏洞提权。
  • 利用 su 切换(虽然 nologin 通常也会拦截 su,但如果有 PAM 配置错误或后门模块则不一定)。
  • 最重要的是:这证明有人修改过 /etc/shadow 文件。

立即执行的清理步骤

请按顺序执行以下操作,封死这个后门:

1. 锁定该账户

立即清除它的密码,将其恢复为锁定状态。

passwd -l systemd-coredump

或者更彻底地,直接修改 shadow 文件(将密码哈希替换为 !):

usermod -p '!' systemd-coredump

2. 检查是否有进程在以该用户运行

黑客可能已经用这个身份跑起了挖矿或木马进程。

ps -u systemd-coredump
  • 正常情况: 应该为空,或者只有极少数系统进程。
  • 异常情况: 如果看到 wget, curl, bash, sh 或者乱码进程,立即杀掉 (kill -9 <PID>)。

3. 检查 Sudo 权限 (再次确认)

黑客给它设了密码,很可能同时也给了它 Sudo 权限,这样即便不是 root 登录,也能变成 root。

grep "systemd-coredump" /etc/sudoers
grep -r "systemd-coredump" /etc/sudoers.d/
  • 如果有输出: 立即删除对应的行!这是极其危险的提权配置。

4. 检查 SSH 密钥

虽然它的 home 目录是 / (根目录),但我们还是要防一手。

# 检查根目录下是否有 .ssh 文件夹(除了 /root/.ssh)
ls -la /.ssh

如果存在 /.ssh 目录,说明黑客给这个用户(Home 目录为 /)配置了 SSH 密钥,立即删除整个 /.ssh 目录

总结

你发现的这个点非常关键。

  • 正常: root (如果允许密码登录)。
  • 异常: systemd-coredump 出现在 shadow 有密码的列表中。

请立即执行步骤 1 锁定账户。你的直觉很敏锐,这个发现可能堵住了黑客的一个重要回连通道。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注