在今年Pwn2Own中,有研究人员发现利用一个越界读漏洞竟然实现了Safari沙箱逃逸,然后利用kextutil中存在的TOCTOU获得内核代码执行权限。
目前该漏洞已经被命名为CVE-2019-8603,简单来说,这是一个存在于Dock和苹果卸载网站(com.apple.uninstalld)中的堆越界读取漏洞,该漏洞将导致攻击者调用CFRelease并在macOS上实现Safari浏览器沙盒逃逸,最终获取到目标设备的root权限。
另外,在测试过程中,CVE-2019-8606允许研究者通过kextutil中的竞态条件(race condition),用root权限实现内核代码执行。如果再借助一个qwertyoruiopz和bkth开发的WebKit引擎漏洞(远程代码执行漏洞),则研究人员可以完全实现Safari沙箱逃逸。
在本文发布时,该漏洞已经在最新的macOS 10.14.5版本中被修复了,所以本文我们可以对它的来龙去脉进行详细复盘了。
详细复盘
本来研究人员是计划测试一个模糊测试工具的代码覆盖率,代码覆盖(Code coverage)是软件测试中的一种度量,描述程式中源代码被测试的比例和程度,所得比例称为代码覆盖率。但测试到AXUnserializeCFType函数时,却发现发现了CVE-2019-8603漏洞,这个函数是去年的Pwn2Own中发现的一个简单解析器,不过当时并没有发现其中有什么漏洞。不过在发现有漏洞后,研究人员对这个函数进行了仔细研究,发现它竟然是CoreFoundation对象序列化的另一种实现方式。Core Foundation框架(CoreFoundation.framework)是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能。而AXUnserializeCFType则是HIServices框架的一部分,而且代码就存储在对应的dylib库中。PHP大马
可以通过此函数对CFAttributedString对象进行反序列化,CFAttributedString是一个字符串,其中每个字符与CFDictionary相关联,CFDictionary包含了描述给定字符的任意属性。这些属性可以是颜色,字体或用户关心的任何其他内容。而在本文的示例中,CFDictionary的属性是代码执行。
为了帮助大家更直观地了解CFDictionary的属性,研究人员专门列出了数据结构,数据结构使用游程长度(run-length)压缩,而不是为每个单独的字符专门分配字典:
// from CFAttributedString.c struct __CFAttributedString { CFRuntimeBase base; CFStringRef string; CFRunArrayRef attributeArray; // <- CFRunArray of CFDictinaryRef's }; // from CFRunArray.c typedef struct { CFIndex length; CFTypeRef obj; } CFRunArrayItem; typedef struct _CFRunArrayGuts { /* Variable sized block. */ CFIndex numRefs; /* For "copy on write" behavior */