AccessInfoFactory::ComputeDataFieldAccessInfo
函数中,有两处unrecorded_dependencies.push_back
被删除掉,同时让constness
始终被赋值为PropertyConstness::kConst
先浏览一下整个函数的功能(以下为patch后的代码),首先获取了map
中的instance_descriptors
(存储了对象属性的元信息),然后通过descriptor
定位到了一个具体的属性。
依次判断属性的类型,在进行一定的检查后,将属性加入到unrecorded_dependencies
中。patch导致了一些本应该加入到unrecorded_dependencies
的属性没有被加入进去。
继续跟踪函数返回值可以发现最终返回的是一个PropertyAccessInfo对象,而unrecorded_dependencies
则是被初始化赋值给私有成员unrecorded_dependencies_
其中Merge函数中合并了两个unrecorded_dependencies_
,RecordDependencies函数中将unrecorded_dependencies_
转移到了CompilationDependencies
类的私有成员dependencies_
并清空了自身
浏览CompilationDependencies
类所在的compilation-dependency.cc(.h)
文件,从注释中可以得知该类用于收集和安装正在生成的代码的依赖。
逐个跟进文件查看后,我在compilation-dependencies.cc
中注意到了以下部分代码。从代码中可以看出,Ruduce过程中,可以通过添加dependency的方式来将CheckMaps节点删除,我认为这便是道题的root cause.
该题目中,因为删除了某些添加dependency的代码,这就导致在代码runtime中,某些元素的改变不会被检测到从而没有deoptimize,最终造成type confusion。
patch删除了details_representation.IsHeapObject()
分支中的unrecorded_dependencies.push_back
操作,这意味HeapObject
类型不会被加入dependencies中。
将obj作为参数传入leaker,生成JIT代码后,用{b: buf_to_leak}
替换掉原来的字典,再次调用leaker(obj),可以发现并没有触发deoptimize,而是输出了一个double值(buf_to_leak的地址)
trick:在调试过程中会发现,Elements并不是始终紧邻JSArray的,有些时候两者会相距一段距离。在师傅们的wp中提到可以使用splice
来使该布局稳定,例如
在伪造ArrayBuffer的时候需要同时也伪造出它的Map的结构(当然,也可以对内存中ArrayBuffer的Map地址进行泄露,但是就麻烦了),通过找到JSArray的地址,+0x40即为map的地址,再将map地址填入JSArray的第一项即可。
在v8利用中总是需要布置shellcode,那么在内存中找到一块具有RWX权限的区域将会十分有帮助。wasm(WebAssembly)详细概念就不在这介绍了,这里值得注意的是是用wasm可以在内存中开辟出一块RWX的内存空间。
这里可以将C语言编写的代码转换为wasm格式。当然,编写的c语言代码不能够调用库函数(不然就可以直接写rce了),但是只要通过漏洞,将我们的shellcode覆盖到内存中wasm代码所在rwx区域即可。
1 |
|
1 |
function success(str, val){ |
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论