✍️ 寫在前面
10 月初,Huntress 發布了哪吒 (Nezha) 攻擊報告。
這次事件裡,攻擊者將原本用於伺服器監控的開源專案「Nezha」武器化,
透過暴露在網際網路、沒有登入驗證的 phpMyAdmin 介面入侵多國組織,其中台灣是重災區。作為備戰獎金獵人,
我從這起事件學到的不是新聞,而是:「為什麼這些系統可以不需要密碼?」
「哪些開源工具若設定不當,也可能重演同樣的劇本?」
phpMyAdmin 在正常安裝流程中必須設定登入驗證,
但若是在 Docker 或快速測試環境 下,
攻擊者可能只需以下一行指令就能啟動一個「不安全版本」:
docker run -d -p 8080:80 phpmyadmin
這樣部署的容器:
PMA_ARBITRARY=1
限制;也就是說,任何人都能在瀏覽器輸入:
http://<server-ip>:8080/
直接看到 phpMyAdmin 介面並操作資料庫。
這樣的誤用在企業測試環境與 IoT 韌體開發階段極為常見。
許多廠商在開發 NAS、監控設備或雲端平台時,
都會使用 docker-compose 一鍵建立開發環境,而安全設計卻常被忽略。
根據這次哪吒攻擊行為模式,
攻擊鏈的關鍵是「開源管理介面 + 無驗證 + 暴露於公網」。
以下是目前紅隊可針對性蒐集與分析的潛在標的清單:
類別 | 工具 / 系統 | 常見用途 | 風險點 | 攻擊者可能利用方式 |
---|---|---|---|---|
資料庫管理 | phpMyAdmin | MySQL / MariaDB Web 管理 | 無密碼登入、Docker 預設開放 | Log Poisoning、Web Shell 注入 |
資料庫管理 | Mongo Express / AdminMongo | MongoDB 管理介面 | 預設無認證、HTTP 明文傳輸 | Dump 資料、RCE via eval() |
系統監控 | Nezha Dashboard / Agent | 系統監控、報表 | 未設密碼 token、反向連線控制 | 攻擊者註冊節點、RCE |
網路監控 | Observium / Cacti / MRTG | SNMP / 流量監控 | 預設帳密、RCE 插件漏洞 | SNMP Dump、指令注入 |
IoT 控制 | Node-RED / Mosquitto | IoT 自動化 / MQTT Broker | 未設定認證、開放 MQTT 1883 | 中間人、Topic 注入 |
儲存管理 | OpenMediaVault / NextCloud | 檔案管理 | 預設弱密碼 / 未更新 | 任意上傳、RCE |
工控系統 | Advantech WebAccess / Moxa MXView | 工控與 SCADA | 過期韌體 / 弱密碼 | ICS 漏洞利用 |
這些工具有三個共通點,使它們極易被濫用:
1️⃣ 可視化介面 → 攻擊者不需命令列技巧,只要瀏覽器。
2️⃣ 容器化部署 → 「一行指令」即可重現,導致誤配置率高。
3️⃣ 開源信任 → 因為是開源專案,企業常誤以為「安全性沒問題」。
但正因為它們設計為「可遠端操作」,
一旦部署不當、未加密、未驗證,就成為最佳入侵跳板。
在活動開始前,
建議針對以下類型服務先做「資訊蒐集與 PoC 準備」:
探測項目 | 目的 | 工具建議 | ||
---|---|---|---|---|
搜尋公開 phpMyAdmin / Mongo Express | 確認哪些系統未設定認證 | httpx -title -sc -ports 80,8080,8443 |
||
掃描 1883 / 8883 Port | 確認 MQTT Broker 是否開放 | nmap -p1883,8883 --script mqtt* |
||
偵測 Nezha Agent 節點 | 找出未驗證監控端 | httpx -path /server/status |
||
偵測 Observium / MRTG / Cacti | 確認監控頁是否有登入頁 | `httpx -title -match "Observium | Cacti | MRTG"` |
收集版本資訊 | 比對 CVE | 整合 CVEfeeds 或 NVD API |
下面是結合 httpx 與關鍵特徵詞的簡易篩選腳本,可在掃描後自動分類出潛在風險系統。
import httpx, asyncio
keywords = ["phpMyAdmin", "Mongo Express", "Nezha", "Observium", "Cacti", "MRTG"]
async def scan_target(ip):
try:
async with httpx.AsyncClient(timeout=5, follow_redirects=True) as client:
r = await client.get(f"http://{ip}", headers={"User-Agent": "IoTScanner"})
for k in keywords:
if k.lower() in r.text.lower():
print(f"[+] {ip} 發現 {k} 介面")
break
except Exception:
pass
async def main():
ips = [line.strip() for line in open("target_ip.txt")]
tasks = [scan_target(ip) for ip in ips]
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
📌 小技巧:可以把
target_ip.txt
換成從 Shodan 或官方清單提取的 IoT IP 列表。
這份紅隊清單對藍隊也同樣有用:
「哪吒攻擊」不是單一事件,而是一種思維提醒:
任何開源、可見的工具,都可能在錯誤配置下變成入侵入口。