cve-2023-3079漏洞与patch分析

POC

function set(arr, key, val) {
    arr[key] = val;
}
function leak_hole() {
    for(let i = 0; i < 10; i++) {
        set(arguments, "foo", 1);
    }

    set(new Array(), 0, 1);
    set(arguments, 0, 1);
    return arguments[1];
}
%DebugPrint(leak_hole());

分析

通过对此漏洞的patch分析可知,此漏洞主要是由于没有检查传入的receiver是否是arguments对象并对其做特殊处理导致的:
cve-2023-3079漏洞与patch分析_第1张图片
当在循环执行到第9次时将会触发内联缓调用(前八次都将是no_feedback)AccessorAssembler::KeyedStoreIC(const StoreICParameters* p)函数,由于第一次触发IC所有会进入miss分支,此分支会进入Runtime_KeyedStoreIC_Miss函数:
cve-2023-3079漏洞与patch分析_第2张图片
Runtime_KeyedStoreIC_Miss函数中会调用KeyedStoreIC::Store以此来获取Store操作对应的StoreHandler对象,此对象中保存着具体用于从receiver获取属性内容的code:
cve-2023-3079漏洞与patch分析_第3张图片
cve-2023-3079漏洞与patch分析_第4张图片
KeyedStoreIC::Store函数开始就将会进入漏洞的主要触发流程,在第九次执行set(arguments, "foo", 1);时由于key是属性name类型会直接在调用完StoreIC::Store函数后结束:
cve-2023-3079漏洞与patch分析_第5张图片
在执行set(new Array(), 0, 1);时会与前一个处理过的arguments对象相同,由于receiver与key都不同所以将会触发miss分支,并调用KeyedStoreIC::Store函数,与上一行代码不同的是set(new Array(), 0, 1);key不是一个属性name类型,而是一个元素索引类型,所以KeyedStoreIC::Store函数会先执行到以下位置:
cve-2023-3079漏洞与patch分析_第6张图片
此处主要用于获取is_argumentsold_receiver_mapkey_is_valid_indestore_mode几个变量,其中store_mode比较重要,因为在生成StoreHandle时会根据它来选择具体的存储代码,由于此处处理的是array所以is_argumentsis_proxy都将会是false,而key是0也是一个有效的index,所以此处会通过GetStoreMode来获取具体的存储模式:
cve-2023-3079漏洞与patch分析_第7张图片
存储模式主要有四种,根据poc来分析漏洞的话可知此处我们需要STORE_AND_GROW_HANDLE_COW模式,此模式是一个可扩展的存储模式,由于可扩展模式没有比较严格的边界检查所以会导致之后的问题,想要得到这种模式,要满足四个条件:

  • receiver是一个JSArray对象
  • 必须得是越界访问
  • 当前索引必须小于JSArray最大索引数
  • 数组元素必须连续,也就是说必须是PACKED_ELEMENTS类型的数组

之后将会去调用UpdateElements函数,UpdateElements函数会先初始化一个target_maps_and_handlers列表,通过调试可知这个列表的内容与feedback反馈槽中保存的内容是一至的,通过名称可知这个列表里主要保存map与handler:
cve-2023-3079漏洞与patch分析_第8张图片
cve-2023-3079漏洞与patch分析_第9张图片
map通过执行lambda表达式通过map的过渡树向上遍历map转换关系得到更新后的map,而handler则是通过反馈网络对象获取:
cve-2023-3079漏洞与patch分析_第10张图片
获取完target_maps_and_handlers后会对单态会用直接用StoreElementHandler函数去获取StoreHandler,如果不满足单态那就用多态的处理函数StoreElementPolymorphicHandlers去获取StoreHandler,此处会进入多态处理函数:
cve-2023-3079漏洞与patch分析_第11张图片
StoreElementPolymorphicHandlers函数会遍历处理target_maps_and_handlers列表中的每一个map与handler,并且会根据当前map是否具有过渡map来进入不同分支,此处列表中的两个map都不存在过渡,所以会直接去执行StoreElementHandler函数,StoreElementHandler函数中会根据store_mode来获取具体的code,而store_mode在前面已经提到过是通过当前正在处理的对象,也就是Array对象获取到的STORE_AND_GROW_HANDLE_COW,所以在遍历中无论是处理Arguments map还是处理Array map都是用STORE_AND_GROW_HANDLE_COW模式来获取code:
输入图片说明
最后得到一个结构如下的feedback,0是arguments对象的map,1为STORE_AND_GROW_HANDLE_COW模式的code,2为Array对象的map,3同1一样也是STORE_AND_GROW_HANDLE_COW模式的code:
cve-2023-3079漏洞与patch分析_第12张图片
最后在执行set(arguments, 0, 1)时由于COW(写入时拷贝)的原因当在具体向arguments对象elelments写入内容时会将elements中的内容完整的拷贝到一块新的elements中并将要写入的内容写入。最后通过arguments[1]越界读取内容时就会将hole错误的读出来导致hole泄露。
而在官方的patch中的修复方案也比较简单,当在StoreElementHandler遇到arguments map并且elements是PACKED_ELEMENTS时,直接不使用外部传入的store_mode,而是直接用标准存储模式STANDARD_STORE
cve-2023-3079漏洞与patch分析_第13张图片

你可能感兴趣的:(浏览器安全漏洞,chromium,bugs,网络安全,pwn,chrome,issue)