这题看着wp复现的,粗浅的认识v8的Escape Analysis,还有些许疑惑,望以后能理解把
前言
题目链接:https://github.com/pwn2winctf/challenges-2020/tree/master/pwn-OmniTmizer
这是本人粗浅的认识,有错误还望指出
题目分析
题目目录:
1 | PS D:\shared\pwn2win_2020\pwn-OmniTmizer\files> ls |
进入到x64.release目录下,是个d8.exe,这题是一个windows下的题目
在看看patch文件:
1 | https://github.com/v8/v8/tree/50dd84ca317ae35c926ed34d001a72b62aea6662 |
这个好像是把checkMap Node全给删掉了
在JIT中,如果一个函数总是用某一类型的对象(例如字符串)来调用,那么JIT优化后函数就会针对该类型的对象进行预先的特化,或者类似模板?但是如果参数不是字符串的时候,这优化后的函数就会出错。为了避免这种情况,JIT优化的时候是会对Map进行检查的,个人理解就是本来参数一直都是字符串,突然间传入了一个对象,这时候JIT就会DeOptimise,这个好像依赖于CheckMap,这题的patch把这一check给删掉了,所以会造成类型混淆
故我们可以用这个来制造addressof原语和fakeobj原语,已达到执行任意代码的目的
exploit
整体的攻击流程如下:
- 先构造好addressof原语和fakeobj原语
- 伪造一个FixedDoubleArray,越界读取高位的指针值以计算完整的地址
- 在伪造一个ArrayBuffer,修改其backing_store,来进行任意地址读写
- 修改wasm的可执行代码来执行shellcode
exp:
1 | function r(i) { |
效果:
踩坑
伪造ArrayBuffer的时候,那个Map最好也伪造一下,就找一个正常的ArrayBuffer对象,把它的Map长啥样照抄过来就行;
因为这个pointer compression 的问题,我们泄露出来的地址都只有4个字节,这里的好处就是伪造的时候很好伪造,坏处就是第一次调试的时候很难受,而且仅仅只是伪造FixedDoubleArray达不到任意地址读写的目的,所以还是要依赖ArrayBuffer来任意地址读写(伪造对象的时候记得地址+1);
还有一个疑问就是那个伪造对象的没看懂,感觉还是差了那么点东西才能理解
参考链接
2020 Pwn2Win OmniTmizer Challenge:https://yichenchai.github.io/blog/omnitmizer
V8逃逸分析(escape-analysis)N1CTF2020 Escape https://www.anquanke.com/post/id/224317