从漏洞利用角度介绍Chrome的V8安全研究

来源:岁月联盟 编辑:猪蛋儿 时间:2020-04-14

红色:这是在JavaScript级别执行的基本JavaScript代码或动作。例如JSEqual,JSToBoolean等。

绿色:机器级别的语言。在此处可以找到V8 Turbolizer上机器级别语言的操作和标识符示例。
请注意,这些描述可能并不完全准确,因为所有文档都是以下链接并在查找V8的源代码:
· TurboFan TechTalk
· turbofan简介
0x05  优化  Turbofan
如上所述,Turbofan进行了几次优化,并且可以通过类型混淆漏洞来利用许多优化阶段,如果检查Turbolizer,看到大约有20个阶段:

TurboFan阶段
利用过程不在本博客的讨论范围之内,大概的利用方法是通过使用/破坏DataView对象或堆来创建任意的读/写原语,堆喷后使用越界读/写来攻击受害对象,以破坏对象内的指针(该模式始终破坏一组对象属性以具有上述读/写原语)。
0x06  调试分析
由于已经在调试模式下编译了v8,因此本节将首先在Turbolizer上分析要查找的最常见节点之一,然后进行一些调试。要记住的一件事是,我们需要在d8二进制文件所在的位置运行gdb ,以便正确加载源代码,而不必dir在gdb中运行命令。
如之前在有关利用的笔记中所述,方法之一是越界读/写,因此,我们将继续一个JavaScript示例,该示例禁用越界数组访问检查。如果想深入了解更多细节,这篇文章将介绍Turbofan,它比此处更详细地介绍了禁用此类检查和V8漏洞利用代码,但是这有点过时了,代码更改如下:
 let arr = [1.1, 2.2, 3.3];
 
 function nochecks(pos){
     let mod = 2;
     var access = arr[pos] % mod;
     return access;
 }
 
 nochecks(10);
 for (let i = 0; i
我们可以看到有一个nochecks将pos变量作为参数的函数。之后,pos计算模2 并用于访问arr数组中的位置,阻止大于1的数字。由此,直到实施最新的V8强化之前,要寻找的常见事情之一就是查看是否优化程序已删除边界检查。对于此任务,有两件事帮助我完成了分析。
一是以下trace``d8标志:

一个非常有价值的flag是--trace-turbo-reduction,它将给我们在与精简代码相关的每个优化阶段对代码进行的所有精简的详细trace。从漏洞利用代码开发角度来看,减少编译器时间将是利用优化的重点。
因此,如果我们使用以下命令运行先前的JavaScript代码段:
 ./v8/out/x64.debug/d8 --trace-turbo-reduction --trace-turbo javascript_tests/nochecks.js
我们将获得上述优化跟踪,并且因为此后将使用Turbolizer,所以该--trace-turbo标志将帮助我们生成一个.json文件,以后可以将其馈送到Turbolizer中进行分析。如我们所见和期望的那样,优化器发现我们正在访问数组,因此插入了CheckBound节点:
 ./v8/out/x64.debug/d8 --trace-turbo-reduction --trace-turbo javascript_tests/nochecks.js | grep -i bound

在不同的优化阶段插入的CheckBound和CheckedUint64Bounds节点
然后可以在Turbolizer中观察此数据,这将有助于分析行为,具体取决于生成的节点的数量。例如,让我们观察Turbolizer上CheckBounds该LoadElimination阶段内的节点。为此,我们打开生成的turbo-nochecks-0.json文件,然后选择适当的优化阶段:

在Turbolizer中检查CheckBounds节点
这样,我们可以通过检查优化器中哪些其他组件正在与CheckBounds节点交互来继续进行分析。
如前所述,我们将通过一个简单的调试会话来完成本节和文章,以说明在CheckBounds的情况下v8实现的安全强化。为此,在源代码中VisitCheckBounds在simplified-lowering.cc文件中查找该函数并将断点放在第一if行(d8在断点之前运行一次,否则将不起作用):

断点打在第一if的VisitCheckBounds函数
如果继续调试,我们将看到优化器访问该节点,但是什么也不做。我们对此没有兴趣,因为没有完成降级操作,要进入降级阶段,请输入c调试器,然后输入p lower()。如果Turbofan正在降级阶段,则该lower函数返回true。因此,当我们看到命令返回0x1时,就不继续调试并逐行查看发生了什么。在以前的代码版本中,我们希望调用一个函数,DeferReplacement该函数将消除边界检查。

上一页  [1] [2] [3]  下一页