Disarming Enhanced Mitigation Experience Toolkit (EMET)
With the emergence of recent Internet Explorer Vulnerabilities, we’ve been seeing a trend of EMET recommendations as a path to increasing application security. A layered defense is always helpful as it increases the obstacles in the path of an attacker. However, we were wondering how much does it really benefit? How much harder does an attacker have to work to bypass these additional protections? With that in mind, we started a deep dive into EMET.
The protections implemented by EMET are well described in its user guide. In addition, there are also some publicly available papers that describe various EMET mitigation bypasses, such as EMET 4.1 Uncovered and Bypassing EMET 4.1.
We picked a semi-random public exploit and started making our way towards getting it to successfully execute code of our choice on an EMET protected machine. The exploit we will focus on in this post is Internet Explorer 8 – Fixed Col Span ID Full ASLR & DEP Bypass. Our development system has the most current version of EMET at the time of this writing: EMET 4.1 update 1.
Once we test the exploit against our system with EMET installed, we notice that it is effectively stopped, with a closer look at the event logs showing that the HeapSpray mitigation from EMET caused our exploit to fail.
As noted in the EMET 4.1 Uncovered paper, this protection consists of allocating guard pages at commonly used addresses in current exploits however, as the paper mentions, this can easily be bypassed by choosing a different address to which you redirect execution to. Running the exploit again still causes EMET mitigations to kick in however, this time we see that instead of the previous HeapSpray mitigation, we are stopped by the StackPivot one.
Looking at previous publications that discuss EMET mitigation bypasses, we see that the StackPivot protection checks whether or not the stack has been pivoted, with this check being done upon entering a critical function. The list of critical functions can be reviewed in EMET 4.1 Uncovered. In our case, the critical function was “VirtualProtect”, which is one of the common APIs used to bypass DEP.
Since bypassing EMET mitigations has been thoroughly discussed in Bypassing EMET 4.1, we wanted to take a different approach. Instead of bypassing the mitigations introduced by EMET, we focused more on finding a way to disarm EMET. The main advantages of such a method are:[fancy_list style=”arrow_list” variation=”green”]
- The ability to use generic shellcode such as the ones generated by Metasploit;
- A generic way to disable all protections rather than dealing with them one by one during the development cycle of an exploit;
- Not having to rely on functions that are not critical to EMET when trying to defeat the MemProt ROP protection, especially when having “Deep Hooks” enabled.
After taking a close look at EMET.dll, we noticed that the ROP mitigations provided are controlled by two global variables in the .data section, which are located at static offsets. Of these two variables, the first one is probably the most interesting as it acts as a switch to enable or disable the entire set of ROP protections at runtime. To make things even easier, this global variable is located on a memory page marked with read/write permissions. At this point, the security implications of these findings are becoming more apparent. If we manage to zero out the general switch, all the ROP mitigations implemented by EMET would be disabled. This requires an attacker to build a ROP chain that will dynamically retrieve the base address of EMET.dll and overwrite the global variable with a zero.
The DLL we use to generate our ROP chain, as do many others, imports kernel32!GetModuleHandle. Since we have the base address of the DLL, we can easily fetch GetModuleHandle from the Import Address Table (IAT). Also, we are not parsing the Export Address Table of kernel32.dll or ntdll.dll, we will not trigger the EAF checks from EMET. In addition, GetModuleHandle is not considered a critical function by EMET. The ROP chain used can be observed below:
MOV EAX,DWORD PTR [EAX] # RETN
PUSH EAX # RETN
POP ECX # RETN
Pointer to EMET string
ADD EAX,ECX # RETN
POP ECX # RETN
MOV DWORD PTR [EAX],ECX # RETN
ADD ESP,0C # RETN
If we execute our exploit at this stage with our debugger attached, we successfully receive our shell however, as soon as we try it outside of the debugger, we notice that the exploit no longer works. This is due to the EAF checks which kick in once the generic/Metasploit shellcode tries to parse the export table address of kernel32.dll. This is confirmed by attaching a kernel debugger to the exploited process.
EAF bypass techniques have been discussed in the past and we decided to disarm EAF using a method posted by the security researcher Piotr Bania. We chose this method as it would allow us to keep our generic/Metasploit shellcode without any modifications. The exploit code was modified to resolve the function using kernel32!GetProcAddress obtained from the IAT of our DLL rather than hard-coding the systemcall value of ntdll!NtSetContextThread.
After all the changes have been made, we successfully get a shell outside of the debugger. The full EMET-disarming exploit code can be downloaded from the Exploit-DB.
We have not seen this method of bypassing EMET in public exploits, however we do believe that Microsoft became aware of it as it has been corrected in Technical Preview versions of EMET 5 and greater.
What this shows is that while EMET is definitely a good utility and raises the bar for exploit developers, it is not a silver bullet in stopping these types of attacks. We have been able to modify this example to disarm an EMET v5 preview and are waiting to see what the final release will look like. Those of you that are coming to our sold out AWE class at Black Hat Vegas will have the opportunity explore EMET hands on in one of the modules that will be covered in the class.
Of course, a video of this process is in order. Best viewed in HD and full screen!