CVE-2019-8697:macOS磁盘管理漏洞分析

阅读量    86155 |   稿费 110

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

 

0x00 前言

不久以前,研究人员“ccpwd”通过ZDI漏洞计划提交了macOS磁盘管理守护程序(diskmanagementd)中的一个堆缓冲区溢出漏洞。diskmanagementd是负责驱动器管理及分区的一个服务,用户可以通过“Disk Utility”(磁盘工具)与该服务交互。该服务会运行一个Mach服务端,可以通过进程间通信(IPC)与之交互。客户端可以使用Mach IPC接口来发送及接收消息,通过这种RCP机制执行Mach服务端中的函数,这些函数通过MIG(Mach Interface Generator)生成(MIG是Apple的RPC代码生成工具)。

 

0x01 漏洞分析

该服务的所有通信流量最终都会流经launchd(这是macOS版的init),我们可以分析该服务对应的plist文件/System/Library/LaunchDaemons/com.apple.diskmanagementd.plist)来了解更多信息。

一开始该服务会分配一个回调函数,在发送和接收Mach消息的IPC操作期间会调用这个回调函数。

图1. 设置sub_10000C241回调函数

当在0x10000BE1F获得receive right(接收权限)后,CFMachPortCreateWithPort会将sub_10000C241设置为回调函数,以便处理在Mach端口上收到的信息。根据msgh_id(在Mach消息中发送的一个值,用来传递操作或者函数对应的ID)的具体值,sub_10000C241会间接使用该id作为两个远程函数dispatch表的索引。sub_100001DA2以及sub_100002005分别负责发起并拆分后续的通信会话。

图2. 设置端口权限

Mach端口采用单工(unidirectional)模式,这意味着每个发送/接收请求需要使用自己的端口。Apple有如下一段描述

端口(port)是客户端与服务端之间的一个单向通信信道,客户端请求服务,服务端提供服务。如果想向服务请求返回响应,那么就必须使用第二个端口。这种模式相当于UNIX中的(unidirectional)管道。

图3. 在off_1001AB6E0处将msgh_id作为dispatch表的索引使用

sub_10000CCA9中(sub_100001DA2会调用该函数),该函数会创建另一个Mach端口,设置sub_10000DACC回调函数,以Comms-F2TPort作为key保存到一个字典中。该函数会分配大小为0x1000字节的一个缓冲区,用来响应Mach消息,该缓冲区保存在Comms-F2T-replyarea key中。

图4. 分配响应缓冲区并创建Mach端口

随后,目标服务会调用setObject:forKey:,将键值对添加到字典中。

图5. 将端口及响应缓冲区以键值对形式加入字典

当客户端发送消息时,目标服务就会触发sub_10000DACC,然后根据msgh_id的值来访问对应的MIG远程过程调用。这里我们重点关注sub_1000087C9

图6. 通过mig_reply_setup设置回复缓冲区并调用RPC dispatcher

缓冲区溢出点位于sub_1000087C9函数中,其中用户输入会被添加到回复缓冲区中。经过一系列计算后,最终得出的长度值会超过0x1000偏移量。

图7. 长度值经过计算后会得到一个较大的偏移量

在图6中,0x1000大小的回复缓冲区位于r14中,而用户输入从0x38偏移处开始,因此用户输入有0xfc8的可用空间。当输入数据到达0xfc8时,strlen会返回相同的值。经过一系列运算后,最终的值为0xfcc [ ((0xfc8 + 1) + 3) & 0xfffffffc]。在0x100008ABD地址处,偏移量会变成0x1004 [0xfcc+0x38],这样就能泄露4字节并写入4字节,实现可靠的漏洞利用原语。泄露效果可能并不明显,因为缓冲区大小为0x1000字节,而写入地址位于0x1004处。这意味着我们可以从下一个块中读取4字节缓冲区。

这个漏洞利用起来有一些限制条件。输入必须不能包含NULL字符,不然会导致strlen在该位置停止计算。另一个限制是超出缓冲区末尾写入的数据将始终是var_DC的内容,而该变量为sub_100085B30返回的错误代码。

 

0x02 总结

对这类漏洞分析始终是非常有趣的一个过程,从中我们可以看到,即便一个非常小的错误也可能存在漏洞,最终导致能在目标系统上执行代码。Apple在macOS Mojave 10.14.5中修复了这个bug(以及其他bug),根据官方描述,Apple通过“改进内存处理机制”解决了这个问题。有趣的是,Apple在CVE公告中将这个漏洞拆分到Disk Management组件以及另一个概念模糊的“Security”组件中,而“Security”部分的漏洞已经在macOS Sierra 10.12.6和macOS High Sierra 10.13.6上被修复。不论如何,存在漏洞的代码被修复总是一件不错的结果。

分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多