過去幾年,UEFI 防病毒領域發生了顯著的變化,其中尤以 UEFI 惡意引導程式的進化最為突出。此類惡意程式最早可追溯至 2012 年,當時 Andrea Allievi 提出了首個 UEFI 惡意引導程式的概念驗證(PoC),開創了在現代 Windows 系統上部署 UEFI 惡意引導程式的先河。此後,許多其他概念驗證(例如 EfiGuard、Boot Backdoor、UEFI 惡意引導程式)陸續出現。然而,真正意義上的 UEFI 惡意引導程式在現實世界中浮現,卻是多年以後的事(可參考 2021 年 ESET 關於 ESPecter 的部落格文章,以及同年卡巴斯基關於 FinSpy 惡意引導程式的部落格文章)。又過了兩年,臭名昭著的 BlackLotus(首款能夠在最新系統上繞過 UEFI 安全引導機制的 UEFI 惡意引導程式)才正式現身。
上述已公開的惡意引導程式有一個共同點,即僅對 Windows 系統有效。然而,今天我們率先公布一項最新發現:首款專為 Linux 系統設計的 UEFI 惡意引導程式已經問世,其開發者將其命名為 Bootkitty。我們認為,該惡意引導程式僅是一個初步的概念驗證。根據我司遙測系統的回饋,它尚未在現實世界中被部署。然而,它的出現傳遞了一個重要訊息:UEFI 惡意引導程式已不再局限於 Windows 系統。
此惡意引導程式的主要目的是禁用內核的簽名驗證功能,並通過 Linux 的 init 進程(即系統啟動期間由 Linux 核心執行的第一個進程)預加載兩個目前尚未知的 ELF 二進制檔案。在分析過程中,我們發現了一個可能與此有關的未簽名內核模組–有跡象表明,它可能是由同一群引導程式的開發者編寫的。該模組部署了一個 ELF 二進制檔案,負責載入我們在分析時尚未識別的另一個內核模組。
本文要點:
- 2024年11月,一個不為人知的UEFI應用程式 bootkit.efi 被上傳到 VirusTotal。
- 經初步分析後,我們確認這是一款名為 Bootkitty 的UEFI惡意引導程式。令人驚訝的是,這是首款針對 Linux,尤其是某些 Ubuntu 版本的UEFI惡意引導程式。
- Bootkitty 使用自簽名憑證進行簽名,因此除非攻擊者的憑證已被安裝,否則無法在啟用了UEFI安全啟動的系統上運行。
- Bootkitty 的目的是無縫引導 Linux 核心,無論系統是否啟用了UEFI安全啟動,因為它會在 GRUB 執行之前,修改記憶體中不具防篡改驗證功能的關鍵數據。
- bootkit.efi 包含多個工件,這表明它更像是一個概念驗證(Proof of Concept),而非威脅行為者的實際工具。
- 我們還發現可能與其相關的一個核心模組,並將其命名為 BCDropper。該模組會部署一個ELF程式,該程式負責加載另一個核心模組。
Bootkitty 概況
正如前文所述,Bootkitty 包含多個工件。這表明我們正在處理的是一個概念驗證(Proof of Concept),而非現實世界中活躍的惡意程式。在本節中,我們將深入探討這些工件,揭示該惡意引導程式的基本情況。
Bootkitty 包含兩個未使用的函數,能夠在執行過程中將特定字符串顯示於螢幕上。第一個函數的輸出如圖1所示,它可以打印ASCII圖像。我們認為該圖像代表引導工具包的名稱:Bootkitty。

圖1. 惡意引導程式中內建的ASCII圖像
第二個函數可以打印文字,如圖2所示。該文字中疑似包含引導程式的開發者名單,以及開發過程中可能的參與者名單。
圖片中提到的一個姓名可以在 GitHub 上找到,但其個人資料中並未提及任何與UEFI引導程式開發項目相關的公共資源庫。因此,我們無法確認或否認惡意引導程式中提及姓名的真實性。

圖2. 惡意引導程式中內建的人員名單(已編輯)
每次開機時,Bootkitty 都會在螢幕上打印如圖3所示的字符串。

圖3. Bootkitty 的歡迎辭
請注意,下文的「可加載核心模組」一節中也提到了 BlackCat。儘管名稱相同,但我們認為它與 ALPHV/BlackCat 勒索病毒團夥沒有任何關聯。這是因為 BlackCat 僅僅是研究人員使用的一個名稱,而 Bootkitty 是以 C 語言開發的;而同名團伙自稱 ALPHV,並且僅使用 Rust 開發惡意程式。
如前文所述,Bootkitty 目前支持的系統數量有限。其原因在於,為了在記憶體中找到需要修改的函數,該引導程式採用了硬編碼的字節模式。雖然字節模式匹配是引導程式的常用手法,但其作者並未使用可以覆蓋多種內核或 GRUB 版本的最佳模式;因此,該引導程式僅能在有限的配置環境下實現完整功能。
對該惡意引導程式的應用構成更大限制的是其給解壓後的 Linux 核心打補丁的方式:在內核映像解壓後,Bootkitty 只是簡單地將惡意補丁複製到內核映像中硬編碼的偏移量位置,如圖4所示。

