首页
论坛
课程
招聘

Chromium issue 1196683、1195777分析

2021-04-21 17:52

2021年4月12日,开源浏览器内核Chromium的一处改动提交引起了关注。这是Chromium Javascript引擎v8的一处漏洞bugfix。同时针对该bugfix的回归测试样本regress-1196683.js也被提交。基于该回归测试,有安全研究员公布了完整的利用代码。由于Chromium开发流程,该漏洞于4月13日Chrome的release版中才被修复。无独有偶,4月15日Chromium代码仓库另一处改动提交也包含了回归测试样本regress-1195777.js。基于该样本,完整的利用代码再次被公布。由于最新的Chrome release版没有引入该bugfix,利用代码仍可以在最新的Chrome浏览器的渲染进程稳定利用。当受影响版本的Chormium内核浏览器在没有开启沙箱的情况下(--no-sandbox),访问攻击者构造的恶意链接时,将会触发该漏洞,造成远程代码执行。


 

1. Issue 1196683原理分析


该issue的bugfix代码如下:

 

 

bugfix修复了v8 TurboFan在指令选择阶段针对ChangeInt32ToInt64节点的指令选择错误问题。改动前根据ChangeInt32ToInt64节点的输入节点类型选择指令。如果输入节点类型为有符号整数,则选择指令X64Movsxlq先做符号扩展,否则选择X64Movl做零扩展。Bugfix后则无论输入类型,一律选择X64Movsxlq做符号扩展。根据修复代码可以猜测,这里应该是ChangeInt32ToInt64节点输入类型为无符号整数,导致指令选择阶段错误选择X64Movl指令引发的安全问题。

 

首先通过regress-1196683.js分析漏洞根因:

 

 

触发JIT的foo函数只有一行代码,重点关注 (arr[0] ^ 0) + 1在TurboFan中关键阶段的优化过程:


1) TyperPhase

 

异或操作符对应32节点,其两个输入分别为常量0(24节点)和arr[0](80节点)。

 

2) SimplifiedLoweringPhase

 

32节点SpeculativeNumberBitwiseXor被优化成Word32Xor,并加入后继节点ChangeInt32ToInt64。此时ChangeInt32ToInt64节点的输入节点Word32Xor类型为Signed32

 

3) EarlyOptimizationPhase

 

可以看到原32节点被删除,并用80节点替代作为110节点ChangeInt32ToInt64的输入。此时ChangeInt32ToInt64节点的输入节点LoadTypedElement类型为Unsigned32


这段逻辑对应的v8代码如下:

 

如上所示,对于x ^ 0 => x的情况,使用左节点替换当前节点,从而引入了错误的数据类型。

 

4) InstructionSelectionPhase


根据前面的分析,指令选择阶段,ChangeInt32ToInt64节点的输入节点LoadTypedElement类型为Unsigned32,最终选择X64Movl指令替换ChangeInt32ToInt64节点:

 

 

因为错误选择了零扩展指令X64Movl,导致(arr[0] ^ 0)返回错误的值:0x0000000080000000


最终利用该漏洞,通过如下代码可以得到一个JIT中非预期值为1的变量x(预期值应为0):

 

 


2. Issue 1195777原理分析


该issue的bugfix代码如下:

 

 

bugfix修复了v8 TurboFan在SimplifiedLowering阶段,对64位整数转为32位整数的数据类型转换节点生成错误的问题。改动前对于当前节点的输出类型为Signed32Unsigned32均生成TruncateInt64ToInt32节点(截断);改动后,对于当前节点的输出类型为Unsigned32的情况,还需要检查use_info的类型,只有在use_info.type_check() == TypeCheckKind::kNone的情况下,才会生成TruncateInt64ToInt32节点。

 

首先通过regress- 1195777.js分析漏洞根因:


 

 

触发JIT的foo函数中关键代码为return -1 < Math.max(0, x, -1)。重点关注 Math.max(0, x, -1)在TurboFan中关键阶段的优化过程:


1) TyperPhase

 

Math.max(0, x, -1)对应了56,58节点,58节点输出作为41节点SpeculativeNumberLessThan<)的输入。

 

2) TypedLoweringPhase

 

Math.max(0, x, -1)两个常量参数0,-1(54,55节点)被替换成了常量节点32和14

 

3) SimplifiedLoweringPhase

 

原56,58的NumberMax节点,被Int64LessThan + Select节点替换;原41节点SpeculativeNumberLessThan被替换为Int32LessThan。在处理SpeculativeNumberLessThan输入节点的时候,因为输入节点(Select)的输出类型为Unsigned32,从而触发漏洞,导致76节点TruncateInt64ToInt32被错误生成。从而将Math.max(0, x, -1)的结果截断为Signed32。因此,当Math.max(0, x, -1)中的x为Unsigned32时,会被TruncateInt64ToInt32错误截断为Signed32

 

