繞過安全啓動并建立持久性
在本部分中,我們将詳細了解 BlackLotus 如何在啓用 UEFI Secure Boot 的系統上實現持久性。由于我們将要描述的執行鏈非常複雜,我們将首先解釋基本原理,然後深入了解技術細節。
簡而言之,該過程包括兩個關鍵步驟:
利用 CVE-2022-21894 繞過安全啓動功能并安裝 bootkit。這允許在早期啓動階段任意執行代碼,此時平台仍然由固件擁有,UEFI 啓動服務功能仍然可用。這使得攻擊者可以在沒有物理訪問權限的情況下,在啓用了 UEFI Secure Boot 的設備上做許多不應該做的事情,例如修改僅用于啓動服務的 NVRAM 變量。這就是攻擊者在下一個步驟中爲 bootkit 設置持久性所利用的。通過将自己的 MOK 寫入 MokList 來設置持久性,Boot 僅服務 NVRAM 變量。這樣,它可以使用合法的 Microsoft-signed shim 加載其自簽名(由寫入 MokList 的密鑰的私鑰簽名)UEFIbootkit,而不是在每次啓動時利用該漏洞。有關這一點的更多信息,請參閱 Bootkit 持久性部分。
爲了使下面兩部分的分析更容易,研究人員将遵循執行圖(下圖)中所示的步驟。
繞過安全啓動并使用 MOK 設置持久性
利用 CVE-2022-21894
爲了繞過安全啓動,BlackLotus 使用 baton drop 漏洞(CVE-2022-21894):安全啓動安全功能繞過漏洞。盡管這個漏洞對系統安全影響很大,但它并沒有得到應有的重視。盡管微軟在 2022 年 1 月的更新中修複了該漏洞,但由于受影響的二進制文件仍未添加到 UEFI 取消列表中,因此攻擊者仍有可能利用該漏洞。因此,攻擊者可以将他們自己的易受攻擊的二進制文件副本帶到受害者的設備上,以利用此漏洞并繞過最新 UEFI 系統上的安全啓動。
此外,自 2022 年 8 月以來,針對該漏洞的概念證明(PoC)漏洞已公開可用。考慮到第一次 BlackLotus VirusTotal 提交的日期,惡意軟件開發人員可能隻是根據他們的需要調整了可用的 PoC,而不需要深入了解此漏洞的工作原理。
讓我們先簡單介紹一下該漏洞,主要是與 PoC 一起發布在 GitHub 上的文章中的關鍵點:
受影響的 Windows 啓動應用程序(如 bootmgr.efi、hvloader.efi、winload.efi …)允許在應用程序加載序列化安全啓動策略之前,使用 truncatememory BCD 啓動選項從内存中删除該策略。
這允許攻擊者使用其他危險的 BCD 選項,如 bootdebug、testsigning 或 nointegridchecks,從而破壞安全啓動。
有多種方法可以利用此漏洞——其中三種方法已發布在 PoC 存儲庫中。
例如,其中一個 PoC 顯示了如何利用它使合法的 hvloader.efi 加載任意的自簽名 mcupdate_
現在,我們繼續介紹 BlackLotus 如何利用此漏洞:
1. 安裝程序重新啓動機器後,UEFI 固件将繼續加載第一個啓動選項。對于 Windows 系統,默認情況下,第一個啓動選項是位于 ESP 上 ESP:/efi/Microsoft/boot 文件夾中的 bootmgfw.efi。這一次,固件沒有執行原始受害者的 bootmgfw.efi(安裝程序以前将其重命名爲 winload.efi),而是執行安裝程序部署的易受攻擊的啓動。
2. 執行 bootmgfw.efi 後,它将加載 BCD 啓動選項,該選項先前由安裝程序修改。下圖顯示了合法 BCD 和修改後 BCD 的比較。
3. 如下圖所示(路徑以綠色劃線),合法的 Windows Boot Manager 通常會将 Windows OS 加載程序(Windowssystem32winload.efi)作爲默認啓動應用程序加載。但這一次,使用修改後的 BCD,它繼續加載易受攻擊的 ESP:system32bootmgr.efi,避免内存 BCD 元素設置爲值 0x10000000,并且 custom:22000023 BCD 指向另一個攻擊者存儲在 ESP:system32BCD 中的 BCD。
合法 BCD 存儲(BEFORE)與 BlackLotus 安裝程序使用的存儲(AFTER)的比較
4. 在下一步中,執行的 ESP:system32bootmgr.efi 加載位于 ESP:system32BCD 中的附加 BCD。這個附加 BCD 的解析内容如下圖所示。
BlackLotus 安裝程序釋放的第二個 BCD ——用于利用 CVE-2022-21894
5. 由于從上圖所示的 BCD 文件加載了選項,bootmgr.efi 将繼續加載安裝程序部署的另一個易受攻擊的 Windows 啓動應用程序 ESP:system32hvloader.efi,即 Windows Hypervisor Loader。更重要的是,在同一 BCD 文件中指定了其他 BCD 選項:
值設置爲 0x10000000 的 truncatememory;
nointegridchecks 設置爲 Yes;
testsigning 也設置爲 Yes;
此時就會發生意想不到的事情,由于序列化的安全啓動策略應該在 0x10000000 以上的物理地址中加載(因爲前面步驟中使用了 avoidlowmemory),指定 truncatmemory 元素将有效地删除它。因此,中斷安全啓動并允許使用危險的 BCD 選項,如 nointegritychecks 或 testsigning。通過使用這些選項,攻擊者可以使 hvloader.efi 執行自己的自簽名代碼。
6. 爲此,使用此 PoC 中描述的技巧,即在執行過程中,合法的 hvloader.efi 從
從合法的 hvloader.efi 反編譯 BtLoadUpdateDll 函數,負責加載 mcupdate_*.dll
7. 現在,随着攻擊者自己的自簽名 mcupdate*.dll 被加載和執行,它将繼續執行這個鏈中的最後一個組件——一個嵌入式 MokInstaller (UEFI 應用程序)——參見圖 10 了解它是如何完成的。
Hex-Rays 反編譯惡意自簽名 mcupdate*.dll 二進制代碼
Bootkit 持久性
現在,MokInstaller 可以繼續設置持久性,方法是将攻擊者的 MOK 注冊到 NVRAM 變量中,并将合法的 Microsoft 簽名的 shim 二進制文件設置爲默認啓動加載程序來繼續設置持久性。
shim 是由 Linux 開發人員開發的第一階段 UEFI 啓動加載程序,用于使各種 Linux 發行版與 UEFI Secure Boot 一起工作。它是一個簡單的應用程序,其目的是加載、驗證和執行另一個應用程序,在 Linux 系統中,它通常是 GRUB 啓動加載程序。它的工作方式是,微軟隻簽署一個 shim, shim 負責其餘的工作,它可以通過使用 db UEFI 變量中的密鑰來驗證第二階段啓動加載器的完整性,還可以嵌入自己的 " 允許 " 或 " 取消 " 項或哈希列表,以确保平台和 shim 開發人員(例如 Canonical, RedHat 等)都信任的組件被允許執行。除了這些列表之外,shim 還允許使用用戶管理的外部密鑰數據庫,即 MOK 列表。該 MOK 數據庫存儲在名爲 MokList 的僅啓動 NVRAM 變量中。在不利用上述漏洞的情況下,需要物理訪問才能在啓用 UEFI Secure Boot 的系統上對其進行修改(僅在啓動期間,在系統加載程序調用 UEFI 啓動服務函數 ExitBootServices 之前可用)。然而,通過利用此漏洞,攻擊者能夠繞過 UEFI Secure Boot 并在調用 ExitBootServices 之前執行自己的自簽名代碼,因此他們可以輕松注冊自己的密鑰(通過修改 MokList NVRAM 變量),使填充程序執行任何應用程序(由該注冊密鑰簽名),而不會導緻安全違規。
MOK 啓動過程
8.MokInstaller UEFI 應用程序繼續爲 BlackLotus UEFI bootkit 設置持久性,并通過以下方式覆蓋利用痕迹:
8.1 從安裝程序創建的備份中恢複受害者的原始 BCD 存儲,并将 efi 替換爲合法的 microsoft 簽名 shim,該 shim 先前由安裝程序放置到 ESP:system32bootload.efi 中。
8.2 創建包含攻擊者自簽名公鑰證書的 MokList NVRAM 變量。請注意,此變量的格式與任何其他 UEFI 簽名數據庫變量(如 db 或 dbx)的格式相同,它可以由零個或多個 EFI_signature_LIST 類型的簽名列表組成,如 UEFI 規範中所定義。
8.3 從攻擊者的 ESP:system32 文件夾中删除涉及攻擊的所有文件。
最後,它會重新啓動計算機,使部署的 shim 執行安裝程序從 EFIMicrosoftBootgrub64.EFI 中删除自簽名 bootkit,grub64.EFI 通常是 x86-64 系統上 shim 執行的默認第二階段啓動加載程序。
Hex Rays 反編譯代碼—— MokInstaller UEFI 應用程序爲 BlackLotus bootkit 設置持久性
BlackLotus UEFI bootkit
一旦配置了持久性,就會在每次系統啓動時執行 BlackLotus bootkit。 bootkit 的目标是部署一個内核驅動程序和一個最終的用戶模式組件—— HTTP 下載器。在執行過程中,它試圖禁用其他 Windows 安全功能——基于虛拟化的安全(VBS)和 Windows Defender ——以提高成功部署和隐形操作的機會。在詳細介紹如何實現之前,讓我們先了解一下内核驅動程序和 HTTP 下載器的基本知識:
内核驅動程序負責:
部署鏈的下一個組件— HTTP 下載器;
在被終止運行的情況下保持加載器不被關閉;
防止從 ESP 中删除 bootkit 文件;
如果 HTTP 下載器指示的話,執行額外的内核有效負載;
根據 HTTP 下載器的指示,卸載 bootkit。
HTTP 下載器負責:
與 C&C 通信;
執行從 C&C 收到的命令;
下載并執行從 C&C 接收到的有效負載(支持内核有效負載和用戶模式有效負載)。
從安裝程序到 HTTP 下載器的完整執行流程(簡化後)如下圖所示。我們将在下一節中更詳細地描述這些步驟。
BlackLotus UEFIbootkit 執行示意圖
BlackLotus 執行流程
執行步驟如下(這些步驟如下圖所示):
1.UEFI 固件執行默認的 Windows 啓動選項,該選項通常存儲在 EFIMicrosoftbootbootmgfw.EFI 中的文件。正上所述,MokInstaller 二進制文件用一個合法的簽名 shim 替換了這個文件。
2. 執行 shim 時,它讀取 MokList NVRAM 變量,并使用攻擊者先前存儲在其中的證書來驗證第二階段啓動加載程序——位于 EFIMicrosoftBootgrubx64.efi 中的自簽名 BlackLotus UEFI 啓動程序。
3. 驗證後,shim 執行 bootkit。
4.bootkit 從創建僅啓動 VbsPolicyDisable NVRAM 變量開始。如本文所述,此變量在啓動期間由 Windows OS 加載程序評估,如果已定義,則不會初始化核心 VBS 功能,如 HVCI 和憑據保護。
5. 在以下步驟中,bootkit 繼續使用 UEFIbootkit 使用的通用模式。它攔截典型 Windows 啓動流中包含的組件的執行,例如 Windows 啓動管理器、Windows OS 加載器和 Windows OS 内核,并将它們的一些功能挂鈎到内存中。另外,它還嘗試通過修複某些驅動程序來禁用 Windows Defender。所有這些都是爲了在系統啓動過程的早期階段實現有效負載的執行,并避免檢測。以下函數已挂鈎或修複:
5.1 bootmgfw.efi 或 bootmgr.efi 中的 ImgArchStartBootApplication:該函數通常由 bootkit 挂鈎,以捕捉 Windows OS 加載程序(winload.efi)加載到内存中但尚未執行的時刻——這是執行更多内存修複的正确時刻。
5.2 winload.efi 中的 BlImgAllocateImageBuffer:用于爲惡意内核驅動程序分配額外的内存緩沖區。
5.3 winload.efi 中的 OslArchTransferToKernel:連接以捕捉系統内核和某些系統驅動程序已加載到内存中但尚未執行的時刻,這是執行更多内存修複的最佳時刻。下面提到的驅動程序在此挂鈎中進行了修複。下圖顯示了這個挂鈎中負責在内存中查找适當驅動程序的代碼。
5.4 WdBoot.sys 和 WdFilter.sys:BlackLotus 修複了 WdBoot.sys 和 WdFilter.sys(分别是 Windows Defender ELAM 驅動程序和 Windows Defender 文件系統篩選器驅動程序)的入口點,以立即返回。
5.5 disk.sys:bootkit 将 disk.sys 驅動程序的入口點挂鈎,以便在系統初始化的早期階段執行 BlackLotus 内核驅動程序。
OslArchTransferToKernel 挂鈎的反編譯代碼——修複 Windows Defender 驅動程序并搜索 disk.sys 入口點
6. 接下來,當系統内核執行 disk.sys 驅動程序的入口點時,已安裝的挂鈎會跳轉到惡意内核驅動程序入口點。惡意代碼反過來恢複原始 disk.sys 以使系統正常運行,并等待 winlogon.exe 進程啓動。
7. 當惡意驅動程序檢測到 winlogon.exe 進程已啓動時,它會向其中注入并執行最終的用戶模式組件—— HTTP 下載器。
内核驅動程序
内核驅動程序主要負責四個任務:
将 HTTP 下載器注入到 winlogon.exe 中,并在線程終止時重新注入它;
保護部署在 ESP 上的 bootkit 文件不被删除;
解除用戶模式 Windows Defender 進程 MsMpEngine.exe;
與 HTTP 下載器通信,并在必要時執行任何命令。
HTTP 下載器持久性
内核驅動程序負責部署 HTTP 下載程序。當驅動程序啓動時,它會等待名爲 winlogon.exe 的進程啓動,然後再執行任何其他操作。進程啓動後,驅動程序解密 HTTP 下載程序二進制文件,将其注入 winlogon.exe 的地址空間,并在新線程中執行。然後,驅動程序會定期檢查線程是否仍在運行,并在必要時重複注入。如果驅動程序檢測到内核調試器,則不會部署 HTTP 下載程序。
保護 ESP 上的 bootkit 文件不被删除
爲了保護 ESP 上的 bootkit 文件,内核驅動程序使用了一個簡單的技巧。它打開所有要保護的文件,複制并保存其句柄,并使用 ObSetHandleAttributes 内核函數将 HandleFlags(OBJECT_HANDLE_flag_INFORMATION)參數内的 ProtectFromClose 标志指定爲 1,從而保護句柄不被任何其他進程關閉。這将阻止任何删除或修改受保護文件的嘗試。受保護的文件包括:
ESP:EFIMicrosoftBootwinload.efiESP:EFIMicrosoftBootbootmgfw.efiESP:EFIMicrosoftBootgrubx64.efi
如果用戶試圖删除這些受保護的文件,就會出現如下圖所示的情況。
試圖删除受 BlackLotus 驅動程序保護的文件
作爲另一層保護,如果用戶或安全軟件能夠取消設置保護标志并關閉句柄,内核驅動程序将持續監視它們,如果句柄不再存在,則通過調用 KeBugCheck(INVALID_kernel_HANDLE)函數來生成一個 BSOD。
解除主 Windows Defender 進程
内核驅動程序還試圖解除主 Windows Defender 進程 MsMpEng.exe 的防護。爲此,它通過爲每個進程設置 SE_PRIVILEGE_REMOVED 屬性來删除所有進程的令牌權限。因此,Defender 進程應該無法正确地完成其工作(例如掃描文件)。但是,由于該功能執行得很差,因此可以通過重新啓動 MsMpEng.exe 進程使其失效。