启明星辰ADLab:Chrome 任意代码执行漏洞分析

发布时间 2021-04-16

4月13日,国外安全研究人员在社交媒体上发布了Chrome 的0Day 漏洞(参见参考链接[1]),漏洞编号为CVE-2021-21220,并在github上公开了该漏洞的POC以及利用代码,相关的利用代码在关闭沙盒的情况下可达到远程代码执行。由于chromium 相关框架的广泛应用,该漏洞在其他浏览器或脚本引擎中仍有存在的可能。该漏洞在chrome 90.0.4430.72版本已经修复,提醒广大用户及时更新到最新版本(参见参考链接[2]),以规避该漏洞存在的攻击风险。


启明星辰ADLab分析发现,该漏洞存在于Chrome 的JavaScript 解析引擎V8中,POC主要代码如下:


1.png


在POC line4执行异或操作,(2**31)^0=-2147483648。根据ECMA标准(参见参考链接[3]),异或的结果是32位整数:


2.png


在v8 SimplifiedLowering阶段,增加了对异或的结果执行ChangeInt32ToInt64的操作:


3.png


SimplifiedLowering 执行后,异或的类型被标记为Word32:


4.png


在MachineOperatorOptimizer阶段,由于是和0做异或,所以用左操作数代替异或操作。


5.png


此时的结构图如下,可以看出异或的结果是Word32|TypeUint32:


6.png


在指令选择时,对于VisitChangeInt32ToInt64操作,根据其输入类型选择操作码:


7.png


所以,这里的操作码是kX64Movl操作码,该指令在将源操作数移至目的位置时并不做符号扩展,这样在POCline4中x的值为2147483649,于是在poc line12的位置,编译器其实使用的是x=1的值作为创建数组的长度。这是编译器未曾预料到的情况。


在变量的范围分析中,编译器认为创建的数组长度是0:


8.png


 在执行POP时,会先判断数组的长度是否为0,如果不是就会将其长度减1:


9.png


由于数组长度固定,编译器在LoadElimination 的过程中会进行常量折叠,在代码路径走到这里的时候通过StoreField操作将数组的长度直接赋值为-1:


10.png

11.png


由于是smi,所以是0xfffffffe:


12.png


打印数组长度:


13.png

这时超长的数组就出炉了,任由你玩了。从补丁对比上来看(参见参考链接[4]),对于ChangeInt32ToInt64将其输入作为有符号对待,这样就避免了该漏洞通过该路径触发。


14.png


关于利用的部分,基本是老套路,这里就不再赘述。


参考链接:

[1]https://twitter.com/r4j0x00/status/1381643526010597380

[2]https://www.google.com/chrome/

[3]https://www.ecma-international.org/publications-and-standards/standards/ecma-262/

[4]https://chromium-review.googlesource.com/c/v8/v8/+/2820971/3/src/compiler/backend/x64/instruction-selector-x64.cc#1379


启明星辰积极防御实验室(ADLab)


ADLab成立于1999年,是中国安全行业最早成立的攻防技术研究实验室之一,微软MAPP计划核心成员,“黑雀攻击”概念首推者。截止目前,ADLab已通过CVE累计发布安全漏洞近1100个,通过 CNVD/CNNVD累计发布安全漏洞1000余个,持续保持国际网络安全领域一流水准。实验室研究方向涵盖操作系统与应用系统安全研究、智能终端安全研究、物联网智能设备安全研究、Web安全研究、工控系统安全研究、云安全研究。研究成果应用于产品核心技术研究、国家重点科技项目攻关、专业安全服务等。


adlab.jpg