华为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(){ |