­

如何通過macOS的磁碟管理工具實現系統提權

  • 2019 年 11 月 1 日
  • 筆記
寫在前面的話

近期,ZDI的研究人員「ccpwd」在一個名叫「diskmanagementd」的macOS守護進程中,發現了一個基於堆的緩衝區溢出漏洞。diskmanagementd這個服務主要負責對磁碟驅動器進行管理和分區,用戶可以通過磁碟實用工具(Disk Utility)來與該服務進行交互。該服務將會運行一個Mach伺服器,並允許客戶端使用Mach IPC介面來與伺服器端通訊(發送和接收資訊)。通過這種RPC機制,客戶端可以在Mach伺服器中執行各種通過MIG(Mach介面生成器)生成的功能函數。

漏洞分析

所有的通訊數據都需要經過launchd,即macOS的init初始化實現。關於該進程的更多細節可以通過查看其資訊屬性列表文件來了解,文件路徑如下:

/System/Library/LaunchDaemons/com.apple.diskmanagementd.plist

一開始,守護進程會分配一個調用函數,在之後發送和接收Mach消息時,內部進程通訊將需要調用這個函數。

在這裡,CFMachPortCreateWithPort會分配一個函數sub10000C241來作為負責處理Mach消息的回調函數,接收Mach消息的地址為0x10000BE1F。根據msghid,Mach消息中的某個值會傳送一條操作指令或函數ID,sub10000C241會間接使用這個ID來作為兩個遠程函數的調度表索引。sub100001DA2和sub_100002005分別負責啟動和移除後續的通訊會話。

Mach埠是單向通訊的,這也就意味著每個發送、接收請求都需要使用單獨的埠,蘋果稱之為:

「埠是請求服務的客戶端和提供服務的伺服器之間單向通訊通道的端點。如果要對此類服務請求提供答覆,則必須使用第二個埠,這與Unix中的(單向)管道類似。」

函數sub10000CCA9是可以通過sub100001DA2訪問到的,另一個Mach埠通過回調函數sub_10000DACC來創建,埠會保存在一個字典里,鍵名為「Comms-F2TPort」。緩衝區0x1000位元組處用於處理Mach消息的響應,並且資訊保存在字典中鍵名為「Comms-F2T-replyarea」的位置。

其中,setObject:forKey用於向字典中添加鍵值對:

當客戶端發送一條消息時,sub10000DACC將會被觸發,然後根據msghid來訪問MIG遠程程式調用。接下來,我們將注意力主要放在函數sub_1000087C9的身上:

緩衝區溢出發生在sub_1000087C9函數中,當用戶輸入數據長度經過計算後偏移量超過0x1000時,便會發生緩衝區溢出。

0x1000響應緩衝區基本上為r14,用戶輸入從偏移量0x38處開始,所以剩下的0xfc8

位元組即為用戶輸入區域,當輸入數據填充至0xfc8處時,strlen將會返回相同的值。經過計算之後,最終的值為 0xfcc [ ((0xfc8 + 1) + 3) & 0xfffffffc]。在地址0x100008ABD處,偏移量將會變成0x1004 [0xfcc+0x38],這裡允許泄露4個位元組,並寫入4個位元組數據,因此攻擊者就可以利用這種特性來實現攻擊了。但是這裡的數據泄露效果不是很顯著,因為大小僅為0x1000,而寫入操作需要在0x1004處完成,這也就意味著程式只能從後續數據塊中讀取4個位元組的數據。

這裡有幾個限制,首先是輸入數據中不能包含空字元,因為這將導致strlen在空字元處停止。另一個限制是在緩衝區結束後寫入的數據將始終是var_dc的內容,這部分內容就是sub b30返回的錯誤程式碼。

總結

分析這些類型的安全漏洞以及程式錯誤其實非常有趣,因為我們可以了解到一個非常小的錯誤如何導致一個嚴重的安全漏洞出現,並最終允許攻擊者在目標設備上實現任意程式碼執行,這也就是所謂的「蝴蝶效應」吧。目前,蘋果方面已經在macOS Mojave v10.14.5中修復了這個漏洞,並於2019年7月22日正式向用戶推送。

*參考來源:zerodayinitiative,FB小編Alpha_h4ck編譯,轉載請註明來自FreeBuf.COM