DEP (Data Execution Prevention) and ASLR (Address Space Layout Randomization) have proven themselves to be important and effective countermeasures against the types of exploits that we see in the wild today.  Of course, any useful mitigation technology will attract scrutiny, and over the past year there has been an increasing amount of research and discussion on the subject of bypassing DEP and ASLR [1,2].  In this blog post we wanted to spend some time discussing the effectiveness of these mitigations by providing some context for the bypass techniques that have been outlined in attack research.  The key points that should be taken away from this blog post are:

  • DEP and ASLR are designed to increase an attacker's exploit development costs and decrease their return on investment.
  • The combination of DEP and ASLR is very effective at breaking the types of exploits we see in the wild today, but there are circumstances where they can both be bypassed.
  • Exploits targeting Microsoft and third party vulnerabilities have been created that are capable of bypassing DEP and ASLR in the context of browsers and third party applications.
  • We are currently not aware of any remote exploits that are capable of bypassing DEP and ASLR in the context of in-box Windows services and various other application domains.
  • Knowledge of potential bypass techniques directly informs our future work to improve the robustness and resiliency of DEP, ASLR, and our other mitigation technologies.

DEP effectiveness (without ASLR)

In a previous blog post series we went into detail on what DEP is and how it works[part 1, part 2].  In summary, the purpose of DEP is to prevent attackers from being able to execute data as if it were code.  This stops an attacker from being able to directly execute code from the stack, heap, and other non-code memory regions.  As such, exploitation techniques like heap spraying (of shellcode) or returning into the stack are not immediately possible.

The effectiveness of DEP hinges on the attacker not being able to 1) leverage code that is already executable or 2) make the attacker's data become executable (and thus appear to be code).  On platforms without ASLR (that is, versions of Windows prior to Windows Vista), it is often straightforward for an attacker to find and leverage code that exists in modules (DLLs and EXEs) that have been loaded at predictable locations in the address space of a process.  Return-oriented programming (ROP) is perhaps the most extensive example of how an attacker can use code from loaded modules in place of (or as a stepping stone to) their shellcode [3,1].  In addition to loaded modules, certain facilities (such as Just-In-Time compilers) can allow an attacker to generate executable code with partially controlled content which enables them to embed shellcode in otherwise legitimate instruction streams ("JIT spraying")[2].

The fact that modules load at predictable addresses without ASLR also makes it possible to turn the attacker's data into executable code.  There are a variety of ways in which this can be accomplished, but the basic approach is to use code from loaded modules to invoke system functions like VirtualAlloc or VirtualProtect which can be used to make the attacker's data become executable.

Summary: DEP breaks exploitation techniques that attackers have traditionally relied upon, but DEP without ASLR is not robust enough to prevent arbitrary code execution in most cases.

ASLR effectiveness (without DEP)

Attackers often make assumptions about the address space layout of a process when developing an exploit.  For example, attackers will generally assume that a module will be loaded at a predictable address or that readable/writable memory will exist at a specific address on all PCs.  ASLR is designed to break these assumptions by making the address space layout of a process unknown to an attacker who does not have local access to the machine.  This prevents an attacker from being able to directly and reliably leverage code in loaded modules.

The effectiveness of ASLR hinges on the entirety of the address space layout remaining unknown to the attacker.  In some cases memory may be mapped at predictable addresses across PCs despite ASLR.  This can happen when DLLs or EXEs load at predictable addresses because they have not opted into ASLR via the /DYNAMICBASE linker flag.  Prior to Internet Explorer 8.0 it was also possible for attackers to force certain types of .NET modules to load at a predictable address in the context of the browser[6].  Attackers can also use various address space spraying techniques (such as heap spraying or JIT spraying) to place code or data at a predictable location in the address space. 

In cases where the address space is initially unpredictable an attacker can attempt to discover the location of certain memory regions through the use of an address space information disclosure or through brute forcing[5].  An address space information disclosure occurs when an attacker is able to coerce an application into leaking one or more address (such as the address of a function inside a DLL).  For example, this can occur if an attacker is able to overwrite the NUL terminator of a string and then force the application to read from the string and provide the output back to the attacker [4].  The act of reading from the string will result in adjacent memory being returned up until a NUL terminator is encountered.  This is just one example; there are many other forms that address space information disclosures can take.

Brute forcing, on the other hand, can allow an attacker to try their exploit multiple times against all of the possible addresses where useful code or data may exist until they succeed.  Brute forcing attacks, while possible in some cases, are traditionally not practical when attacking applications on Windows because an incorrect guess will cause the application to terminate.  Applications that may be subjected to brute force attacks (such as Windows services and Internet Explorer) generally employ a restart policy that is designed to prevent the process from automatically restarting after a certain number of crashes have occurred.   It is however important to note that there are some circumstances where brute force attacks can be carried out on Windows, such as when targeting an application where the vulnerable code path is contained within a catch-all exception block.

Certain types of vulnerabilities can also make it possible to bypass ASLR using what is referred to as a partial overwrite.  This technique relies on an attacker being able to overwrite the low order bits of an address (which are not subject to randomization by ASLR) without perturbing the higher order bits (which are randomized by ASLR).

