CVE-2024-0517分析心得
CVE-2024-0517分析心得
XiaozaYa 看雪学苑 2024-05-19 17:59
Error Fold Allocations in VisitFindNonDefaultConstructorOrConstruct
这个漏洞发生在MaglevGraphBuilder::VisitFindNonDefaultConstructorOrConstruct
函数中,考虑之前分析的CVE-2023-4069
也是发生在该函数中,所以打算把该漏洞也分析了。该漏洞主要发生在折叠分配时,未考虑内存空间分配与初始化之间的操作可能导致触发gc
,从而导致UAF。
还是从patch(https://chromium.googlesource.com/v8/v8/+/78dd4b31847ab1f5b06ef3d8742a9f3835fb6919%5E%21/#F0)入手:
可以看到补丁代码非常简单,就是添加了个ClearCurrentRawAllocation
函数:
该函数的功能为将current_raw_allocation_
指针清空。
这里补丁代码打在了TryBuildFindNonDefaultConstructorOrConstruct
函数中,其上层调用链为:
而VisitFindNonDefaultConstructorOrConstruct
其实我们在之前分析CVE-2023-4069
时就详细分析过,其主要就是处理FindNonDefaultConstructorOrConstruct
节点的,但是这里还是放一下代码分析吧:
这里会先调用TryBuildFindNonDefaultConstructorOrConstruct
尝试进行图创建:
可以看到这里我们可以将其分为快速路径和慢速路径,快速路径主要就是利用new_target.initial
直接进行对象创建,慢速路径则退回到内建函数FastNewObject
,这里我们主要看快速路径,快速路径为【1】->【2】->【3】
,而【3】
也是漏洞代码所在处,所以需要满足以下条件:
◆1、TryGetConstant(this_function)
◆2、TryGetConstant(new_target)
◆3、new_target.initial.constructor === target
这里想要到达想要到达漏洞逻辑,得绕过这三个判断,前面两个还是之前的方式插入CheckValue
节点绕过,第三个就不多说了,new_target
是派生构造函数即可,或者顶层默认构造函数也????,比较简单。
最后为分配对象的语句如下,也是漏洞代码所在处:
然后跟进BuildAllocateFastObject
,看其是如何创建对象的:
这里可以看到分配空间调用了ExtendOrReallocateCurrentRawAllocation
函数,其会尝试折叠分配:
先来说下什么是折叠分配?顾名思义,当我们在进行内存分配时,可能每次分配一小块内存,比如下面场景:
而多次分配内存可能是一个比较耗时的行为,于是编译器在静态分析阶段,会尝试进行分配折叠优化:
这里就避免了多次内存分配,但在动态类型语言中,可能会出现一些问题,比如在JavaScript
中,内存是由gc
进行管理的,在V8
中,没有被root object
直接或间接引用的对象被标记为死对象,在触发gc
时会被回收。所以考虑如下场景:
而如果此时发生分配折叠优化:
这里的问题就是在分配完空间后,只对obj1
的部分进行了初始化,而obj2
的初始化则是在后面,那么如果在初始化obj2
之前触发了gc
,那么此时current_raw_allocation_+0x10
这后面的内存就会被回收掉,如果我们此时分配对象占据这块内存,后面do something2
时,仍然使用current_raw_allocation_+0x10
,则导致UAF。
让我们回到该漏洞分析中,通过上面的分析我们可以知道:
◆在创建this
对象时,保留了current_raw_allocation_
指针,所以如果后面存在内存分配,则可能发生分配折叠
poc
如下:
这里先来看下Maglev IR
:
调试分析下:
this
对象的地址为0x2bca002ba4d5
,instance_size = 12
,与Maglev IR
图是吻合的:
然后程序就crash
了:
从调用栈中的函数名称可以知道,明显触发了gc
,而这里rsi
的值为一个—
地址,所以发生内存访问错误。这里我们来看下this
对象下方的内存:
这里我们换个角度看:0x2bca002ba4d5-1 = this_addr
==>o_addr = this_addr+12
看到这里其实就明白了,最开始分配了 84 字节的空间,减去this
对象占据的头 12 字节的空间,还剩下 72 字节的空间,这 72 字节其实就是包含了o
对象本身的空间和其elements
占据的空间。而这段空间在o
对象初始化之前在gc
的过程中被释放了,然后又被其它对象占据了,所以在o
初始化这段空间时就发生了UAF
,即把其它对象内容给覆盖了,所以后面的rsi
为0x2bca3ff19999 = 0x2bca00000000 + 0x3ff19999
,这里的0x3ff19999
就是1.1
的头 4 字节。
todo
笔者感觉这个漏洞想要稳定利用还是比较困难的,因为我们无法精准控制gc
,并且也无法精确控制释放后的内存被哪个对象占据。后面看看别人的expliot
吧,主要是这里的gc
搞得我很烦。
后续:
写利用写了两天,但是还是没写出来,gc
后似乎拿不到指定的内存,主要是victim
始终在this
对象的上方,不知道为啥,看参考文章说其应该在下方。然后不想在继续浪费时间了,后面有灵感了再回来写利用,暂时留个坑。失败的exploit
:
如有读者能够写出稳定的利用,希望不吝赐教。
通过分析该漏洞,学习到了分配折叠优化,目前已经通过复现漏洞学习了编译的如下常见优化方式:
◆常量折叠
◆公共子表达式消除
◆数组边界检查消除
◆逃逸分析
◆分配折叠
总的来说还是不错的,弥补了自己对编译器知识的匮乏,希望后面能够学到更多有趣的编译器漏洞。
参考
Google Chrome V8 CVE-2024-0517 Out-of-Bounds Write Code Execution
(https://blog.exodusintel.com/2024/01/19/google-chrome-v8-cve-2024-0517-out-of-bounds-write-code-execution/)
看雪ID:XiaozaYa
https://bbs.kanxue.com/user-home-965217.htm
*本文为看雪论坛优秀文章,由 XiaozaYa 原创,转载请注明来自看雪社区
# 往期推荐
2、BFS Ekoparty 2022 Linux Kernel Exploitation Challenge
3、银狐样本分析
4、使用pysqlcipher3操作Windows微信数据库
5、XYCTF两道Unity IL2CPP题的出题思路与题解
球分享
球点赞
球在看
点击阅读原文查看更多