-
-
[原创]CVE-2016-7189分析
-
发表于:
2017-11-17 02:06
6849
-
标签(空格分隔): Chakra
观察一下poc,poc首先创建了一个array t,之后创建object o,并对o设置一个getter。之后把t的_proto设为o,在对t调用Array.prototype.join。
在getter中会把t中的所有元素设为对象{a:i}。
简化POC进行调试,发现程序触发Assert异常
之所以会触发这个Assert异常是因为pArr的虚表类型为JavascriptArray::vtable
,而不是JavascriptNativeIntArray::vtable
,由此推测这是一个Array对象的类型混淆。
根据调用关系可以看到是JavascriptArray::EntryJoin
函数中触发了crash。同时由POC可以看出t的初始类型是JavascriptNativeIntArray,在getter中的赋值会导致t的类型变为JavascriptArray,而这个过程就在Array.prototype.join
中发生。当然这里只是猜测,需要通过调试来说话。
对应于Chakra的implementation是有如下几个函数
其中主要的处理是在JoinArrayHelper
中完成的
关注JavascriptArray::JoinArrayHelper函数的流程,发现有以下代码值得注意
注意代码中调用了TemplatedGetItem
,而这个函数最终会调用到ES5ArrayTypeHandlerBase<T>::GetItem
。我们知道这个函数会调用到对Object设置的Getter。
通过调试发现经过if(TemplatedGetItem(arr, i, &item, scriptContext))
之后array t的类型由Array变成了NativeIntArray
这也印证了我们前面的猜测
POC中还有一句t.length = 100;
如果去掉这句POC是不能触发的。
原因是因为代码的逻辑是获取目标array的长度,然后逐个元素的取出进行操作
但是注意我们对于array t调用Object.defineProperty
的操作并不会增加array的length值,所以TemplatedGetItem也就不会对我们的getter进行调用,因此需要手动设置array t的长度使得我们的getter可以被调用。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课