author: @relooadin / X
2024-06-03 17:09:52
Shout out to @buptsb and @mistymntncop for their brilliant work.
漏洞信息
Chrome Releases: Stable Channel Update for Desktop (googleblog.com)
CVE-2024-4761是V8越界写入漏洞,攻击者可以通过构造恶意代码达成渲染进程RCE(沙箱内)。谷歌在发布的Chrome版本 124.0.6367.207 中修复了该漏洞。
commit:[wasm-gc] Only normalize JSObject targets in SetOrCopyDataProperties
[wasm-gc] Only normalize JSObject targets in SetOrCopyDataProperties (5527397) · Gerrit Code Review (googlesource.com)
根据补丁信息及X上已公开的POC (作者: @buptdsb)可知,该漏洞是由 SetOrCopyDataProperties
函数在转换属性存储模式过程中校验不充分造成的越界写。
关于补丁
- 在
JSReceiver::SetOrCopyDataProperties
函数中 - 当descriptor长度大于1020时,将快属性转化为慢属性。
- 该补丁使非
JSObject
的对象无法进入泛化逻辑 - 从标题来看重点针对
wasm-gc
对象
简单地说就是新引入的WasmObject
对象不该进入JSReceiver::SetOrCopyDataProperties
的 Normalize 逻辑。
POC分析
inobject 个数计算
src/objects/map.h - v8/v8 - Git at Google (googlesource.com)
OOB
inobject被计算为4,前4个32bit被抹零,所以会进入 GetRootForNonJSReceiver
重入JS
在这里切回js
截图来自:CVE-2024-4761.js (github.com)
很多与对象属性访问相关的历史漏洞(如CVE-2021-30551)都使用过“重入JS用户代码”的模式
利用
@buptsb 与 @mistymntncop 已公开利用方法:
CVE-2024-4947: v8 incorrect AccessInfo for module namespace object causes Maglev type confusion (buptsb.github.io)
CVE-2024-4761: v8 missing check of WasmObject type cast causes type confusion and OOB access (buptsb.github.io)
gc会把 0xf2000 00000000 当做map
As the instance_type
is 0 for now, it’s INTERNALIZED_TWO_BYTE_STRING_TYPE
,
so we will call CALL_APPLY(SeqTwoByteString)
to gc this object.
随后GC,使 o' property
与 arr1
重叠,通过访问o的属性更改 arr1
的 length
。
SeqTwoByteString
双字节字符
V8 的源代码中,有一个方便查阅的列表,列出了它使用的所有字符串实现:
从 string.tq 一直往在追,SeqTwoByteString 的内存表示为:
map: Map | raw_hash_field: NameHash | length: int32 | chars[length]: char16
的形式
map为0的对象会被识别成 SeqTwoByteString, 由于instance_type为0,即*(base+8) = 0
原因如下:CVE-2024-4947: v8 incorrect AccessInfo for module namespace object causes Maglev type confusion (buptsb.github.io)
源码参考:string.tq - Chromium Code Search
总结
- wasm-gc对象在
SetOrCopyDataProperties
函数中被normalize
时发生oob(被当做JSObject) - 越界写的内容和范围: map_base+5 ~ map_base+4 范围内置零,对于Wasm Array,该对象后紧接着的一个32位会被越界置零。
- 利用 property array reallocates 布局内存,使一个fast property(
properties[0]=0
)紧随 Wasm Array - 触发漏洞,fast property 的 map被置0,利用getter重回JS用户态(避免崩溃)
- 触发 GC ,fast property 被混淆为
SeqTwoByteString
,可通过访问 fast property 越界写入相邻对象的内部数据。
涉及知识点:
- fast property
- Object.assign
- normalize
- map layout
- getter / runtime call
- GC
- SeqTwoByteString
其他:
- map layout 查询
- 通过 x.tq 查询对象布局
- 使用 --soft-abort 关闭 DCHECK
完整利用
需要绕过 heap sandbox
具体方法可参考补丁中的回归测试文件,不赘述