0
在疫情防控常態(tài)化的背景之下,為了“停課不停學”,眾多高校紛紛開啟了網課模式。近日,支付寶光年安全實驗室收到清華大學網絡與信息安全實驗室(NISL)的邀請,為同學們分享在 macOS 內核(XNU)上的攻防實戰(zhàn)思路和成果。為了讓更多聽眾能夠遠程參與,本次分享以釘釘直播的方式公開進行。包括實驗室的同學在內,一共吸引了兩百多位聽眾參與了線上公開課交流。
下面帶讀者一起回顧一下這次分享的內容
目前主流的操作系統對應用程序區(qū)分對待,應用不同的沙盒配置、用戶組等措施區(qū)分可執(zhí)行代碼的特權。通常系統代碼執(zhí)行最高權限就是操作系統內核和擴展模塊(驅動程序)。惡意程序為了獲得盡可能多的能力,例如隱藏自身運行痕跡或者讀取機密信息(如鑰匙串中保存到應用程序密碼和 iCloud 訪問憑據等),就要想方設法從遠程代碼執(zhí)行作為起點,突破沙箱限制和用戶組限制,獲得內核代碼執(zhí)行的權限。此類攻擊方式稱為本地權限提升(Local Escalation of Privileges)。
在以往公開的研究當中,無論是各種黑客破解秀還是學術論文,攻防的戰(zhàn)場都相對集中在內存安全上。通過利用錯誤的邊界檢查、對象生命周期管理等未定義行為,轉換成漏洞利用原語,改寫內存中關鍵結構的內容實現高權限的任意代碼執(zhí)行。曾有論文《SoK: Eternal War in Memory》將其稱之為“永恒之戰(zhàn)”,可見內存安全問題當下層出不窮和亟待解決的現狀。既然暫時不能徹底消滅漏洞,就提升攻擊門檻。操作系統引入了多種緩解措施(mitigation)來提升利用難度,硬件廠商也在指令集層面實現了控制流保護、內存標簽擴展等技術進行對抗。
但操作系統軟件的復雜度決定了攻擊手段不會局限在某個方面。支付寶光年安全實驗室就向蘋果報告了 macOS 的多個邏輯漏洞,避開所有的通用內存防御,實現 100% 穩(wěn)定性的權限提升。在 macOS High Sierra(10.13.6)上從 Safari 瀏覽器的沙箱內逃逸,然后獲取 root 權限,最終讓 XNU 內核加載一個沒有代碼簽名的內核擴展,實現對 macOS 的完全控制。本次公開課的內容就是詳細講解了其中攻擊內核的部分的技術細節(jié)和啟示。
macOS 允許 root 權限的用戶安裝內核驅動程序,但要求驅動程序必須經過蘋果認證簽名,以及在安裝后需要用戶額外確認一次(User-Approved Kernel Extension Loading)才會激活。通過分析 XNU 的源代碼可以發(fā)現,針對驅動程序的簽名驗證還有用戶確認的邏輯實際上都在用戶態(tài)實現。這些進程都必須擁有 XNU 認可的“良民證”,即嵌入在代碼簽名中,稱之為 entitlements 的一段 XML 字符串。
只有啟用了com.apple.private.security.
kext-management 特權,并擁有蘋果簽名的程序才能安裝內核驅動。同時macOS 默認配置下啟用了 SIP (System Intergrity Protection),禁止注入代碼到其他進程,即使有 root 權限也不行。系統內核認為這足以保證攻擊者無法偽造這種特權,因此來自用戶態(tài)的請求是可信的,會直接執(zhí)行提交過來的代碼。
我們在這種模型上找到了實現的漏洞。由于內核完全信任了特定用戶態(tài)進程,因此我們不需要攻擊 XNU 本身,而只需要在用戶態(tài)想辦法注入惡意代碼到對應進程,打破信任邊界即可。macOS 自帶了一些命令用于應用程序的調試和采樣,其具有 com.apple.system-task-ports 特權,可以繞過 SIP 訪問受限制的系統進程。如果被采樣的進程是 swift 編寫的,為了還原程序上下文堆棧的符號信息,系統會在特定的目錄下搜索 swift 相關的動態(tài)鏈接庫并載入。搜索路徑有四個備選,優(yōu)先級最高的路徑受到系統保護無法修改。但我們給進程強制添加一個 sandbox,禁止其訪問系統自帶的合法路徑,就會強迫其走備選的代碼分支,從環(huán)境變量 DEVELOPER_DIR 控制的目錄中載入任意代碼,造成運行庫劫持。
但這一步又遇到了一個問題。iOS / macOS 為了防御動態(tài)庫劫持,使用了一種名為 Library Validation 的手段,即動態(tài)載入運行庫之前會檢查其代碼簽名是否來自蘋果或者同一開發(fā)者。我們在舊的 macOS 系統上找到了對應程序,但是不帶 Library Validation 的版本,成功觸發(fā)這一代碼劫持漏洞。有了用戶態(tài)任意注入代碼的權限之后,通過注入代碼到管理內核驅動的服務進程,竊取其 com.apple.private.security.
kext-management 特權,成功欺騙 XNU 內核執(zhí)行了沒有任何代碼簽名的模塊。
運行任意一個 swift 程序
從舊版本(El Capitan)macOS 系統中復制一個沒有保護的 symbols 命令
釋放一個惡意的 libswiftDemangle.dylib 到任意目錄
調用 sandbox_init_with_parameters 添加沙箱配置,取消當前進程對系統自帶 libswiftDemangle.dylib 的訪問權限
設置當前進程的 DEVELOPER_DIR 環(huán)境變量,指向惡意的路徑
執(zhí)行 symbols 命令對 swift 程序采樣,觸發(fā)代碼劫持漏洞,載入惡意的動態(tài)鏈接庫
使用這個 symbols 的調試特權附加到 kextd 進程,注入最后階段的攻擊載荷
使用 kextd 提交驅動程序的特權向 XNU 內核注入無簽名的擴展,實現用戶態(tài) root 權限到內核任意代碼執(zhí)行
在這個攻擊鏈條中最重要的突破口實際上是利用了代碼動態(tài)庫劫持,將惡意代碼注入到合法的進程中,從而繞過基于代碼簽名的信任邊界。蘋果在 macOS Mojave 之后強制啟用了 Hardened Runtime 機制,即將 Library Validation 驗證機制的啟用條件從 opt-in 改成了 opt-out,默認全部開啟。針對從老版本系統復制“可信”程序的問題,蘋果在新的 AppleMobileFileIntegrity 驅動中硬編碼了進程采樣工具的標識符,即不再信任舊版本的程序。此外針對任意進程調試,蘋果引入了一個新的 com.apple.system-task-ports.safe 特權,以限制舊版程序的能力。目前,此問題已經得到修復。
不過最關鍵的 XNU 驅動驗證上仍然保留了用戶態(tài)驗證的策略。同時 kextd 進程還加入了 com.apple.security.cs.allow-unsigned-executable-memory 特權,也就是仍然執(zhí)行無簽名的代碼,給漏洞利用提供了方便。假設 kextd 之后出現進程間通信的漏洞,能夠接管控制流,仍有可能通過用戶態(tài)特殊進程的任意代碼執(zhí)行來攻擊內核。
通常攻擊操作系統內核,大量的研究和案例大體都是類似的思路,即通過 syscall 或者平臺特定的內核調用機制(如 XNU 的 IOKit),觸發(fā)內存訪問違例,篡改系統內核的結構甚至劫持控制流,從而獲得更高的代碼執(zhí)行權限。與以往的研究相比,這次分享的案例具有鮮明的特點:
完全沒有利用常規(guī)的內存安全問題,嚴格意義上甚至沒有攻擊 XNU 本身,而是濫用了其信任邊界
從舊版本的操作系統中復制具有合法蘋果代碼簽名,同時允許加載第三方代碼的程序,進一步突破信任模型
原本作為系統安全防線的沙箱機制,在特定條件下卻變成了漏洞利用的重要條件,“以子之盾攻子之盾”。
這次線上分享除了這一套原創(chuàng)漏洞和利用之外,還簡單介紹了 Psychic Paper、以及 phoenhex&qwerty team 在Pwn2Own 2019 所用的內核漏洞等來自其他安全研究員的案例。網絡安全專業(yè)的同學在做研究時通常更喜歡去解決一些普適性的問題,有時會忽視這種平臺特性相關的設計缺陷。而在實戰(zhàn)應用中,這種類型的漏洞有時能以更低的成本實現攻擊的目的。
支付寶光年安全實驗室
隸屬于支付寶安全實驗室。通過對基礎軟件及設備的安全研究,達到全球頂尖破解能力,致力于保障螞蟻金服及行業(yè)金融級基礎設施安全。因發(fā)現并報告行業(yè)系統漏洞,數十次獲得Google、Apple等國際廠商致謝。
雷峰網版權文章,未經授權禁止轉載。詳情見轉載須知。