圖4. Bootkitty 中負責在解壓縮內核執行前篡改其記憶體數據的代碼
我們將在下文的「Linux 核心映像解壓縮掛鉤」一節中,解釋該惡意引導程式如何實際篡改內核數據。現在請注意,由於圖4所示函數中缺少內核版本檢查,Bootkitty 可能會在這些硬編碼偏移量處,對完全隨機的代碼或數據進行篡改,從而導致系統崩潰,而無法成功入侵或掌控系統。這是支持其為概念驗證(Proof of Concept)的事實之一。
另一方面,這可能是由不法分子開發的惡意程式的初始版本,而非已準備好投入使用的生產版本。
最後需要說明的是,該惡意引導程式的二進制文件附帶了一個自簽名憑證,如圖5所示。

圖5. 惡意引導程式附帶的自簽名憑證
技術分析
從 Bootkitty 的執行步驟開始,如圖6所示。以下將簡要介紹其主要功能,並在後續部分進行更詳細的分析。
主要關注以下三個部分:
1. 惡意引導程式的執行及其對正規 GRUB 啟動加載器的篡改(圖6中第4點和第5點)
2. 篡改 Linux 核心的 EFI stub loader(圖6中第6點和第7點)
3. 篡改解壓後的 Linux 核心映像(圖6中第8點和第9點)

圖6. Bootkitty 執行步驟
初始化並與 GRUB 掛鉤
Bootkitty 由 shim 執行後,首先會檢查 SecureBoot 的 UEFI 變量值,以確定 UEFI 安全啟動機制是否已啟用。如果已啟用,它會繼續從 UEFI 認證協議中掛鉤兩個函數(此過程如圖7所示):
- EFI_SECURITY2_ARCH_PROTOCOL.FileAuthentication:此函數被固件用於測量和驗證 UEFI PE 映像的完整性。Bootkitty 通過掛鉤函數篡改了此函數的輸出,使其始終返回 EFI_SUCCESS,即驗證成功。
- EFI_SECURITY_ARCH_PROTOCOL.FileAuthenticationState:此函數被固件用於執行平台專用策略,以響應不同的身份驗證狀態值。同樣,惡意引導程式通過掛鉤篡改該函數,使其始終返回 EFI_SUCCESS,從而使固件可以使用該文件,而不考慮實際的身份驗證狀態。

圖7. 與 UEFI 安全認證協議掛鉤
加載 GRUB 並掛鉤內存代碼
檢查完 UEFI 安全啟動狀態後,Bootkitty 會通過 EFI 系統分區的硬編碼路徑 /EFI/ubuntu/grubx64-real.efi 加載官方 GRUB。該文件應是由攻擊者創建的 GRUB 官方文件的備份。在 GRUB 被加載後(尚未執行),惡意引導程式開始在 GRUB 的內存中篡改並掛鉤以下代碼:
- Peimage GRUB 模組中的 start_image 函數
– 此函數負責啟動已加載的 PE 映像,GRUB 使用它來啟動 Linux 核心的 EFI stub 二進制文件(如 vmlinuz.efi 或 vmlinuz)。– 掛鉤函數利用了在掛鉤執行時 vmlinuz 已載入內存但尚未執行的空檔,篡改了 vmlinuz 中負責解壓縮 Linux 實際內核映像的函數。
– 根據分析,我們認為這裡被篡改的函數應該是 zstd_decompress_dctx,儘管由於 Linux 核心的特定編譯方式,確切名稱可能難以確定。詳情請參閱下文的「Linux 核心映像解壓縮掛鉤」一節。
- shim_lock_verifier_init 函數
– 此函數是 GRUB 內部 shim_lock 驗證機制的一部分,在啟用了 UEFI 安全啟動的狀態下會自動激活。– 該函數負責決定引導過程中是否需要驗證現有文件(如 GRUB 模組、Linux 核心、配置文件等)。
– 掛鉤函數將該函數的輸出修改為 GRUB_VERIFY_FLAGS_SINGLE_CHUNK(值為 2),理論上這應增強安全性。但由於下一步的掛鉤會繞過此函數,因此該修改實際上毫無作用。
- grub_verifiers_open 函數
– GRUB 在打開文件時會隨時調用此函數,用於檢查是否需要對擬加載的文件進行完整性驗證。– 此函數被惡意引導程式掛鉤後,在不檢查任何簽名的情況下直接返回結果,甚至完全繞過了已掛鉤的 shim_lock_verifier_init 函數。
Linux 核心映像解壓縮掛鉤
該掛鉤負責篡改解壓縮的 Linux 核心映像數據。在核心映像解壓縮之前,掛鉤會:
- 恢復原解壓縮函數的字節,並執行該函數解壓核心映像
- 解壓完成後,篡改核心數據(僅限內存中的核心映像)
篡改過程中,掛鉤代碼在硬編碼偏移量處進行以下操作(如圖8所示):
- 重寫核心版本和 Linux banner 字符串為 BoB13:這對系統影響不大,主要是標記痕跡。
- 掛鉤 module_sig_check 函數:這可能用於繞過核心模組的簽名驗證。
- 篡改指向 init 進程第一個環境變量的指針/地址:這可能是為了在系統初始化時注入惡意行為。

