防毒說「沒有偵測到惡意程式」,而它就躺在我硬碟上
那天下午我在整理 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"
然後往下讀,它做四件事:
- 如果自己不見了 →
wget把自己重新下載回來 - 如果系統排程檔沒有那串標記 → 用
>覆寫整個/etc/crontab,把自己塞回去 - 如果開機腳本沒有標記 → 在
/etc/rc.subr後面附加一行(開機自動復活) - 如果主程式沒在跑 → 下載
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:wget、chmod、echo。惡意的是它們組合起來要做的事,而那需要理解,不是比對。
三、那條排程是合法語法。 「惡意設定檔」檢查看的是已知的壞設定樣板,不是「這一行在幹嘛」。*/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 的連線消失了、沒有殘留程序、系統排程檔只剩下正常項目。刪完當下就宣告成功,跟等一個週期再宣告,是兩種不同強度的說法。)




我後來寫的哨兵,不查特徵
既然官方掃描器對這支是綠燈,我不能把它當作偵測手段。所以我寫了一支每天自動跑的檢查,它不做特徵比對,只問三個問題:
/etc/.conf存在嗎?/etc/node存在嗎?- 那串標記字串出現在系統排程或開機腳本裡嗎?
加殼騙得過掃描器,騙不過 ls。
寫的時候我犯了一個錯,值得單獨講:第一版裡,「乾淨」和「連不到 NAS」都回傳同一個結果、記錄同一句話。
意思是——哪天 SSH 壞掉、NAS 關機、或金鑰失效,這支哨兵會永遠安靜,而我會以為有人在幫我盯。
監控器沉默的時候,「一切正常」和「我瞎了」長得一模一樣。
改法是讓它們回傳不同的結果,而且連續看不到三次就主動告警自己失明了。哨兵要為自己的失明出聲,否則它的沉默會被當成安全。
我從這件事帶走的東西
一、「沒偵測到」和「沒有」是兩句不同的話。 工具的輸出是那個工具看到的東西,不是世界的狀態。要確認一件事存不存在,去看那個東西本身。
二、便利功能就是曝露面。 QuickConnect 幫我省下設定路由器的麻煩,代價是把管理介面放到外網。這個交換在漏洞被公開之前是划算的,之後就不是了——而我沒有跟著更新。
三、更新不是「有空再說」。 從漏洞公告到我被打進來,中間隔了超過一年。那一年裡我每次看到更新提示都想著「等等再說,怕更新壞東西」。
四、「以為沒事」比「知道有事」危險。 它在裡面六個月,我完全沒有感覺。系統沒有變慢、沒有異常、官方工具說一切正常。發現它的唯一原因是我問了一句跟它無關的問題。
如果你也有一台 NAS
三件事,十分鐘:
- 把系統更新到最新版。不是最新的大版本,是當前版本的最新修補——那個風險最低、修的洞最多。
- 檢查有沒有把管理介面曝露到外網:路由器的 port forwarding,以及廠商的遠端存取服務(QuickConnect 之類)。用手機關掉 WiFi 測是最準的。
- 開啟自動封鎖。它擋不到這次這種漏洞攻擊,但擋得到大多數的密碼嘗試。
然後,如果你想確認自己乾不乾淨:
grep -rn "/etc/\.conf" /etc/crontab /etc/rc.subr 2>/dev/null
ls -la /etc/.conf /etc/node 2>/dev/null
沒有輸出是好事。有輸出的話,你現在知道那是什麼了。
這篇不是資安專業分析——我是做咖啡的,順便寫程式。 這是一份現場紀錄:一個沒更新的 NAS、一個公開超過一年的漏洞、一個潛伏六個月的程式,和一個說「一切正常」的綠燈。



