Applications that have been frequently targeted by exploits frequently add sandboxes to their features in order to harden their defenses against these attacks. To carry out a successful exploit, an attacker will have to breach these sandboxes to run malicious code. As a result, researchers will pay particular attention to exploits that are able to escape sandboxes.
In both October and November Patch Tuesday cycles, Microsoft addressed several vulnerabilities that were used by attackers to escape the Internet Explorer sandbox. One of these was CVE-2014-6349, which was addressed by Microsoft as part of MS14-065, November’s cumulative Internet Explorer patch. We chose this particular vulnerability for two reasons: exploiting it is relatively easy, and its methodology – using shared memory to escape the Internet Explorer sandbox – has not been seen before. A separate vulnerability that also allowed for sandbox escapes – CVE-2014-6350 – was also fixed in the same patch, and Google released details about this second vulnerability earlier this week.
Internet Explorer 11 exposes a shared memory section object to all tab process (which are sandboxed). This is used to store various Internet Explorer settings. Normally, the tab processes only read this to see these settings. However, in Enhanced Protected Mode (EPM, which is IE’s sandbox mode), the shared memory section‘s DACL (Discretionary Access Control List) is not configured correctly. The tab processes have “write” permission to modify the shared memory section content. This can be used by an attacker to break the IE sandbox. How can this be done? We will explain this in the rest of this post.
To understand the concepts covered in this post, background knowledge about Protected Mode (PM) and EPM is necessary. These MSDN documents and HITB presentations provide background information on these topics. I carried out my tests on a system running Windows 8.1 with Internet Explorer 11.0.9600.17107.
After enable IE 11’s EPM mode, we run IE. The broker process and tab process are seen below:
Figure 1. Internet Explorer broker and tab processes
The parent iexplore.exe broker process’s integrity is Medium. The iexplore.exe tab process’s integrity is AppContainer. This means the web page rendering in the sandboxed tab process is in the sandbox and its privilege is controlled. Both process share a memory section: \Sessions\1\BaseNamedObjects\ie_ias_<frame process id>-0000-0000-0000-000000000000.
The section object’s DACL (Discretionary Access Control List) status is below:
Figure 2. Access Control List for shared memory
The ACE (Access Control Entry) for SID S-1-15-3-4096 is encircled. This shows that this particular “user” can modify the shared memory. What is S-1-15-3-4096? It is a “capability” whose name is “internetExplorer”. This particular concept was introduced in Windows 8 with AppContainer (please refer to the HITB presentation).
Now, let us check the sandboxed tab process’s security tokens:
Figure 3. List of sandboxed tab process security tokens
The above shows us that the sandbox tabs can modify the memory of the shared memory section. Because of the shared memory section’s role, the sandbox can be escaped. Before we look into why, we can examine the previous protections that were used by Internet Explorer.
Figure 4. Architecture of Internet Explorer
Internet Explorer 8 introduced the Loosely-coupled Internet Explorer (LCIE) architecture to improve the browser’s reliability. In IE11 EPM mode, the broker process is running with middle integrity and the tab processes are running in AppContainer (i.e., each is sandboxed). The broker process manages the children tab processes, with each invidual tab process rendering various oben web pages.
In Figure 4, CBrowserFrame within the broker process receives and dispatches messages to process the procedure CBrowserFrame:: FrameMessagePump(). CTabWindow represents tab windows, which each CTabWindow instance corresponding to a sandboxed tab process. The CTabWindowManger manages existing CTabWindow instances, for example, creating a new instance or finding an existing instance.
The shared memory contains the immutable application state (IAS), which is queried by the parent broker process and the sandboxed processes. The shared memory’s address was hold by a global variable whose full name is g_pvImmutableApplicationStateMappingBaseAddress. For convenience , we can call this shared memory as shared IAS memory. This memory is created when the broker process starts. Below is the call stack:
Figure 5. Call stack
After CreateFileMapping is called, the access control information for this section object will be set.
Figure 6. Setting the access control information
The vulnerability exists in the circled code. The SetWindowsHandleAccess function’s parameter is not set correctly, which leads to the shared memory section object’s ACE for the internetExplorer capability to have the modify permission.
Why can the attacker escape from the IE sandbox by modified shared IAS memory? Let us examine the contents of this memory space. It is 0x25C in size, and the table below lists its contents.
Table 1. Contents of shared memory space
We can guess that if an attacker can modify the relevant byte(s) from a sandboxed process, it will control parent broker process’s behavior. For example, let us try the offset 0x2C. Its value is normally 1. We set it to zero from a sandboxed tab process.
Normally, when a new tab is created, this is what is seen. A new process is created for the new tab.
Figure 7. Normal setup – separate processes per tab
If the boolean value at 0x2C is set to zero, a process for a new tab window is not created, as seen below:
Figure 8. No separate processes per tab
Two tabs only have one process. Checking the new tab’s properties, we find:
Figure 9. Protected Mode turned off
The page is not in sandbox mode (EPM mode). We know that 0x2C is a flag that determines whether a new process is created for a new tab, but how does this lead to a sandbox escape?
When the user clicks the “New Tab” button in the IE UI, the broker process’s CBrowserFrame:: FrameMessagePump() function will get the message, and will dispatch the corresponding window’s procedure to handle the message. Finally, it will call CTabWindowManager to create a CTabWindow instance, and will then query the shared IAS memory at 0x2c to decide whether to create new process for the tab window or create a new thread instead.
If this value is 1, a new process is created. If it is 0, the broker process only creates a new thread for the new tab. However, in this case, the new tab renders in the parent broker process’s instance. We can see that the behavior of the parent broker process was modified by the sandboxed process – hence, the sandbox has been breached using this method. Any breach of a sandbox is dangerous and may be exploited in more dangerous attacks.
This vulnerability was fixed by Microsoft by correcting the ACE of the internetExplorer capability for the shared IAS memory.
Figure 10. Corrected ACE
This can be seen in the code below.
Figure 11. Modified code