iT邦幫忙

0

駭客不需要寫驅動程式——他們從 MSI Afterburner 偷一個就能殺光你的防毒軟體

  • 分享至 

  • xImage
  •  

防毒軟體在執行。EDR 已經部署。Defender 顯示「您的裝置受到保護」。

但是攻擊者根本不需要繞過它們——他們只要把它們關掉

不是用社交工程說服使用者關閉。不是利用某個 zero-day。是利用一個你電腦上可能已經有的、Windows 自己信任的、由微軟認可的廠商簽章的合法驅動程式——例如 MSI Afterburner 用來監控顯示卡溫度的那個小工具——讓它執行任意的 kernel 操作,把整個防毒系統的監視機制從記憶體裡刪掉。

這個技術叫 BYOVD(Bring Your Own Vulnerable Driver)。BlackByte、Lazarus、Cuba、BlackCat/ALPHV、AvosLocker、RobbinHood——過去三年最有破壞力的勒索軟體和 APT 攻擊,都用過這招。

這篇文章會從 CPU 的特權模型開始,一路講到 IOCTL handler、kernel callback、Direct Kernel Object Manipulation,把這個攻擊鏈拆給你看。文末會討論 Microsoft 為什麼即使知道這個問題、也沒辦法完全擋住。

先看一個事實:你的 Windows 信任了 1,000 多個有漏洞的驅動程式

Microsoft 維護一份叫 Recommended Driver Block Rules(推薦驅動程式封鎖清單)的文件(來源)。這份清單上的每一條,都是一個「簽章合法、但有可被利用的核心級漏洞」的驅動程式。

