华为XCTF专场-HWS-v8 暨 WCTF2019-independency_day题解
前言
华为XCTF比赛时P4nda
学长说这个题完全用了WCTF2019-independency day
的题目,原题是在win7-32bit
下的,这道题刚好是linux
下的,这里记录一下解题的过程。其中WCTF
的题目比较难找,地址在这里
环境搭建
为了能在release
版本下调试,稍微修改下args.gn
1 | is_debug = false |
1 | git reset --hard 51a443ce |
漏洞分析
patch
如下,直接把InstallDependency
给注释了,查看下相对引用,发现这个函数是所有*Dependency
类的成员函数Install
的核心。比如下面的TransitionDependency
,用来绑定map transition
过程中的依赖,每个依赖都会对应增加weak code
用来监督对象类型,以确定是否要进行解优化
。在之前的分析中我们介绍过v8
使用两种解优化的方式:eager deoptimization/lazy deoptimization
,前者对应CheckMaps
节点,后者对应code dependency
机制。其中对于stable map
我们使用code dependency
,所谓的stable map
即map
的transition
链中最后一环,我们在gdb
调试时使用DebugPrint
时可以看到Map
信息中会标记出stable map
。
在WCTF
的分享中使用double array->dictionary
触发。
1 | class TransitionDependency final : public CompilationDependency { |
1 | diff --git a/src/objects/code.cc b/src/objects/code.cc |
因为这里将安装dependency
的函数注释掉了,我们的优化函数中不再有检查参数类型的操作,当我们修改掉对象类型再传参进入优化函数后,函数仍会按照之前的map
类型解析和操作对象,可以借此构造出类型混淆
。下面是最简单的一种类型混淆的方式,我们在优化完成后修改arr[2]
的类型为obj
,即可构造出addressOf
原语,因为压缩指针
的缘故,我们再在其后面布置oob_arr
,即可以同样方式越界写其length
字段得到OOB
数组。
1 | //addressOf |
这里发现指针压缩后在其后布置oob_arr
仍不能越界访问到,联想到之前CVE-2020-6418
的对象空间布局,我们布置一些hole
在数组之前,最后成功越界读和写得到了oob_arr
。
1 | var obj = {}; |
漏洞利用
在下面的exp
中我使用的是WCTF
的方式,通过构造double array->dictionary
的map转换实现了越界读写(一旦转换为字典模式后,中间的空间都是free spce,而对于优化函数来说依然是按照索引访存和取值)。之后依然是通过obj_arr
实现addressOf
原语,通过BigUint64Array
实现任意地址读写,最后wasm
执行shellcode。
1 | function gc(){ |