2019年3月25日,Apple公司发布了macOS Mojave 10.14.4和iOS 12.2。这两个更新修复了包括CVE-2019-8507在内的安全漏洞。该漏洞是FortiGuard Labs研究人员于2019年1月3日报告给apple公司的。
本文主要从技术上分析macOS CVE-2019-8507漏洞。
概述
QuartzCore也称之为CoreAnimation,是macOS和iOS用来创建动画场景图形的框架。CoreAnimation框架使用的是一个特殊的渲染模型,其中图像操作运行在一个单独的进程中。在macOS系统中,是WindowServer进程,在iOS中是backboard进程。
服务名为com.apple.CARenderServer
,是在CARenderServer
中引用的。该服务存在于macOS和iOS中,可以通过Safari沙箱访问。在macOS中,当QuartzCore在CA::Render::Decoder::decode_shape()
函数中处理图像对象时,会发送内存破坏漏洞。还可能会引发应用奔溃。
下面是该问题被触发后WindowServer
进程被破坏后日志记录:
PoC
下面介绍用来触发该漏洞的PoC:
下面是原始的Mach消息和伪造的Mach消息的比较:
图1. 原始的Mach消息和伪造的Mach消息的比较
通过二进制文件差异分析,只需将0xB6
处的一个字节从0x06
修改为0x86
就可以触发该漏洞。
如PoC代码所示,为了发送一个伪造的Mach消息来触发该漏洞,首先需要发送一个msgh_id 40202
的Mach消息来从新连接的客户端处提取connection ID。获取connection ID后,就可以在伪造的Mach消息中对应的0x2C
处设置该值。最后发送Mach消息来重现该漏洞。
漏洞根源分析
这一部分使用LLDB来动态分析该漏洞来确定漏洞的根源。
注:需要通过SSH模式调试WindowServer进程。
基于日志中奔溃的线程分析,研究人员对函数CA::Render::Server::ReceivedMessage::run_command_stream
使用以下命令设置条件断点:
conn_id
的值可以通过在POC代码的86行设置断点来实现。
在断点处,可以通过发送的围绕的Mach消息的缓冲数据。寄存器r13
指向伪造的Mach消息。
图2 CARenderServer接收的伪造的Mach消息
函数CA::Render::Decoder::decode_object(CA::Render::Decoder *this, CA::Render::Decoder *a2)
可以用来解码所有类型对象数据。缓存数据是从下图中的0x70000907dd52
处开始的。
图3. 有异常Image对象的伪造的Mach消息
下面的代码用来对函数CA::Render::Decoder::decode_object
中的Image对象进行分析。
图4. 处理Image对象数据的代码
下面分析Image对象被处理的过程。
下图是函数CA::Render::Image::decode()
的代码,研究人员在其中添加了部分注释。
图5.函数CA::Render::Image::decode()
可以看出offset0x70000907dd52
出的0x06
变成了0x86
,所以变量v4
就等于0x86
。然后程序会跳转到LABEL_31
来自行其他分支代码,因为变量v4
要比0x20
大。在LABEL_31
的最后,程序会继续调用函数CA::Render::Texture::decode(CA::Render::Texture *this, CA::Render::Decoder *a2)
来处理表示Texture对象的数据。
图6. 函数CA::Render::Texture::decode
研究人员发现它可以调用函数CA::Render::Decoder::decode_shape
来处理Shape
对象数据。
图7. 函数CA::Render::Decoder::decode_shape
可以看出变量v2
等于0x02
。然后分配缓存大小为8字节。最后,调用函数CA::Render::Decoder::decode_bytes
来解码数据的其他字节。该函数有3个参数,第二个指向malloc_zone_malloc
函数分配的缓冲区,第3个是类型size_t
,可以通过表达式4LL * v2 – 12
来进行计算,这会在结果等于0xfffffffffffffffc
时产生政府溢出。当调用函数bzero()
时,它的第一个参数指向一个更小的缓冲区,但是第二个参数是个超大的64位无符号整数,会导致内存破坏。
图8. 函数CA::Render::Decoder::decode_bytes
所以该漏洞是根源在于对函数CA::Render::Decoder::decode_shape
缺乏限制范围检查。
下面介绍下apple公司是如何修复该漏洞的:
图9. 漏洞修复前后比较
总结
该漏洞存在于函数CA::Render::Decoder::decode_shape()
处理shape对象时,漏洞主要原因是没有对输入进行验证。通过比较修复前后,可以看出该问题是通过改善输入验证来解决的。该漏洞影响macOS Mojave 10.14.2和macOS Mojave 10.14.3。