ZDI年度五大漏洞第四弹——让指针指向你想要的对象
字数 1399 2025-08-29 08:31:35

macOS Dock 服务未初始化指针漏洞分析 (ZDI-18-781/CVE-2018-4196)

漏洞概述

本漏洞是2018年Pwn2Own大赛中MWR实验室攻破苹果Safari浏览器的沙箱逃逸漏洞,编号为ZDI-18-781/CVE-2018-4196。该漏洞存在于macOS Dock服务中,涉及未初始化指针的使用,最终导致任意代码执行。

漏洞背景

  • 漏洞类型:未初始化指针漏洞
  • 影响组件:macOS Dock服务
  • 利用场景:Safari浏览器沙箱逃逸
  • 发现者:MWR实验室
  • 相关CVE:CVE-2018-4196
  • 漏洞价值:Pwn2Own大赛获胜漏洞

技术细节

1. 攻击面分析

macOS中的Dock服务通过Mach服务"com.apple.dock.server"提供接口,这些函数大量使用HIServices框架提供的序列化功能。

2. 漏洞触发点

漏洞在DSSetDesktopForDisplayAndSpace函数中触发,当发送ID为96548的Mach消息时:

; 函数开始部分
; 在调用_UnserializeCFType之前,堆栈上已经初始化了一些变量

3. 关键函数分析

_UnserializeCFType函数

该函数存在于HIServices框架中,其伪代码如下:

if (第四个参数 >= 8) {
    初始化第五个参数为NULL;
    尝试基于数据类型进行反序列化;
    if (反序列化成功) {
        将新创建对象的指针存储在第五个参数中;
    }
}

DSSetDesktopForDisplayAndSpace函数

该函数的关键问题在于:

  1. 传递给UnserializeCFType函数的栈上变量未被初始化
  2. 只有当UnserializeCFType的第二个参数≥8时,才会初始化指针
  3. 随后对该栈变量调用objc_autorelease函数

4. 漏洞原理

漏洞的根本原因是:

  • 未初始化的栈变量被直接传递给objc_autorelease
  • 攻击者可以控制栈上的内容,从而控制被释放的指针
  • 通过精心构造的Mach消息,可以控制代码执行流程

5. 利用技术

MWR团队通过以下方式利用该漏洞:

  1. 使用包含push rbx指令的函数进行利用
  2. 该指令与未初始化栈变量的偏移量对齐
  3. 执行时,rbx寄存器指向Mach消息中的40个字节
  4. 控制objc_autorelease最终操作的指针对象

6. 相关函数

共有8个函数包含类似的易受攻击代码逻辑:

  • 未初始化第4个参数
  • 或未检查返回值的情况下调用_UnserializeCFType函数

正确的实现应:

  1. 检查_UnserializeCFType函数的返回值
  2. 确保函数执行成功
  3. 将作为参数传递的堆栈变量初始化为NULL

历史相关漏洞

  1. ZDI-16-282 (2016年)

    • 发现者:lokihardt
    • 影响:Microsoft Edge浏览器
    • 利用链:处理'Array.concat'函数时的未初始化堆栈变量
  2. ZDI-17-237 (2017年)

    • 发现者:360安全团队
    • 影响:VMware Workstation
    • 效果:客户机逃逸到宿主机操作系统

漏洞防护建议

  1. 对所有指针变量进行初始化
  2. 严格检查函数返回值
  3. 对Mach消息进行严格的边界检查
  4. 使用安全的序列化/反序列化实践
  5. 启用现代编译器的安全特性(如自动初始化)

总结

该漏洞展示了未初始化指针在macOS系统服务中的危险性,特别是在Mach服务交互场景下。通过精心构造的Mach消息,攻击者可以控制程序执行流程,最终实现沙箱逃逸。这类漏洞在Pwn2Own等高级攻击场景中经常出现,需要开发者特别注意内存安全编程实践。

macOS Dock 服务未初始化指针漏洞分析 (ZDI-18-781/CVE-2018-4196) 漏洞概述 本漏洞是2018年Pwn2Own大赛中MWR实验室攻破苹果Safari浏览器的沙箱逃逸漏洞,编号为ZDI-18-781/CVE-2018-4196。该漏洞存在于macOS Dock服务中,涉及未初始化指针的使用,最终导致任意代码执行。 漏洞背景 漏洞类型:未初始化指针漏洞 影响组件:macOS Dock服务 利用场景:Safari浏览器沙箱逃逸 发现者:MWR实验室 相关CVE:CVE-2018-4196 漏洞价值:Pwn2Own大赛获胜漏洞 技术细节 1. 攻击面分析 macOS中的Dock服务通过Mach服务"com.apple.dock.server"提供接口,这些函数大量使用HIServices框架提供的序列化功能。 2. 漏洞触发点 漏洞在 DSSetDesktopForDisplayAndSpace 函数中触发,当发送ID为96548的Mach消息时: 3. 关键函数分析 _ UnserializeCFType函数 该函数存在于HIServices框架中,其伪代码如下: DSSetDesktopForDisplayAndSpace函数 该函数的关键问题在于: 传递给 UnserializeCFType 函数的栈上变量未被初始化 只有当 UnserializeCFType 的第二个参数≥8时,才会初始化指针 随后对该栈变量调用 objc_autorelease 函数 4. 漏洞原理 漏洞的根本原因是: 未初始化的栈变量被直接传递给 objc_autorelease 攻击者可以控制栈上的内容,从而控制被释放的指针 通过精心构造的Mach消息,可以控制代码执行流程 5. 利用技术 MWR团队通过以下方式利用该漏洞: 使用包含 push rbx 指令的函数进行利用 该指令与未初始化栈变量的偏移量对齐 执行时, rbx 寄存器指向Mach消息中的40个字节 控制 objc_autorelease 最终操作的指针对象 6. 相关函数 共有8个函数包含类似的易受攻击代码逻辑: 未初始化第4个参数 或未检查返回值的情况下调用 _UnserializeCFType 函数 正确的实现应: 检查 _UnserializeCFType 函数的返回值 确保函数执行成功 将作为参数传递的堆栈变量初始化为NULL 历史相关漏洞 ZDI-16-282 (2016年) 发现者:lokihardt 影响:Microsoft Edge浏览器 利用链:处理'Array.concat'函数时的未初始化堆栈变量 ZDI-17-237 (2017年) 发现者:360安全团队 影响:VMware Workstation 效果:客户机逃逸到宿主机操作系统 漏洞防护建议 对所有指针变量进行初始化 严格检查函数返回值 对Mach消息进行严格的边界检查 使用安全的序列化/反序列化实践 启用现代编译器的安全特性(如自动初始化) 总结 该漏洞展示了未初始化指针在macOS系统服务中的危险性,特别是在Mach服务交互场景下。通过精心构造的Mach消息,攻击者可以控制程序执行流程,最终实现沙箱逃逸。这类漏洞在Pwn2Own等高级攻击场景中经常出现,需要开发者特别注意内存安全编程实践。