Summary: ASLR breaks an attacker's assumptions about where code and data are located in the address space of a process.  ASLR can be bypassed if the attacker can predict, discover, or control the location of certain memory regions (particularly DLL mappings).  The absence of DEP can allow an attacker to use heap spraying to place code at a predictable location in the address space.

DEP+ASLR effectiveness

In the previous sections we described the effectiveness of DEP and ASLR in isolation from one another.  In reality, DEP and ASLR are designed to be used in combination on Windows Vista and beyond.  Both of these mitigations are enabled in the context of important applications like Internet Explorer 8, Microsoft Office 2010, and in-box services and applications that ship with the OS.  This means that attackers looking to exploit vulnerabilities in these environments will need to overcome both obstacles (in addition to numerous other mitigations). 

The DEP+ASLR bypass techniques that are currently being explored in attack research have primarily focused on identifying and refining methods of bypassing ASLR.  Once ASLR has been bypassed it is typically straightforward to bypass DEP using established techniques such as return-oriented programming.  At this point in time there have been multiple exploits which have demonstrated that it is possible in practice to bypass the combination of DEP+ASLR in the context of certain application domains (such as browsers and third party applications).  These exploits have bypassed ASLR through the use of predictable DLL mappings, address space information disclosures, or JIT spraying and have bypassed DEP through the use of return-oriented programming (or some simpler variant thereof) or JIT spraying.   In many cases these exploits have relied on predictable mappings caused by DLLs that ship with third party components or by JIT compilation capabilities included in non-default browser plugins.  This means that these exploits will fail if the required components are not installed.

Although exploits have been written which are capable of bypassing the combination of DEP+ASLR, the vast majority of exploits that have been written to date do not have such capabilities and instead strictly target applications and platforms that do not enable these mitigations.  This affirms our position that DEP+ASLR are strong countermeasures for the types of attacks that we see in the wild today despite weaknesses in their current implementations.

Summary: DEP+ASLR are most effective when used in combination; however, their combined effectiveness is heavily dominated by the effectiveness of ASLR.  Exploits have been developed that are able to bypass DEP+ASLR in the context of browsers and third-party applications.  Nevertheless, the vast majority of exploits written to date do not attempt to bypass the combination of DEP+ASLR.

Future directions

As we look toward the future it is clear that attackers will continue to become increasingly incentivized to attempt to develop exploits which are capable of bypassing the combination of DEP+ASLR.  Our understanding of the ways that DEP and ASLR can be bypassed directly informs the future work we are doing to improve the robustness and resiliency of our mitigation technologies.  Although this work is ongoing there are two noteworthy improvements that we would like to highlight. 

The first improvement can be seen in the latest version of the Enhanced Mitigation Experience Toolkit (EMET) which now includes support for a feature known as mandatory ASLR.  This feature enforces ASLR for all modules regardless of whether or not they are ASLR aware (which effectively eliminates predictable DLL mappings when enabled on Windows Vista and above).  This resolves the ASLR bypass technique we described previously and it has been used in practice to successfully mitigate exploits in the wild.  The second improvement consists of JIT spraying mitigations that have been directly incorporated into the JavaScript JIT compiler that was recently released in the Internet Explorer 9 beta.  These mitigations act as countermeasures against the JIT spraying techniques that have been described in attack research. 

These two improvements help to further illustrate our belief that DEP, ASLR, and exploit mitigations in general are extremely important due to the impact they have on the cost of developing reliable exploits and due to the knowledge demands they place on attackers.  Mitigations such as these enable us to be proactive about providing additional protection to customers who may be running software with an unknown or unpatched vulnerability.  Ultimately our goal with exploit mitigations is to reach a point where vulnerabilities become too expensive to reliably exploit - and this is a goal we are actively working toward.

Recommendations

For enterprises and users

We recommend that enterprises and users enable DEP for all critical applications and run a version of Windows that supports ASLR (such as Windows 7).  The Enhanced Mitigation Experience Toolkit (EMET) can be used to easily enable DEP and other mitigations for a process.  You can read more about EMET here:

http://support.microsoft.com/kb/2458544

For ISVs

The effectiveness of mitigations like DEP and ASLR across the Windows ecosystem is heavily contingent on ISV adoption.  ISVs that are interested in more details on how to enable DEP, ASLR, and other mitigations in their products are encouraged to refer to the guidance below:

http://msdn.microsoft.com/en-us/library/bb430720.aspx

Matt Miller, MSEC Security Science

References

[1] Dino Dai Zovi.  Practical Return-Oriented Programming.  April, 2010.

[2] Dionysus Blazakis.  Interpreter Exploitation: Pointer Inference and JIT Spraying.  February, 2010.

[3] Hovav Shacham.  Return-Oriented Programming: Exploits Without Code Injection.  August, 2008.

[4] Peter Vreugdenhil.  Pwn2Own 2010 Windows 7 Internet Explorer 8 Exploit.  March, 2010.

[5] Hovav Shacham et al.  On the Effectiveness of Address-Space Randomization.  2004.

[6] Alexander Sotirov and Mark Dowd.  Bypassing Browser Memory Protections.  August, 2008.

*Posting is provided "AS IS" with no warranties, and confers no rights.*