CVE-2023-4427 poc分析
Build
CVE详情页
V8的OOB漏洞,issue页面有非常详细的poc和原理解释,后面根据这个poc进行调试。
查看第一条commit,parent hash为610c1976fe17b5bfb12eefe1e6dc7c3a5bd5141a
。
复现环境为windows 11。
Details
map中关于属性的信息存储在DescriptorArray中,这一Array将会被多个具有相同结构的Object共享,其中存在enum cache,用于对fast object的for...in
遍历进行优化,当访问对象不变时,将会直接使用enum cache加速对Array的遍历。它一开始不会产生,只有在实际调用时,才会初始化或修改enum cache,调用过程如下图。
Turbofan优化时,如果函数中对属性的值进行读取,会调用ReduceJSLoadPropertyWithEnumeratedKey
函数进行优化,顾名思义,优化的方式就是每次不再使用JSLoadProperty
的方式通过名称来读取一个property的值,而是直接使用enum cache中的索引值进行读取。函数中使用很长的注释进行了描述。
1 | Reduction JSNativeContextSpecialization::ReduceJSLoadPropertyWithEnumeratedKey( |
这就存在一个问题,如果enum cache在函数循环的过程中被更新了,并且元素个数小于应有的元素个数,就会产生越界读。
poc
直接对issue中给出的poc稍作修改进行分析
1 | const object1 = {}; |
运行过程中Turbofan对trigger这一函数进行了优化,但是在最后一次调用中,callback函数进行了一些有side effect的操作,首先c属性的值变成了浮点数类型,这就导致map中的DescriptorArray需要重新生成,但是并不需要重新生成map,所以这一过程能够通过checkmap检查。此时新的DA中enum cache为null,因为没有进行过任何let...in
的遍历操作,但是紧接着对object1进行遍历的过程中,enum cache被初始化为了一个长度为1的数组,但是object2的长度是从map中获取的,始终是2,所以在读取的时候,或在enum cache的indices中越界访问到后面的内容。
End
这次没有写exp,只是快速地对poc进行了分析,因为利用起来需要十分复杂的堆排布,感觉想要实现完整exp比较困难,并且也没有发现ITW的利用。
在强网杯的决赛又见到了这个CVE,还是写了exp,方法看起来有些ugly,通过spray硬编码的地址来实现越界访问,不太稳定。
Reference
https://cwresearchlab.co.kr/entry/CVE-2023-4427-PoC-Out-of-bounds-memory-access-in-V8
Comments