首页
社区
课程
招聘
[原创]看雪CTF2019Q3 第十二题:精忠报国 题目设计思路
发表于: 2019-9-9 21:56 3597

[原创]看雪CTF2019Q3 第十二题:精忠报国 题目设计思路

2019-9-9 21:56
3597

简单地说这是一个V8的利用题,patch里面先是把d8的一些函数给删掉了,不然你可以直接用read读flag。然后漏洞patch是把FillImpl函数的用于扩大capacity的代码删除了,这样子的话,当end > capacity的时候,可以早成OOB写。

漏洞在FillImpl,可是我们怎么从JavaScript中调用到它并且控制end和capacity的值呢?这个时候可以找一下cross-reference,或者直接搜索字符串。发现这里调用了FillImpl:

然后,继续搜索这个函数的cross-reference,会发现在builtins-array.ccTryFastArrayFill中使用了他,并且这个函数会被BUILTIN(ArrayPrototypeFill)所调用。然后很明显这个函数就对应JavaScript中的Array.prototype.fill

总结一下,就是patch的函数是Array.prototype.fill的底层实现之一,只要我们能够让传进去的end > capacity,就可以OOB写。end来自于end_index,而这个来自于args.atOrUndefined(isolate, 3),即JavaScript的参数。

阅读一下这个函数,发现end_index是从GetRelativeIndex转换而来,而这个函数永远会保证返回的值小于等于array.length,这个length其实一定小于等于后面的capacity。咋一看好像触发不了,但是其实是有一个小问题的,就是Object::ToInteger可以调用JavaScript代码,然后在这个时候可以去收缩array的长度,这样就可以在FillImpl里面使得capacity < end了。

具体PoC:

还有一点要注意,因为就算你收缩了arr的长度,实际上这后面能写到的地方也是未被使用的内存,所以我们需要调用一下GC,这样就可以让OOB写到有用的数据了。

接下来的利用就很常规了,首先通过堆风水,在arr后面分配另一个array,这样可以OOB写它的length,然后这个时候就能拿到一个oobArray,把OOB写升级成OOB读写。

然后这个oobArray后面也得有一个ArrayBuffer和一个web assembly function的地址,这样就能leak,然后任意读写,在RWX页上写shellcode并且执行。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-9-25 09:37 被kanxue编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//