CVE-2016-7200&7201源码分析

来源:互联网 发布:广州小孩学编程 编辑:程序博客网 时间:2024/06/06 17:05

1.    Summary

CVE-2016-7200与CVE-2016-7201,漏洞攻击对象是微软的edge浏览器,而edge浏览器在进行解析javascript使用的模块是chakra.dll模块。本次分析的sample所使用的漏洞均在chakra.dll模块。由于在2015年,微软已经将chakra脚本解析引擎开源了,所以可以直接从GitHub获取源码利用VS进行调试。另外可以从GitHub的源码中看出微软是如何修补漏洞的。本次分析也是从微软修复漏洞反推漏洞的点。

源码所在地址:https://github.com/Microsoft/ChakraCore

2.    CVE-2016-7200

经查阅资料,对CVE-2016-7200有这样一段描述:There is an info leak in Array.filter. In Chakra, the destinationarray that arrays are filtered into is initialized using ArraySpeciesCreate,which can create both native and variable arrays. However, the loop that callsthe filter function assumes that the destination array is a variable array, andsets each value using DirectSetItemAt, which is unsafe, and can lead to a varpointer being written to an integer array.可以看出漏洞的利用是进行了类型混淆,直接查找chakra源码中针对CVE-2016-7200的bug fix。


先看一下微软是如何修复这个问题的:
Type confusion in Array.prototype.filter. Type confusion due to reentrancy can cause a Var to be written into a native int array.
Fix by making sure type-specialized code path is used only when ArraySpeciesCreate() invokes built-in Array constructor.
由于代码将自定义变量类型的数组作为原生int数组了,导致类型混淆从而实现越界读写。那么微软的修复是通过添加类型检查函数以防止数组类型混淆。代码diff如下:

代码添加了isBuiltinArrayCtor的检查,如果是那么就不进行DirectSetItemAt操作,所以问题出在此处的DirectSetItemAt

查看DirectSetItemAt源码:


DirectSetItemAt是一个inline函数,且是非虚函数。那么默认调用对象是JavaScriptArray类型,但是函数内部并没有做任何typeID的检查。在代码中,假如newArr并不是JavasCriptArray对象,而是其子类的对象,就会引发越界读的漏洞。

3.    CVE-2016-7200POC代码分析

64位的edge中,JavasCriptArray的每个element占用的内存大小是0×8字节,因为要保存双精度浮点数以及对象地址等信息,但是在JavasCriptNativeIntArray中每个element占用的内存大小是0×4字节.

因此每次调用JavasCriptArrayDireCtSetItemAt会占用JavasCriptNativeIntArray两个element的位置.

那么即使length没有发生越界,最终也必然会导致越界写的行为发生

 

4.    CVE-2016-7200可以用来写rule的点

要触发CVE-2016-7200必须要用到的点有:

(1)  get[Symbol.species]()

(2)  xx.__proto__= xxx.prototype;

(3)  xxx..filter(xxx);

 

5.    CVE-2016-7201

针对CVE-2016-7201有这样一段描述,JavascriptArray::FillFromPrototypes is amethod that is used by several Javascript functions available in the browser toset the native elements of an array to the values provide by its prototype.This function calls JavascriptArray::ForEachOwnMissingArrayIndexOfObject withthe prototype of the object as a parameter, and if the prototype of the objectis an array, it assumes that it is a Var array. While arrays are generallyconverted to var arrays if they are set as an object's prototype, if anobject's prototype is a Proxy object, it can return a parent prototype that isa native int array. This can lead to type confusing, allowing an integer to betreated as an absolute pointer, when JavascriptArray::FillFromPrototypes iscalled.

同样查看微软如何修复这个问题:

 


从微软漏洞修补的操作看,主要是在进行ArrayElementEnumerator初始化之前先进行了类型检查和类型转换。在ArrayElementEnumerator的构造函数中可以看出,函数内部同样没有对arraytypeID进行检查,那么会将传入的array默认为Var array这样与CVE-2016-7200类似,可以实现内存越界读写。源码如下:

 

6.    CVE-2016-7201POC 代码分析

 

7.    CVE-2016-7201可用作静态rule的点

(1)    newproxy(xxx)

(2)    xxx.__proto__= xxx

(3)    xxx.shift.call(xxx)

0 0
原创粉丝点击