2018年6月5日/ Patrick Biernat, Markus Gaasedelen, Nick Burnett
原文链接:http://blog.ret2.io/2018/06/05/pwn2own-2018-exploit-development/
Pwn2Own是趋势科技旗下的Zero Day Initiative每年组织的行业级安全竞赛。Pwn2Own邀请顶级安全研究人员展示对高价值软件(如最新版本的Web浏览器,操作系统和虚拟化解决方案)的0day 攻击。
今年第一次参加比赛,我们很有兴趣,我们选择了运行在 MAC OS的 Safari 浏览器作为攻击对象,因为我们此前并未尝试过这个平台上的这款软件。
为了这次比赛,我们发现并利用了Apple软件中之前两个未被披露的漏洞,以实现通过在Safari网页浏览器内点击一次就可以root身份实现远程代码执行。
来自ZDI的Joshua Smith正在评估我们在Pwn2Own 2018提交的0day
Pwn2Own 要求我们以一种非常公开的方式来评估这些高价值的目标,作为此次比赛的延伸,我们为此写了一系列博文,以详细介绍这些利用方法。
每篇文章都会对利用开发周期的关键点作坦诚的介绍。
1. 概述,目标选择,发现的漏洞
2. JSC Fuzzer 和根源分析
3. 将JSC漏洞用于RCE攻击
4. 评估Safari沙盒,对 WindiowsServer进行Fuzz
5. 实现Safari沙盒逃逸
入口点:Safari
web浏览器是人们探索外部网络的窗口,随着人们对网络需求的增加,浏览器为了保持相关性变得越来越复杂。软件出现漏洞不可避免,一些bug甚至会引发严重的安全问题。
现在的浏览器中,DOM和JavaScript引擎是黑客攻击的主要目标,研究几个最近的浏览器漏洞,发现确实如此。案列:(1,2,3,4,5, …)
其中以Safari浏览器中的JS引擎:JavaScriptCore,最引入入胜:
Safari网页浏览器是对一款开源浏览器引擎:WebKit的一个包装
JavaScriptCore(JSC)让人着迷的地方在于JS脚本可以在引擎的执行环境中执行复杂的操作,JS允许浏览器终端用户在上下文中高效地执行任意计算。通常,JS会将动态的客户端行为添加到静态的HTML网页中。
这种模式让今天的浏览器厂商很难在回退到我们知道和使用的网页之外进行限制。作为攻击者,我们的目标就是打破这种执行环境的限制。
JSC:漏洞挖掘和利用
就Pwn2Own而言,我们感兴趣的是那些可以快速被发现的bug,它们的生命周期也更短。参考了一些开源项目后,我们构建了一个分布式的fuzzing,它以覆盖率为导向,并基于JS语法。
经过大约两周的fuzzing,评估覆盖率,改进JS语法以及排除一些不太有用的crash外,我们的fuzzer生成了一个有着相当有趣的栈回溯的测试用例:
你的栈回溯里面有WTFCrashWithSecurityImplication(...)说明可能会有好事发生
对一个最简测试用例进行根源分析后,我们发现 array.reverse()和 Riptide 之间存在竞态条件,而Riptide是JSC新的并发垃圾回收器。
在合理场景下,对array.reverse()进行适时的调用将生成一个JSArray,其中包含了分散在各处的已释放对象。在这个条件竞争中的稳定胜出为我们带来了一个独特而强大的原语:任意JS对象的UAF。
这个漏洞后来被Apple 修复为CVE-2018-4192:
我们在Pwn2Own 2018上利用的JSC静态条件漏洞的CVE细节
在本系列的第2部分中,我们将详细介绍如何构建一个JS fuzzer,并以此作为漏洞挖掘的一种方法,并描述我们对记录重放调试技术的使用以分析这个棘手的竞态条件漏洞的根源。
第3部分将提供我们构建的,去持续赢取这一数据竞态的PoC,以及我们如何利用这个bug在Safari上下文中实现远程代码执行(RCE)。
沙盒逃逸:WindowServer
为了更好地保护用户,主流浏览器使用了沙盒技术将自己和系统的其他部将那些隔离,在软件发生安全问题时,沙盒技术可以减小攻击对系统的影响。
回顾Safari沙盒的研究就不难让人注意到macOS的WindowServer。WindowServer是一个用户空间系统服务,负责绘制和管理macOS的各种图形组件。
可以看到‘ps aux’中输出的WindowServer
基本来说,WindowSever用来处理来自运行在系统上的应用程序的mach_message。在WindowSever上大约有600个终端作为处理例程负责处理这些消息。这些处理例程突出显示了可以从沙盒内部实现权限提升的攻击面。
WindowServer的一部分mach消息处理例程
WindowSever看起来是一个理想的攻击目标:以root权限运行,存在于用户空间(容易调试/评估),有大量攻击面,还有许多历史攻击案例(1, 2, 3, …).
WindowServer:漏洞挖掘和利用
WindowServer是一个未文档化的私有框架。它不可以直接交互,而是由各种高级的公共图形库包装而来。出于测试600个未文档化的处理例程的时间限制,我们写了一个in-process fuzzer。
在WindowServer内,我们已经识别了三个不同的派遣例程,在将传入的mach_message传递到它们的显式处理程序函数之前,它们必须经过这些派遣例程。
我们在一个in-process fuzzer内拦截的三个端点中的一个
在Frida的帮助下,我们控制了这些派遣例程,以便可以检查,记录,位翻转和重放被传递到WindowServer的消息。普通应用程序生成的位翻转消息使我们在对底层子系统只有粗浅的了解下也可以快速评估(例如,fuzz)大范围的攻击面。
我们在为Pwn2Own购买的MacBook上运行fuzzer还不到24小时,就产生了一个越界读取崩溃。更重要的是,这个错误的调用堆栈只是来自WindowServer端点处的一个调用。找到这样的一个“浅”的运行错误是有利的,因为它暗示这个错误相对容易触发和控制。
重放我们录制的位图快照,我们可以稳定地重现并找到问题的根源:
WindowServer中的签名比较漏洞
崩溃可归因于经典签名比较问题。
函数_CGXRegisterForKey(…)接受一个可被控制的数组索引,它期望的是一个从0到6的整数。但是,这个检查是作为一个签名操作实现的。传入一个负索引(如-10000)将绕过这个检查并将数组索引到边界之外。
这个漏洞被修复为CVE-2018-4193:
我们在Pwn2Own 2018上利用的WindowServer签名比较漏洞的CVE细节
有趣的是,我们竞争对手Richard Zhu也遇到了这个问题。最终,在比赛的三次尝试中,Richard 和我们都未能独立地解决这一问题。特定的限制条件和一些非常不幸的巧合使这个漏洞相当难以利用。
在本系列的第五篇也是最后一篇文章中,我们将讨论CVE-2018-4193漏洞的复杂性,以及通过这个漏洞来完成一次沙盒逃逸的代码的复杂度。
总结
Pwn2Own是为数不多的几个能让公众窥见零日漏洞开发这一神秘过程的赛事之一。在这一系列的博文中,我们将揭开这一神秘过程的面纱,以从昂贵的错误和纯粹的奉献精神中学到教训。
下周,我们将展开我们的JSC fuzzing成果,并利用高级调试技术和技巧展示对一个复杂的竞态条件漏洞根源进行分析的过程。
本文由看雪翻译小组 cherrir 编译,感谢小伙伴@ 银雁冰 的校对
来源:http://blog.ret2.io/2018/06/05/pwn2own-2018-exploit-development/
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2018-6-13 08:22
被cherrir编辑
,原因: