WP-ShellStorm後門攻擊事件簿
內容目錄
🕵️♀️ 全球140萬個網站遭殃!教你3分鐘揪出偽裝間諜
你有沒有想過,你家網站可能早就「被裝了竊聽器」,而你完全不知情?就在2026年7月,資安圈爆出一起超大規模的入侵事件——駭客利用一款叫做WP-ShellStorm的後門工具,一口氣鎖定超過140萬個網站,而且更狗血的是,這整起事件之所以曝光,居然是因為駭客自己「忘記鎖車門」被抓包!
今天這篇文章,我要用最生活化的方式,帶你搞懂這整起事件的來龍去脈,最後還會附上一份「傻瓜級」的自我檢查步驟,讓你也能在自己的伺服器上抓抓看有沒有可疑的「臥底」。
🎬 第一幕:小偷把作案工具忘在自家沒鎖的車庫
這起事件最有趣的地方,不是駭客有多厲害,而是他們有多「迷糊」。
想像一下:一個竊盜集團辛辛苦苦準備了整套開鎖工具、贓物清單、還有下一批要下手的目標名單,結果收工回家之後,居然忘記把車庫鐵門鎖上,就這樣大剌剌地曝光了整整22天。
這就是威脅情報公司 SOCRadar 發現這起事件的經過——駭客架設了一台伺服器,用來存放他們的攻擊工具跟紀錄,卻完全忘記設密碼保護。研究人員只是路過看了一眼,就撿到了整個犯罪組織的作案SOP,包含:
- ✅ 完整的攻擊工具(後門程式、漏洞掃描器)
- ✅ 詳細的操作紀錄(bash history)
- ✅ 一份長達140萬筆的「潛在肉雞」名單
💡 小提醒:這告訴我們一件事——就算是專業駭客,也會犯下「基本功沒做好」的低級錯誤。資安這件事,說穿了很多時候拚的不是誰的技術強,而是誰的「基本設定」做得確實。
🎯 第二幕:駭客到底是怎麼「進門」的?
很多人以為被駭客入侵,一定是自己「不小心點了什麼可疑連結」。但這次的手法完全不是這樣——駭客用的是「海放式打漏洞」戰術。
打個比方:這就像有個小偷不是專程來你家,而是拿著一把萬能鑰匙,走遍整條街,挨家挨戶去試每一戶的門鎖。只要哪一戶的鎖沒換新(也就是外掛程式沒更新),鑰匙一插就開,完全不需要你開門讓他進來。
這次駭客總共動用了27個已知漏洞,鎖定的都是WordPress常見外掛,戰績如下表:
| 被攻擊的外掛 | 白話解釋 | 戰果 |
|---|---|---|
| Breeze Cache Cleaner(快取外掛) | 幫網站加速的常見工具 | 4.5萬個目標中,1.7萬個被成功入侵 |
| ThemeREX Addons(佈景主題外掛) | 美化網站外觀用的工具 | 4.66萬個目標中,3,378個中招 |
| Joomla JCE(編輯器外掛) | 另一套建站系統的編輯工具 | 丟了56萬個目標,只成功77個(証明「有更新習慣」真的有用!) |
看到最後一列了嗎?Joomla JCE雖然被丟了最多次攻擊,成功率卻最低,因為多數用戶都已經修補了這個漏洞。這就是這次事件給我們最重要的啟示:你的外掛版本,就是你家門鎖的等級。
🥷 第三幕:後門怎麼躲貓貓躲到讓專家都找半天?
如果你以為後門程式就是一個大剌剌寫著「我是病毒」的檔案,那你就太小看這群駭客了。這次發現的主要後門down.php,做了四層偽裝,簡直像是套了四層洋蔥皮:
- 第一層:文字編碼混淆(讓人類肉眼看不懂)
- 第二層:壓縮加密(讓檔案看起來像亂碼)
- 第三層:變數名稱偽裝(連工程師掃過去都容易忽略)
- 第四層:最後才解開變成真正的「萬能鑰匙」
更狠的是,這個後門會偽裝成一般的「404錯誤頁面」給正常訪客看,也就是說,就算你自己點進網站檢查,看起來一切正常,其實裡面早就有人在裡面翻箱倒櫃。
最厲害(也最陰險)的一招,是遠端遙控用的程式會把自己改名偽裝成電腦系統內建的正常程序,具體來說就是偽裝成一種叫「kworker」的系統內部工作,讓人在檢查電腦「目前在跑什麼東西」的時候,誤以為它只是電腦自己在做家事,完全不會多想。
💡 生活化比喻:這就像小偷混進你家不是穿黑衣蒙面,而是換上一套跟你家管家一模一樣的制服,你看到他走來走去也不會覺得奇怪——因為他「看起來」就是自己人。
🔍 第四幕:3分鐘傻瓜自我檢測,看看你家有沒有「臥底」
看到這裡,你可能會緊張:那我自己的網站主機,要怎麼知道有沒有中招?別擔心,這邊教你一招最簡單的初步檢查,用電腦的「終端機」就能做,完全不用懂程式:
第一步:打開終端機,輸入以下指令:
ps aux | grep kworker
第二步:看輸出結果的「格式」
| 狀態 | 長什麼樣子 | 白話解釋 |
|---|---|---|
| ✅ 正常 |
[kworker/0:2-mm_percpu_wq] |
後面有清楚的「工作說明」尾巴,像正常員工都有名牌 |
| 🚨 異常 |
[kworker/0:2] |
光禿禿沒有任何說明,像是沒戴名牌卻穿著制服到處走的可疑人物 |
如果你發現有「光禿禿沒有尾巴」的可疑項目,別自己亂刪,先截圖記錄,再找懂技術的朋友或資安人員協助確認。
cat > /tmp/check-backdoor-full.sh << 'EOF'
#!/bin/bash
# ============================================
# 系統後門/持久化機制 全面快速檢測腳本
# 涵蓋範圍:
# 1. 偽裝成 kworker 的可疑核心程序
# 2. Crontab 排程是否被植入可疑任務
# 3. SSH authorized_keys 是否被塞入陌生公鑰
# 4. systemd 服務是否有可疑的自啟動項目
# 5. 近期被修改過的系統關鍵檔案
# ============================================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
TOTAL_ISSUES=0
echo "════════════════════════════════════════"
echo "🔍 第一部分:kworker 偽裝程序檢測"
echo "════════════════════════════════════════"
KTHREADD_PID=$(pgrep -x kthreadd | head -1)
SUSPICIOUS_COUNT=0
if [ -z "$KTHREADD_PID" ]; then
echo -e "${YELLOW}⚠️ 找不到 kthreadd,建議人工檢查${NC}"
else
for pid in $(pgrep -f 'kworker'); do
PNAME=$(ps -p "$pid" -o comm= 2>/dev/null)
PPID=$(ps -p "$pid" -o ppid= 2>/dev/null | tr -d ' ')
FLAG=0
REASONS=""
if ! echo "$PNAME" | grep -qE '^kworker/[u]?[0-9]+:[0-9]+H?(-[a-zA-Z0-9_/-]+)?$'; then
FLAG=1
REASONS="${REASONS}命名格式異常; "
fi
if [ "$PPID" != "$KTHREADD_PID" ] && [ "$PPID" != "2" ]; then
FLAG=1
REASONS="${REASONS}父行程非kthreadd(PPID=$PPID); "
fi
if [ -e "/proc/$pid/exe" ]; then
EXE_TARGET=$(ls -l "/proc/$pid/exe" 2>/dev/null | awk '{print $NF}')
if [ -n "$EXE_TARGET" ]; then
FLAG=1
REASONS="${REASONS}存在/proc/exe連結:$EXE_TARGET; "
fi
fi
if [ "$FLAG" -eq 1 ]; then
SUSPICIOUS_COUNT=$((SUSPICIOUS_COUNT+1))
echo -e "${RED}🚨 PID=$pid 名稱=$PNAME 原因:$REASONS${NC}"
fi
done
if [ "$SUSPICIOUS_COUNT" -eq 0 ]; then
echo -e "${GREEN}✅ 未發現偽裝的 kworker 程序${NC}"
else
TOTAL_ISSUES=$((TOTAL_ISSUES+SUSPICIOUS_COUNT))
fi
fi
echo ""
echo "════════════════════════════════════════"
echo "🔍 第二部分:Crontab 可疑排程檢測"
echo "════════════════════════════════════════"
CRON_HITS=0
# 檢查所有使用者的crontab + 系統層級排程
{
for user in $(cut -f1 -d: /etc/passwd); do
crontab -l -u "$user" 2>/dev/null | grep -v '^#' | grep -v '^$' | sed "s/^/[user:$user] /"
done
find /etc/cron.d /etc/cron.daily /etc/cron.hourly /etc/cron.weekly /etc/cron.monthly -type f 2>/dev/null -exec echo "[system] {}" \; -exec cat {} \;
} > /tmp/.cron_dump_$$
# 揪出常見惡意特徵:curl/wget下載後直接執行、base64解碼執行、反彈shell、寫入陌生路徑
while IFS= read -r line; do
if echo "$line" | grep -qE '(curl|wget).*\|.*(bash|sh)|base64 -d|/dev/tcp/|nc -e|mkfifo|chmod \+x /tmp|chmod \+x /var/tmp'; then
CRON_HITS=$((CRON_HITS+1))
echo -e "${RED}🚨 可疑排程:$line${NC}"
fi
done < /tmp/.cron_dump_$$
rm -f /tmp/.cron_dump_$$
if [ "$CRON_HITS" -eq 0 ]; then
echo -e "${GREEN}✅ 未發現明顯異常的排程任務${NC}"
echo " (建議仍手動看一眼 crontab -l 確認每一條都是你熟悉的)"
else
TOTAL_ISSUES=$((TOTAL_ISSUES+CRON_HITS))
fi
echo ""
echo "════════════════════════════════════════"
echo "🔍 第三部分:SSH authorized_keys 檢測"
echo "════════════════════════════════════════"
KEY_HITS=0
for keyfile in $(find /root /home -maxdepth 3 -name authorized_keys 2>/dev/null); do
COUNT=$(grep -cve '^\s*$' "$keyfile" 2>/dev/null)
echo "📄 $keyfile (共 $COUNT 把公鑰)"
grep -v '^\s*$' "$keyfile" 2>/dev/null | while IFS= read -r key; do
COMMENT=$(echo "$key" | awk '{print $NF}')
echo " → 註記:$COMMENT"
done
done
echo -e "${YELLOW}⚠️ 上面列出的每把公鑰請自行確認是不是你或團隊成員添加的,腳本無法自動判斷「陌生」與否${NC}"
echo ""
echo "════════════════════════════════════════"
echo "🔍 第四部分:systemd 可疑自啟動服務"
echo "════════════════════════════════════════"
SYSTEMD_HITS=0
for svc in $(systemctl list-unit-files --type=service --state=enabled 2>/dev/null | awk '{print $1}' | grep '\.service$'); do
SVC_PATH=$(systemctl show -p FragmentPath "$svc" 2>/dev/null | cut -d= -f2)
if [ -n "$SVC_PATH" ] && echo "$SVC_PATH" | grep -qE '^/(tmp|var/tmp|dev/shm)/'; then
SYSTEMD_HITS=$((SYSTEMD_HITS+1))
echo -e "${RED}🚨 可疑服務:$svc 定義檔位於臨時目錄:$SVC_PATH${NC}"
fi
done
if [ "$SYSTEMD_HITS" -eq 0 ]; then
echo -e "${GREEN}✅ 未發現定義在 /tmp、/dev/shm 等臨時目錄的自啟動服務${NC}"
else
TOTAL_ISSUES=$((TOTAL_ISSUES+SYSTEMD_HITS))
fi
echo ""
echo "════════════════════════════════════════"
echo "🔍 第五部分:近7天內被修改的關鍵系統檔案"
echo "════════════════════════════════════════"
RECENT_FILES=$(find /etc /usr/bin /usr/sbin /usr/local/bin -type f -mtime -7 2>/dev/null)
if [ -n "$RECENT_FILES" ]; then
echo -e "${YELLOW}⚠️ 以下檔案在近7天內被修改過,請確認是否為你自己的操作(例如系統更新):${NC}"
echo "$RECENT_FILES" | head -30
FILE_COUNT=$(echo "$RECENT_FILES" | wc -l)
if [ "$FILE_COUNT" -gt 30 ]; then
echo " ...(共 $FILE_COUNT 個,僅顯示前30個,多半是正常系統更新造成)"
fi
else
echo -e "${GREEN}✅ 未發現近期異常修改的關鍵系統檔案${NC}"
fi
echo ""
echo "════════════════════════════════════════"
echo "🏁 總結"
echo "════════════════════════════════════════"
if [ "$TOTAL_ISSUES" -eq 0 ]; then
echo -e "${GREEN}✅ 五項檢測皆未發現明確的自動化可判斷異常${NC}"
echo " 建議仍手動複查 authorized_keys 與近期修改檔案清單這兩項(腳本無法完全自動判斷)"
else
echo -e "${RED}🔴 共發現 $TOTAL_ISSUES 項自動判定的可疑項目,建議處置流程:${NC}"
echo "1️⃣ 先保留現場,不要急著刪除或kill,截圖/記錄上面的可疑項目"
echo "2️⃣ 中斷該程序或服務對外的網路連線:ss -antp | grep "
echo "3️⃣ 移除可疑crontab項目、可疑SSH公鑰、可疑systemd服務"
echo "4️⃣ 檢查該主機上跑的網站程式(如WordPress)是否有外掛版本過舊未更新"
echo "5️⃣ 若無法排除是否還有其他殘留後門,建議整台重灌重建,並在重建後第一時間更新所有軟體版本"
fi
echo "════════════════════════════════════════"
EOF
chmod +x /tmp/check-backdoor-full.sh
bash /tmp/check-backdoor-full.sh
🧯 第五幕:與其事後抓賊,不如提前鎖好門
看完整起事件,你會發現一個很殘酷的真相:這些受害網站,多數都是「本來可以避免」的悲劇。只要做好以下幾件事,你就能把中招機率降到最低:
- 🔐 外掛、佈景主題定期更新——這是最重要也最基本的一件事,就像家裡的門鎖該換就要換
- 🔑 SSH登入只用金鑰、別用密碼——密碼再複雜都可能被暴力破解,金鑰安全性高上不只一個檔次
- 🚪 不用的服務、外掛,直接移除——多一個沒在用的東西,就多一個可能被打穿的破口
- 📅 定期做健康檢查——就像定期健檢一樣,抓早期病灶總比等到病入膏肓便宜又省心
💬 碎念:資安這件事真的很像存錢——大家都知道很重要,但總是要等到真的出事了才會認真做。與其等網站被駭客賣掉存取權限才後悔,不如現在就花五分鐘檢查一下,真的划算多了 😌
📌 延伸閱讀與資料來源
- 駭客利用後門程式WP-ShellStorm入侵WordPress網站並兜售存取權限(iThome)
- How WP-SHELLSTORM Exposed 1.4M WordPress Sites(SOCRadar 原始技術報告)
看完這篇文章別忘了現在就去檢查一下自己的外掛版本喔!👍💪