清單上有:

  • 某些版本的 MSI Afterburner(RTCore64.sys)——CVE-2019-16098
  • 某些版本的 GIGABYTE 工具(gdrv.sys)——CVE-2018-19320 等
  • 某些版本的 Dell BIOS 工具(dbutil_2_3.sys)——CVE-2021-21551
  • 原神反作弊驅動(mhyprot2.sys
  • 多個 EDR/AV 自己的舊版驅動
  • ...合計超過 1,000 條規則

這些驅動程式全部都通過了 Microsoft 的簽章驗證。這份清單不是「要封鎖的惡意軟體」,是「Windows 自己曾經信任、但被發現可以拿來打進核心的合法軟體」。

要理解這為什麼是個問題,得從 CPU 開始講。

第一層:CPU 的特權模型

x86/x64 架構的 CPU 有 4 個特權層級,叫 Ring 0 到 Ring 3。這是硬體層的設計,不是軟體規則:

Ring 名稱 誰在這裡執行
Ring 0 Kernel Mode OS 核心、device drivers
Ring 1 (現代 OS 不用) (早期 OS 設計,但 Linux/Windows 沒採用)
Ring 2 (現代 OS 不用) 同上
Ring 3 User Mode 你的瀏覽器、Word、防毒軟體的 UI 部分

CPU 的指令集本身就會檢查特權層級。很多指令在 Ring 3 是無法執行的——例如 WRMSR(寫入 Model-Specific Register)、HLT(停止 CPU)、INVLPG(清除 TLB)、直接讀寫物理記憶體。Ring 3 的程式碼想做這些事,必須透過系統呼叫(syscall),讓 CPU 切換到 Ring 0、執行核心提供的服務。

這是個防爆牆:即使 Ring 3 的惡意軟體拿到管理員權限,它仍然不能直接讀寫核心記憶體、不能直接修改其他行程的狀態、不能繞過 OS 的存取控制。它必須請求核心做這些事,而核心會檢查請求是否合法。

只要攻擊者進不到 Ring 0,他能做的事情有上限。

防毒軟體和 EDR 之所以有效,是因為它們有一部分在 Ring 0 執行——所以它們可以在 kernel 層級監視所有 process 的建立、所有 driver 的載入、所有檔案系統的存取。Ring 3 的惡意軟體看不到 EDR 的 kernel 部分、也碰不到。

除非——惡意軟體自己也能進到 Ring 0。

第二層:Windows 怎麼決定誰可以進 Ring 0

唯一能在 Windows kernel 內執行程式碼的合法管道,是載入 device driver。Driver 是 OS 用來跟硬體(顯示卡、網路卡、印表機...)溝通的程式碼,它必須在 Ring 0 執行才能跟硬體直接互動。

從 Windows Vista 開始,64 位元 Windows 強制要求所有 kernel-mode driver 必須有合法的數位簽章——這個機制叫 Driver Signature Enforcement (DSE)。從 Windows 10 開始,Microsoft 進一步要求所有新的 kernel driver 必須送交 Microsoft 自己簽名(透過 Hardware Dev Center),叫 Kernel Mode Code Signing (KMCS)

理論上,這個機制應該很安全:

  1. 攻擊者不能把自己寫的 evil.sys 載入到 kernel——沒有合法簽章,DSE 會拒絕
  2. 要拿到合法簽章,必須有 EV Code Signing Certificate(要用真實公司身分申請)+ Microsoft 的 attestation 簽章
  3. 所以攻擊者只能在 Ring 3 活動,做不了大事

問題在於:DSE 檢查的是「這份檔案有沒有合法簽章」,不是「這份檔案的程式碼安不安全」。

任何在過去 15 年內、由任何合法廠商發行、簽過名的 driver——包括那些已經被廠商棄用、有公開 CVE、廠商也不再維護的——仍然會通過 DSE 檢查

這就是 BYOVD 的入口。

第三層:拆解一個真實的 BYOVD 攻擊

來看 BlackByte 勒索軟體 2022 年的攻擊鏈(Sophos 完整逆向過,來源)。我刻意不寫成可執行的步驟,只描述每一步在系統內發生的事:

Step 1:取得 admin 權限(前置條件,不是 BYOVD 本身)

BYOVD 不是初始入侵手法。攻擊者必須已經有 local admin 權限才能用這招。通常來自:

  • 釣魚信件 + macro 執行 + UAC bypass(取得 admin token)
  • 暴力破解 RDP / SSH(直接登入)
  • 從初始入侵掮客(IAB)那裡買來的存取
  • 漏洞利用公開的 web 服務後橫向移動

重點:BYOVD 是「從 admin 升級到 kernel」的橋梁,不是入口。

Step 2:投放有漏洞的 driver

BlackByte 的二進位檔案內直接 hardcode 了 RTCore64.sys 的內容(這是 MSI Afterburner 的一個元件)。執行時,它把這個 driver 寫到 %AppData%\Roaming\ 目錄,檔名隨機。

RTCore64.sys合法的 Micro-Star International(MSI)數位簽章。Windows 看到這個簽章,會通過。

Step 3:把 driver 註冊成系統服務

sc create <random_name> binPath= "<dropped_path>" type= kernel
sc start <random_name>

這需要 admin 權限(SeLoadDriverPrivilege)。Windows 的 service control manager 收到請求後,會把 RTCore64.sys 載入到 kernel——因為它通過 DSE

到這一步,攻擊者還在 Ring 3。但他現在有一個運作中的 kernel driver 等著被「請求」。

Step 4:濫用 IOCTL 漏洞取得 kernel R/W

這是技術上最關鍵的一步。

User-mode 程式跟 driver 溝通的標準介面是 IOCTL(I/O Control):user-mode 呼叫 DeviceIoControl() API,傳入一個 IOCTL code 和一塊 buffer,driver 收到後根據 IOCTL code 執行對應的操作。

正常的 driver 會在 IOCTL handler 裡做嚴格的參數驗證——尤其是任何牽涉到記憶體位址的操作。Microsoft 的 Driver Security Checklist 明確要求:「定義允許 caller 讀寫任意 kernel 記憶體位址的 IOCTL code 是危險的」。

RTCore64.sys 就違反了這個規則CVE-2019-16098 技術分析):

  • 它定義了某些 IOCTL code,接受一個 user-mode 傳來的 kernel 記憶體位址,然後對該位址執行任意讀或寫
  • 它對 IRP(I/O Request Packet)沒有做存取控制——任何低權限使用者也可以打開 \\.\RTCore64 這個裝置

也就是說:攻擊者只要呼叫 DeviceIoControl() 並傳入特定的 IOCTL code,就能讓這個合法的 MSI driver 替他讀寫任何 kernel 位址——包括 Windows 核心結構、其他 driver 的程式碼、防毒軟體的 callback 表。

到這一步,攻擊者實質上有了 kernel R/W 能力——而這一切都是「透過合法簽章的驅動程式」完成的。

Step 5:拆掉 EDR 的 callback

Windows kernel 提供了一組 API,讓 driver 可以註冊「通知」,在系統發生特定事件時被呼叫:

API 通知時機
PsSetCreateProcessNotifyRoutine process 被建立或終止
PsSetCreateThreadNotifyRoutine thread 被建立或終止
PsSetLoadImageNotifyRoutine DLL 或驅動被載入
CmRegisterCallback registry 被修改
ObRegisterCallbacks 對特定 object 的 handle 被開啟