最终利用该漏洞,通过如下代码可以得到一个JIT中非预期值为1的变量x(预期值应为0):


 


 

3. 漏洞利用分析


根据上面对这两个漏洞的分析可以知道:这两个漏洞是TurboFan在做整型数据类型转换(扩展、截断)时发生的错误。利用这两个漏洞,通过如下代码可以得到一个JIT中非预期值为1的变量x。接下来根据在野利用样本,分析如何根据这个错误数值为1的变量x,实现远程代码执行。


具体利用步骤为:

1)借助这个错误数值为1的变量x,构造一个长度为1的Array;

2)通过Array.prototype.shift()获得一个长度为0xFFFFFFFF的越界数组;

关键代码如下:

 

其中var arr = new Array(x);对应的JIT代码:

 

这里rdi为数组的长度,即x的值1。指针压缩后,左移一位(rdi+rdi),存放在JSArray.length属性(+0xC)。

 

arr.shift();对应的JIT代码:

 

 

这里可以看到,arr.shift()后,数组的长度直接由常量0xFFFFFFFE赋值,其优化过程:


(1)TyperPhase

 

这里数组长度赋值操作主要由152,153节点组成。其中152节点做Array.length-1计算操作。153节点将计算结果保存在Array.length(+0xC)处。


2LoadEliminationPhase

 

这里可以看到,由于在Ignition执行过程中收集的x值为0,这里做了常量折叠(0-1=-1),从而得到常量0xFFFFFFFF。左移一位后为0xFFFFFFFE,存放在Array.length(+0xC)处。从而得到一个长度为0xFFFFFFFF的越界数组。


得到越界数组后,后面的利用方法就比较通用了,一般为:


3)借助这个越界数组,实现addrof/fakeobj


4)借助addrof/fakeobj,伪造一个JSArray,实现任意地址读写;


样本中利用arr和cor实现任意地址读写的内存布局为:

 

(1)首先利用漏洞获得一个长度为0xFFFFFFFF的arr(红框)

2)利用越界的arr和cor实现addrof/fakeobj(绿框)

(3)利用越界的arr修改cor的长度(黄框)

(4)利用越界的cor,泄露cor的map和properties属性(蓝框),构造一个fake JSArray,借助这个fake JSArray实现任意地址读写

 

5)借助WebAssembly执行shellcode


最后借助WebAssembly创建一个RWX属性的内存页,拷贝shellcode至该内存页,执行shellcode


完整的利用演示:

 

 


4. 结论


经分析,这两个v8 JIT的漏洞触发容易且利用简单,在没有开启沙箱的Chromium内核浏览器中可以稳定利用。考虑到这两个漏洞只是Chromium内核浏览器渲染进程的远程代码执行漏洞,无法穿透浏览器沙箱(默认开启),建议用户不要关闭Chromium内核浏览器的沙箱,且不要点击不明链接。

 


5. 参考链接


[1] https://chromium-review.googlesource.com/c/v8/v8/+/2820971

[2] https://chromereleases.googleblog.com/2021/04/stable-channel-update-for-desktop.html

[3] https://chromium-review.googlesource.com/c/v8/v8/+/2826114

[4] https://github.com/r4j0x00/exploits/blob/master/chrome-0day/exploit.js

[5] https://github.com/avboy1337/1195777-chrome0day/blob/main/1195777.html


 

6. 团队简介


深信服南研安全研究团队专注于APT攻击,在野漏洞利用追踪、研究检测,攻防对抗等方向的研究工作。团队成员曾在Windows,MacOS/iOS,Linux/Android等主流操作系统中发现了上百个安全漏洞,在BlackHat USA、BlackHat Europe、BlackHat Asia、HITB、Microsoft BlueHat、CodeBlue、HITCON、Virus Bulletin、Pacsec、看雪SDC、Freebuf CIS等国内外知名安全会议上发表过演讲和论文。

 

如果你对以下技术内容感兴趣,希望和高手切磋共事,赶紧发简历过来吧(邮箱caolei@sangfor.com.cn 工作地点:南京):

[APT攻击溯源] 恶意代码分析,威胁情报研究APT溯源分析

[检测引擎研发] EDR、XDR等检测引擎研发

[攻防对抗技术] 红蓝对抗,ATT&CK技术研究,检测规则编写

[漏洞挖掘与利用] 在野漏洞利用研究,漏洞挖掘

[云原生安全] 云原生安全技术研究和产品研发

[MacOS安全] macOS安全产品核心模块开发,macOS沙箱、EDP、EDR、DLP等安全产品开发

[大数据安全] 研发基于大数据技术的下一代安全产品



漏洞分析 漏洞 系统底层
声明:该文观点仅代表作者本人,转载请注明来自看雪专栏
最新评论 (0)
登录后即可评论