In the recent Microsoft security bulletin for Internet Explorer, we found an interesting improvement for mitigating UAF (User After Free) vulnerability exploits. The improvement, which we will name as “isolated heap”, is designed to prepare an isolated heap for many objects which often suffers from UAF vulnerabilities.
Let’s use Internet Explorer 11 as an example. Before it was patched, the function CHeadElement::CreateElement allocates memory space from the heap. The code is as follows:
Figure 1. The function CHeadElement::CreateElement
From Figure 1, we can see the memory space is allocated from the heap g_hProcessHeap, which is the IE default heap. In other words, all these IE objects share the same heap. After the patch, in the sample location, the code was changed to the following:
Figures 2 and 3. The function CHeadElement::CreateElement after the patch
From Figures 2 and 3, we can see that Internet Explorer now allocates memory space from the heap g_hIsolatedHeap. In other words, these class objects which use the isolated heap do not share the same heap with IE’s other objects.
How can an isolated heap mitigate UAF vulnerability exploits?
The first routine of UAF vulnerability exploits is to use controlled objects to occupy the memory space which is owned by the UAF object. Some recent Internet Explorer zero-day vulnerabilities such as CVE-2014-0322 and CVE-2014-1776 used this technique.
We can summarize the technique of occupying space in the following steps:
- Use String or Array to make a buffer which can be controlled by attacker. For example: “var d=b.substring(0,(0x340-2)/2);”
- Create an IE element object. For example: “g_arr[a]=document.createElement(‘div’)”
- Trigger vulnerability to free the target object.
- Set the attribute of the objects which is created by step 2 for many times with the String which is created in step 1. For example:
In step 4, IE will allocate memory space in the heap g_hProcessHeap. In the example for step 4, we can see the following part of the call stack:
Figure 4. The function CAttrArray::Set() calling the function RtlAllocateHeap()
In figure 4 we see CAttrArray::Set() calling the function RtlAllocateHeap(). The call stack is done with the following code:
Figure 5. It uses RtlAllocateHeap with heap “g_hProcessHeap” and then copies the String ‘s data to this buffer.
Before the latest patch, if the RtlAllocateHeap has the correct size, the probability that an attacker-controlled buffer could occupy the freed object’s memory space is high. But after the latest patch, the freed object is allocated in heap g_hIsolatedHeap, so there is no probability that the freed object memory space is occupied by the attacker-controlled buffer. The solution is a good way to mitigate UAF vulnerability exploits.
From the patch‘s code,the heap g_hIsolatedHeap is used by HTML and SVG DOM Elements (CXXXElement) and supporting elements such as CTreeNode, CMarkup, CAttribute and so on. These objects have a high probability of having the UAF vulnerability, so it is important that they are secured through the isolated heap.
Can the isolated heap solution mitigate UAF vulnerabilities completely?
No solution is perfect. The improvement implemented by Microsoft raises the difficulty in creating an exploit, but it does not eliminate the vulnerability completely. There are two theoretical ways to bypass this protection:
- If attackers can find an object which meets the following three criteria instead of String:
- Allocated with the isolated heap.
- Correct size for the UAF object.
- Easily control the content of the object.
What is not clear is if attackers can find a reasonable way to perform the above attack.
- Many objects are still using the process heap, not the isolated heap. If these objects encounter UAF vulnerability, the isolated heap solution doesn’t work. However, Microsoft can easily add objects to use the isolated heap if this becomes a problem down the road.
We are glad that Microsoft is continuing to improve the security of Internet Explorer and mitigating the abuse of vulnerabilities. While the isolated heap is not a perfect solution, it represents a significant improvement that will help mitigate attacks of this type moving forward.