這就是 EDR 怎麼運作的。 防毒軟體和 EDR 在 kernel driver 裡呼叫這些 API,把自己的 callback 函式登錄進核心。每當系統有 process 建立、檔案被開啟、registry 被改——核心會自動呼叫 EDR 的函式,讓 EDR 決定要不要阻擋、要不要記錄。

這些 callback 的位址被存在 Windows kernel 內部的 array 裡(例如 PspCreateProcessNotifyRoutine 這個變數)。

BlackByte 用 RTCore64.sys 的任意記憶體寫入,直接把這些 array 裡的條目覆寫成零——把 EDR 的眼睛挖掉。

從這一刻起:

  • EDR 仍在執行,UI 還顯示「保護中」
  • 但 process 建立時,沒有人收到通知
  • 檔案被加密時,沒有人收到通知
  • 攻擊者後續執行的所有操作,EDR 都看不見

Sophos 的逆向發現,BlackByte 內建一份「需要拆 callback 的 EDR/AV 清單」,長度超過 1,000 個產品。這份清單跟開源工具 EDRSandblast 的清單幾乎完全相同——說明攻擊者直接抄了開源 PoC 的程式碼。

Step 6:勒索軟體開始加密

防護機制全部拆完之後,BlackByte 才開始投放勒索軟體 payload,加密整個檔案系統。到這個時候,被害人才會看到第一個徵兆——但所有監視機制都已經被悄悄關掉

不只 RTCore64:BYOVD 的 driver 名單

過去三年實際被武器化的 driver:

Driver 來自 漏洞 用過的攻擊組織
RTCore64.sys MSI Afterburner CVE-2019-16098 BlackByte、Cuba、Lazarus
gdrv.sys GIGABYTE CVE-2018-19320 RobbinHood(用來關掉 DSE 載入自己的 unsigned rootkit)
dbutil_2_3.sys Dell BIOS 更新工具 CVE-2021-21551 UNC3524(APT)
mhyprot2.sys 原神反作弊(miHoYo) 設計上有漏洞 多個勒索軟體組織
aswArPot.sys Avast Antivirus(舊版本) 設計上有漏洞 AvosLocker
procexp.sys Sysinternals Process Explorer 不是漏洞,是設計上的功能 AuKill(殺 EDR 的工具,被 Medusa Locker、LockBit、Nokoyawa 使用)
WinRing0 多個硬體監控工具 開源、提供 MSR 存取 多個用來提權

procexp.sys 那個案例特別值得停下來想:Microsoft 自己的合法工具Microsoft 自己簽章設計上就提供了「終止任何 process」的功能(因為 Process Explorer 本來就是要管理 process 的工具)。AuKill 把這個 driver 載入後,就用它終止所有 EDR/AV 的 user-mode 處理程序——根本沒有「漏洞」這個概念。它做的事情就是 Microsoft 設計它要做的事

為什麼防禦這麼難

Microsoft 知道這個問題很多年了。他們的對策有四層:

對策 1:Driver Block Rules(推薦封鎖清單)

Microsoft 維護一份 XML,內含已知有漏洞的 driver 的 hash 和簽章資訊。Windows 會檢查每個要載入的 driver,如果在這份清單上就拒絕。

限制

  • 這份清單只在 HVCI 啟用時才強制執行來源
  • HVCI 預設只在新硬體+Windows 11 22H2 之後才預設啟用
  • 老設備、Windows 10、Windows Server 2019——很多都沒有
  • 規則是事後的——新發現的有漏洞 driver 要等 Microsoft 排定更新才會進清單
  • 規則的更新頻率比一些研究團隊回報的速度慢(Talos、Sophos 有時提前公布 PoC)

對策 2:HVCI(Hypervisor-Protected Code Integrity)

也叫 Memory Integrity。它的設計很巧妙:

  1. CPU 的 Intel VT-x / AMD-V 虛擬化技術建立一個迷你 hypervisor
  2. Windows kernel 自己被放進一個 VM 裡跑
  3. 任何 kernel 程式碼的修改,都必須經過外層 hypervisor 的驗證
  4. 即使 BYOVD 拿到 kernel R/W,寫入也會被 hypervisor 攔截

這是非常強的防禦——但有限制:

  • 需要硬體支援 SLAT、IOMMU、UEFI Secure Boot
  • 跟很多舊驅動不相容(這就是為什麼預設不啟用)
  • 攻擊者改 callback array 還是有可能繞過(因為 array 不在 code section、是 data)
  • HVCI 保護的是「不讓 unsigned code 在 kernel 執行」、不是「不讓 callback 被刪」——兩個是不同的攻擊面

