今年的Pwn2Own比赛刚刚结束,在Pwn2Own温哥华站的比赛中,Fluoroacetate团队所使用的一个Webkit漏洞成功吸引了我的注意。这个漏洞是一个价值五万五千美金的漏洞利用链的一部分,在这篇文章中,我将会对这个漏洞进行深入分析,并对漏洞进行验证和研究。
当然了,在开始深入分析之前,我们先把该漏洞的概念验证PoC提供给大家:
首先,我们需要对受该漏洞影响的WebKit版本进行编译,即Safari v12.0.3版本,根据苹果的版本发布信息,该版本对应的是修订版v240322。
svn checkout -r 240322 https://svn.webkit.org/repository/webkit/trunk webkit_ga_asan
我们可以使用AddressSanitizer(ASAN)来完成编译操作,它可以允许我们在发生内存崩溃的时候第一时间检测到错误信息。
ZDIs-Mac:webkit_ga_asan zdi$ Tools/Scripts/set-webkit-configuration --asan ZDIs-Mac:webkit_ga_asan zdi$ Tools/Scripts/build-webkit # --jsc-only can be used here which should be enough
我们将使用11db来进行调试,因为macOS本身就自带了这个工具。由于PoC中没有包含任何的呈现代码,因此我们需要在11db中使用JavaScriptCore(JSC)来执行它。为了在11db中执行jsc,我们需要调用它的二进制代码文件,而不是之前的脚本run-jsc。这个文件可以从 WebKitBuild/Release/jsc路径获取,并且需要正确设置环境变量。
env DYLD_FRAMEWORK_PATH=/Users/zdi/webkit_ga_asan/WebKitBuild/Release
我们可以在11db中运行这条命令,或者把它放在一个文本文件中,然后传递到11db -s中。
ZDIs-Mac:webkit_ga_asan zdi$ cat lldb_cmds.txt
env DYLD_FRAMEWORK_PATH=/Users/zdi/webkit_ga_asan/WebKitBuild/Releaser
好的,接下来,我们可以开始调试了:
我们可以看到,代码在0x6400042d1d29处发生了崩溃:mov qword ptr [rcx 8rsi], r8,经分析后我们确认为越界写入所导致的内存崩溃。栈追踪分析显示,它发生在虚拟机环境中,也就是编译过程或者JITed代码出了问题。我们还注意到的rsi索引,它包含了0x20000040,这个数字我们在PoC中是有见过的。