Microsoft Edge JavaScript Information leaking Vulnerability Analysis

On November’s Microsoft Patch Tuesday, Microsoft patched multiple security vulnerabilities in Edge browser. At the beginning of January, a security research published POC code on github which exploit CVE-2016-7200 and CVE-2016-7201. Not long after the POC code, these 2 vulnerabilities become actively being exploited by multiple exploit kits. This blog is about the analysis of root cause of CVE-2016-7200 and attackers’ exploit.

CVE-2016-7200 Information Leaking Vulnerability

This vulnerability is about leaking of a JavaScript array’s memory address. Attackers can exploit this vulnerability to get a JavaScript array’s real memory address. The exploit is in a form of a JavaScript function which takes an array as input and the memory address as output. below is the exploit code:

2017-01-25-exploitcode

 

The argument “t” here is a “JavaScriptArray”. The returned array “h” is a JavaScript “NativeIntArray”. Basically if an array only contains integer values or integer array then it’s a “NativeIntArray”, and it will be a JavaScript Array if it contains strings or another type array. In Edge’s JavaScript engine Chakra, these two types of array are defined like this:

2017-01-25-Arraytype

 

The vulnerability is when __proto__ of a “JavaScriptArray” is set to ArrayB(MyArray in the exploit). Chakra doesn’t check ArrayB carefully enough. It allows ArrayB to return a “NativeIntArray” array which returned from client provided constructor, as you can see in the screenshot:

2017-01-25-Arraydspecies

 

So now array “a” whose type is a “JavaScriptArray” have its species set to “NativeIntArray”.

When array “a” calls its filter function, a lower level function named “EntryFilter” will be called in Chakra. “EntryFilter” will overwrite its species array “d” with its original values. The problem here is Chakra already thinks array “a” is a “NativeIntArray”. “JavascriptNativeIntArray::SetItem” function will be called to set values for the returned array:

2017-01-25-SETITEM

Chakra thinks the second argument Var must be a pointer which points to an IntArray/FloatArray or an integer value. But what the attackers provide is a “JavaScriptArray” or String.

2017-01-25-SETVALUE

Var is defined as a void pointer in Chakra, so it can point to anything.

typedef void * Var;

So when attackers provide a “JavaScriptArray” to the “setitem” function, the address of the input array will be saved to the returned array. At the end of the exploit, the attack returns the high bits and low bits with this statement:

return [h[3], h[2]]

2017-01-25-RETURN

 

Attackers Get the Memory Address of an Array — So What?

Address space layout randomization (ASLR) technology allows Edge browsers to load the stack, heap and libraries into different memory address every time the process is started. This is to stop the attackers from overwriting the RIP/EIP to execute the attacker’s shellcode — they can’t find a reliable address to overwrite.

After knowing the memory address of an array, offset 0x0 of this array points to the “vftable” which is list of functions all the arrays point to. The weak part of ASLR  technology is that it can’t change the offsets within a randomly loaded library, as you can see below:

2017-01-25-Chakra

The distance between “vftable” and the module Chakra’s base address is 0x274C40. So you know the module’s base address (00007ffa`99db0000) after you know the address of an array. So attackers finally know where to write to take control of EIP/RIP.  The code is as below:

      var retPtr = chakraBase.add(0x162A1D);                   

After executing the JavaScript code, “ExecutePendingScripts” function will return and the return address will be overwritten with the attacker’s shellcode. The attacker achieves this overwriting by exploiting another vulnerability in Edge browser which is CVE-2016-7201. I will discuss this vulnerability in another post.

Conclusion

Although information leaking vulnerabilities don’t sound as serious as remote code execution, this type of vulnerabilities plays an important role in the whole attacker’s exploit chain to finally execute shell code. CVE-2016-7200 is being actively exploited in the wild. Qualys has released a QID 91300 to detect the vulnerability. We highly recommend that customers scan their environment for this QID to identify these assets remotely.

Leave a Reply

Your email address will not be published. Required fields are marked *