2021最近Chorme漏洞(推特Chrome 0.5day漏洞分析)

0x01 前言

北京时间4月13日凌晨,安全研究人员Rajvardhan Agarwal在推特上发布了一个可远程代码执行(RCE)的0Day漏洞,该漏洞可在当前版本的谷歌Chrome浏览器和微软Edge上运行。

ae99eff927f592ea0fb6cfa2fd6f3535.jpg
Agarwal发布的漏洞,是基于Chromium内核的浏览器中V8 JavaScript引擎的远程代码执行漏洞,同时还发布了该漏洞的PoC(概念验证)。

当Chrome或Edge浏览器加载PoC HTML文件及其对应的JavaScript文件时,该漏洞可被利用来启动Windows计算器(calc.exe)程序。

该漏洞是一个已经公开披露的安全漏洞,但在当前的浏览器版本中还没有修补。Agarwal表示,在最新版本的V8 JavaScript引擎中该漏洞已经被修复,但目前还不清楚谷歌何时会更新Chrome浏览器。

好消息是,Chrome浏览器沙盒可以拦截该漏洞。但如果该漏洞与另一个漏洞进行链锁,就有可能躲过Chrome沙盒的检测。

Chrome浏览器的沙盒是一道安全防线,可以防止远程代码执行漏洞在主机上启动程序。

0x02 POC

<html>
    <script>
        function log(str){
            document.write("<p>" + str + "</p>");
        }
        print = console.log;
        const arr = new Uint32Array([2**31]);
        function foo() {
            return (arr[0] ^ 0) + 1;
        }
        log(foo());//-2147483647
        for(let i=0;i<10000;i++){
            print(foo());
        }
        log(foo());//2147483649
    </script>
</html>

60241fe3482f04abb8033af46c5c03eb.jpg

如出现不一致,则代表存在漏洞。

  • 用于漏洞调试
  const arr = new Uint32Array([2**31]);
  function foo() {
    return (arr[0] ^ 0) + 1;
  }
  %PrepareFunctionForOptimization(foo);
  print(foo());
  %OptimizeFunctionOnNextCall(foo);
  print(foo());
  • root cause runtime执行

arr[0]是unsigned int32 = 2**31 = 2147483648 = 0x8000 0000
->
arr[0] ^ 0会转成signed int32 = 2**31^0 = 0x8000 0000 = -2147483648
->
(arr[0] ^ 0) + 1会转成signed int64,按理说是先符号拓展,得到0xFFFF FFFF 8000 0000,然后再加一,得到0xFFFF FFFF 8000 0001 = -2147483647

  • JIT compiler
    3aa9fb65e45090dd9a48129b67d732bc.jpg

3959b5b4f7c92e03da6f8f41d9769fcc.jpg
如图可以看出我们之前的分析是合理的。
但因为JIT的x64指令选择存在问题,所以在为ChangeInt32ToInt64 IR生成汇编时会对0x8000 0000进行零拓展,得到0x0000 0000 8000 0000,然后再加一,得到0x0000 0000 8000 0001 = 2147483649
看一下这个问题是什么

       case MachineRepresentation::kWord32:
-        opcode = load_rep.IsSigned() ? kX64Movsxlq : kX64Movl;
+        // ChangeInt32ToInt64 must interpret its input as a _signed_ 32-bit
+        // integer, so here we must sign-extend the loaded value in any case.
+        opcode = kX64Movsxlq;

从补丁可以看出,存在漏洞的逻辑是根据load_rep.IsSigned()来选择opcode是kX64Movsxlq还是kX64Movl指令,前者是符号拓展,后者是零拓展。
而load_rep其实是来自于图上的LoadTypedElement节点,而这个节点的符号是Unsigned32的,所以会选择kX64Movl指令,最终导致(arr[0] ^ 0) + 1计算出的结果出错。

exploit

该漏洞利用的依然是根据类型推断的值,和实际执行的值的误差来完成漏洞利用的。chrome对于typer漏洞做了大量的加固,但仍有绕过,本篇仅分析漏洞,关于漏洞利用请移步阅读。
https://github.com/r4j0x00/exploits/tree/master/chrome-0day
https://faraz.faith/2021-01-07-cve-2020-16040-analysis/
https://doar-e.github.io/blog/2020/11/17/modern-attacks-on-the-chrome-browser-optimizations-and-deoptimizations/
https://doar-e.github.io/blog/2019/05/09/circumventing-chromes-hardening-of-typer-bugs/

本文经授权后发布,本文观点不代表立场,文章出自:https://mp.weixin.qq.com/s/O81Kw-ujcbjY_1S6dFKpxQ 转载来自ChaMd5安全团队
-- 展开阅读全文 --
New:关于JAVA视频推迟发布公告
« 上一篇 04-12
利用chrome漏洞进行微信钓鱼攻击防范
下一篇 » 04-17

发表评论