圖8. Vmlinuz 之中的 Bootkitty 內核解壓縮掛鉤
函數 module_sig_check 被篡改為始終返回 0。此函數負責檢查模組是否具有有效簽名。將該函數篡改為返回 0 後,內核將加載任何模組,而不再驗證其簽名。在已啟用 UEFI 安全啟動的 Linux 系統中,擬加載的內核模組必須具有簽名。當內核在啟用了 CONFIG_MODULE_SIG_FORCE 的情況下構建,或當內核命令行參數 module.sig_enforce=1 被傳遞時,這種情況也會發生,詳情請參見 Linux 內核文檔的說明。很可能發生的情況是,後續階段至少會加載一個惡意內核模組,如下文所分析的投放器等。
Linux 內核執行的第一個進程是第一個有效硬編碼路徑的 init(啟動/init from initramfs),並附帶命令行參數和環境變量。掛鉤代碼將第一個環境變量替換為 LD_PRELOAD=/opt/injector.so /init。LD_PRELOAD 是一個環境變量,用於在加載其他對象之前加載 ELF 共享對象,並可用來覆蓋函數。這是攻擊者加載惡意二進制文件的常見手法。在本例中,當 init 進程啟動時,會加載 /opt/injector.so 和 /init ELF 共享對象。這裡有一點我們不太清楚作者的意圖,主要是為何要將第二個 /init 字符串納入 LD_PRELOAD。
我們目前尚未發現任何惡意的 ELF 共享對象。然而,在本文即將發表之際,一篇涉及我們報告中提到的缺失組件的說明性文章已經發表。現在看來,這些對象僅僅是用來加載下一階段的惡意程式。
後果及補救措施
除了加載未知的 ELF 共享對象外,Bootkitty 還會在系統中留下足跡。首先是刻意修改內核版本和 Linux banner 字符串(非必要步驟)。前者可以通過執行 uname -v 看到(圖 9),而後者可以通過執行 dmesg 看到(圖 10)。

圖9. 執行 uname 後出現的 BoB13 字符串

圖10. 執行 dmesg 後出現的 BoB13 字符串
我們分析過程中發現,在執行 dmesg 命令後,還可以看到有關 init 進程運行情況的詳細信息。該進程隨 LD_PRELOAD 環境變量運行,如圖 11 所示(最初是 HOME=/,現已被惡意引導程序替換為 LD_PRELOAD=/opt/injector.so /init)。

圖11. 執行 dmesg 後可看到的 init 進程參數和環境變量
請注意,圖11第一行中的 /init 對應 initramfs 中的官方程序,它最終會將控制權交給 Ubuntu 系統中默認的 systemd。是否存在 LD_PRELOAD 環境變量,還可以通過查看 /proc/1/environment 文件來驗證。
我們在測試環境下使用 Bootkitty 啟動系統後,注意到內核被標記為受污染(圖12中的命令可用於檢查污染值),而在沒有惡意引導程序的情況下則一切正常。對於已啟用 UEFI 安全啟動的系統,另一種判斷惡意引導程序是否存在的方法是,開機時嘗試加載一個無簽名的虛擬內核模組。如存在惡意引導程序,模組將被加載;如不存在,內核將拒絕加載該模組。