對策 3:PPL(Protected Process Light)

Windows 的 EDR 進程可以被標記為 PPL,讓其他進程(即使是 SYSTEM)不能傷害它的 user-mode 部分。但 BYOVD 是直接在 kernel 動手,PPL 不在這個層級保護。

對策 4:ASR(Attack Surface Reduction)規則

Defender 有一條 ASR 規則叫 「Block abuse of exploited vulnerable signed drivers」。它會阻止 process 把已知有漏洞的 driver 寫到磁碟上。但對「driver 已經在系統上、攻擊者直接載入」的場景沒幫助。

Linux 怎麼做?

Linux 的設計哲學不同。Linux kernel 預設不要求 module 必須簽章——你可以 insmod evil.ko 載入任何東西。所以 Linux 早期沒有 DSE 這層,但也不會有 BYOVD(因為攻擊者不需要找有漏洞的舊 driver——他直接載自己的)。

從 Linux 5.4 開始,引入了 Kernel Lockdown LSM來源),有兩個模式:

  • Integrity mode:禁止任何修改 kernel 的操作(包括載入未簽章的 module)
  • Confidentiality mode:上面再加上禁止讀取 kernel 內部資訊(debugfs、/dev/mem 等)

啟用 Lockdown 需要:

  1. Kernel 編譯時 CONFIG_SECURITY_LOCKDOWN_LSM=y
  2. 啟用 Secure Boot(多數發行版會自動開啟 Lockdown)
  3. 想載入自己的 module,要用 MOK(Machine Owner Key) 簽章

實務上,啟用 Secure Boot 的 Ubuntu / RHEL / Fedora 預設就在 Lockdown integrity mode——這比 Windows 預設的保護等級更積極。但代價是維護自己的 kernel module 變得複雜(要管理 MOK),所以 server 環境經常會關掉。

你能做什麼

個人 Windows 使用者

  1. 用 Windows 11 22H2 以後的版本
  2. 在「Windows 安全性」→「裝置安全性」→「核心隔離」手動啟用「記憶體完整性(HVCI)」——這會強制 Driver Block Rules
  3. 確認「Microsoft 易受攻擊驅動程式封鎖清單」是「開啟」狀態
  4. 移除你不再使用的硬體監控工具、舊 GPU/CPU 工具——它們是 BYOVD 的常見來源

企業 IT/資安

  1. 部署 Windows Defender Application Control (WDAC) 或新名稱 App Control for Business,建立 driver 白名單而非黑名單
  2. 對端點機器啟用 ASR 規則「Block abuse of exploited vulnerable signed drivers」
  3. 把 Sysinternals 的 procexp.sysprocexp152.sys 列入封鎖清單——除非有特定的合理使用場景
  4. 用 EDR 監控 \Device\<driver_name> 的可疑 IOCTL 呼叫模式(許多 EDR 廠商已經把 EDRSandblast / AuKill 加入偵測規則)
  5. 監控 service 建立事件中、binary path 在使用者目錄或 %AppData% 的——這是 BYOVD 投放的訊號

Linux 系統管理員

  1. 啟用 Secure Boot + Kernel Lockdown LSM(Integrity mode 至少)
  2. 編譯 kernel 時開啟 CONFIG_MODULE_SIG=yCONFIG_MODULE_SIG_FORCE=y
  3. 用 IMA 對 module 做完整性度量
  4. 監控 init_module() / finit_module() 系統呼叫

最後想說的

BYOVD 是個很乾淨的範例,說明為什麼純粹的「簽章驗證」不等於「程式碼安全」

DSE 的設計沒錯。簽章驗證的目的是「這個 driver 是不是來自你信任的供應商」——這個問題它回答得很好。但攻擊者把問題改成「這個來自合法供應商的 driver 是不是寫得安全」——而簽章機制完全沒辦法回答這個問題。

這也是為什麼**縱深防禦(defense in depth)**這個觀念這麼重要:簽章 + HVCI + Block Rules + EDR + ASR 規則 + 行為監控——任何一層都不夠,必須疊起來才能擋住現代的 kernel 級攻擊。

對於那位看到「您的裝置受到保護」綠色勾勾的使用者來說——那個勾勾的意思是「沒有偵測到威脅」,不是「沒有威脅」。這兩件事之間的距離,就是 BYOVD 攻擊的工作空間。

參考資料


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言