V8学习
V8环境搭建
找个代理以后,直接参考这个师傅的文章:v8调试环境搭建。但是自己本地的代理对于浏览器这种应用可以,不知道为什么终端就是不走代理(正好和参考文章的情况相反),这里我使用的是在终端中输入export https_proxy="http://127.0.0.1:8889/
和export http_proxy="http://127.0.0.1:8889/
这种暂时的的代理,剩下的就没什么区别了。
如果本地还是存在一些奇奇怪怪的问题,可以参考:工欲善其事:Github Action 极简搭建 v8 环境,这篇文章使用GitHub Action去搭建V8,由于这个项目最后更新的是2020,有一些东西和现在已经不同了。之前在GitHub Action使用的是Ubuntu18,但现在Ubuntu18似乎已经被遗弃,改用Ubuntu20;之前使用的是牛奶快传这种工具,但是现在好像也没法去正常使用,最后改用文叔叔。
这里给出我魔改的版本:
1 |
|
V8源码分析
本人很菜,现在只能对builtins-array.cc中常见的函数进行一些总结。
builtins-array.cc是JavaScript 数组操作相关的内置函数的实现。
1 |
|
具体题目:starctf2019-oob、数字经济-final-browser
V8漏洞利用
addressOf和fakeObject
1 |
|
obj_array数组中存储的是obj的地址,float_array数组中存储的是浮点数,v8完全依赖map类型对js对象进行解析。如果可以修改obj_array的map为float_array的map,再去使用obj_array[0]是去按浮点数去取值,原来的值是obj的地址,最后以浮点数的形式泄漏地址;同样如果可以修改float_array的map为obj_array的map,再去使用float_array[0]是去按对象地址去取值,原来的值是浮点数,最后以16进制的IEEE754数为地址得到一个对象,当然这个地址与地址中的内容需要提前构造好。
利用ArrayBuffer去任意读写
1 |
|
BackingStore地址是申请堆上的一段内存,是真正写入数据的地址,如果修改BackingStore指针,那么就可以获得任意读写的能力了。
当然要想任意读写的前提是先泄漏一个合法的地址,再修改BackingStore指针,如果V8使用了指针压缩,将指针的有效位数减少到32位或更少,虽然对BackingStore指针没有影响,但是前面提到的obj_array中存的会是一个32位地址(将高32直接去掉,只保留低32位),这样无法泄漏完整的地址。
伪造map
有时如果没法泄漏map地址,是可以直接伪造map
具体题目:34c3 v9
wasm执行shellcode
1 |
|
结合其它漏洞将原本内存中的的wasm代码替换为shellcode,当后续调用f函数时,实际上调用的就是shellcode。
先得到f函数的地址,通过shared_info–>WasmExportedFunctionData–>Instance这一系列关系,最后在Instance的固定偏移处(不同V8版本偏移是不同的),就能读取到存储wasm代码的内存页起始地址,这个内存页是RWX段并且是页对齐的。如果直接可以得到wasmInstance的地址就不用上述麻烦办法,其实Instance的地址就是wasmInstance的地址。
对于一些低版本的V8,RWX段是可以直接在f函数的地址的偏移处找到的(具体题目:34c3 v9)
也有shared_info中没有WasmExportedFunctionData的这种情况(还不清楚是什么原因,具体题目:PlaidCTF roll a d8)