圖12. 系統感染 Bootkitty 後開機的污染狀態
去除惡意引導程序的一個簡單補救技巧是,將官方文件 /EFI/ubuntu/grubx64-real.efi 移回其原始位置,即 /EFI/ubuntu/grubx64.efi。這會使 shim 執行官方 GRUB,使系統在沒有惡意引導程序干預的情況下啟動(注意,這樣做只適用於惡意引導程序部署為 /EFI/ubuntu/grubx64.efi 的情況)。
BCDropper 和 BCObserver
在惡意引導程序之外,我們還發現了一個未簽名的內核模塊 BCDropper 可能與它有關。該模塊與惡意引導程序一起,在同一時間由同一帳號上傳到 VirusTotal,並且內含可能與惡意引導程序相同的多個跡象,這些跡象表明它們可能由同一夥作者開發,例子如下:
- 執行 modinfo 命令後會顯示 BlackCat 字符串,如圖13所示。
- 該模塊二進制文件的調試路徑中含有另一個 blackcat 字符串,如圖14所示。
- 內含未使用的文件隱藏功能,可以從目錄列表中隱藏指定條目。在硬編碼的文件名字符串中,用於過濾這些條目的前綴之一是 injector,如圖15所示(注意,Bootkitty 試圖通過 /opt/injector.so 路徑預加載共享庫)。
即使掌握了上述證據,我們也無法確定該內核模塊是否與 Bootkitty 有關(或由同一夥開發人員開發)。此外,惡意引導程序
支持圖13中提到的內核版本(6.8.0-48 generic)。

圖13. 投放器模塊信息

圖14. 投放器調試符提到 blackcat

圖15. 投放器中的待隱藏文件列表
顧名思義,該內核模塊會將我們命名為 BCObserver 的 ELF 內建文件,釋放到 /opt/observer 目錄中,並使用 /bin/bash 來執行它(圖17)。不僅如此,該模塊還會從模塊列表中刪除自身條目來隱藏自己。它還實現了一系列與 rootkit 相關的其他功能,如隱藏文件(見圖15)、進程和開放端口等,但投放器不會直接使用這些功能。

圖16. Hex-Rays 反編譯的投放器代碼
BCObserver 是一個相當簡單的應用程序。它會首先等待顯示管理器 gdm3 運行,然後再通過 finit_module 系統調用指令,從 /opt/rootkit_loader.ko 載入一個未知的內核模塊。等待顯示管理器啟動的作用是,確保代碼在系統完全啟動後再加載內核模塊。

圖17. Hex-Rays 反編譯的監視器代碼
雖然我們無法確定,投放器是否與惡意引導程序有某種關聯,以及如果有的話,投放器是如何執行的,但我們非常確定,惡意引導程序篡改 module_sig_check 函數是有原因的,並且加載未簽名內核模塊(如這裡介紹的投放器)肯定也是有意義的。
結論
不管是不是概念驗證,Bootkitty 都標誌著 UEFI 病毒領域的一個有趣進化,打破了現代 UEFI 惡意引導程序是 Windows 專屬威脅的說法。儘管現階段 VirusTotal 上的最新樣本還沒有對大多數 Linux 系統構成真正威脅,但它凸顯了為未來潛在威脅做好準備的必要性。
為了使您的 Linux 系統遠離此類威脅,請確保啟用 UEFI 安全引導功能,將系統固件和操作系統更新至最新版本,UEFI 安全引導程序禁用簽名庫也一樣。
IOC
完整 IOC 和樣本列表,歡迎來我司 GitHub 資料庫查閱。
文件

MITRE ATT&CK 技術分析
本表使用 MITRE ATT&CK 框架第 16 版生成

關於ESET
ESET成立於1992年,是一家面向企業與個人用戶的全球性的電腦安全軟體提供商,其 獲獎產品——NOD32防病毒軟體系統,能夠針對各種已知或未知病毒、間諜軟體 (spyware)、rootkits和其他惡意軟體為電腦系統提供實時保護。ESET NOD32佔用 系統資源最少,偵測速度最快,可以提供最有效的保護,並且比其他任何防病毒產品獲 得了更多的Virus Bulletin 100%獎項。ESET連續五年被評為“德勤高科技快速成長500 強”(Deloitte’s Technology Fast 500)公司,擁有廣泛的合作夥伴網絡,包括佳 能、戴爾、微軟等國際知名公司,在布拉迪斯拉發(斯洛伐克)、布里斯托爾(英國 )、布宜諾斯艾利斯(阿根廷)、布拉格(捷克)、聖地亞哥(美國)等地均設有辦事 處,代理機構覆蓋全球超過100個國家。
關於 Version 2 Digital
資安解決方案 專業代理商與領導者
台灣二版 ( Version 2 ) 是亞洲其中一間最有活力的 IT 公司,多年來深耕資訊科技領域,致力於提供與時俱進的資安解決方案 ( 如EDR、NDR、漏洞管理 ),工具型產品 ( 如遠端控制、網頁過濾 ) 及資安威脅偵測應 變服務服務 ( MDR ) 等,透過龐大銷售點、經銷商及合作伙伴,提供廣被市場讚賞的產品及客製化、在地化的專業服務。
台灣二版 ( Version 2 ) 的銷售範圍包括台灣、香港、中國內地、新加坡、澳門等地區,客戶涵 蓋各產業,包括全球 1000 大跨國企業、上市公司、公用機構、政府部門、無數成功的中小企業及來自亞 洲各城市的消費市場客戶。




