Understanding Windows security mitigations

The purpose of implementing various exploit mitigations is to prevent and thwart attackers from launching exploits and malicious attacks against your systems and information. Microsoft over the years has implemented various exploit mitigations specifically targeted towards stopping overflow attacks and some of the techniques that advanced attackers may use to gain access to systems.

Exploit mitigation have always been a cat and mouse game because once a new technique is created to exploit something. A mitigation is created to prevent that, and for every mitigation that has been introduced, an exploits mitigation bypass has been discovered.

When applying exploit mitigations there is usually a very strict set of requirements that one should take since it just takes one bad module to break and ruin the security of the whole program. If an entire program has built-in mitigations, and then the author decides to add just one more DLL to it and forgets to protect that DLL, it renders the security of the program virtually useless. The purpose of applying exploit mitigation is to compensate for poor programming which leads to software vulnerabilities in a program.

In the very early years, Operating systems like Windows XP and Windows 2000s did not have any sort of exploit mitigations added to it. Attacks against these early systems were frequent and very easy to pull off. If you don’t use exploit mitigations, make sure to enable them and learn to check programs for mitigations.


NX bit/XD bit

The NX bit is a feature of the Memory Management Unit technology used in CPUs to mark different areas of memory as “non-executable”. The NX bit is also known as the XD (Execute Disable) bit which is marketed by supported Intel CPUs, whereas AMD CPUs will use the NX bit.

This is used as a prevention against attackers being able to inject malicious code/shellcode into another program and having it executed. By marking the stack as non-executable, you are blocking external code from being ran, this is common prevention against attacks like buffer overflows, where the goal is to write data onto the stack and have it be executed.


DEP (Data execution prevention)

DEP first started with Windows XP SP2 and Windows server 2003. Similar to the NX bit, DEP marks memory pages in the stack/heap as non-executable and raises an exception if an execution attempt occurs. But DEP also offers software-based DEP capabilities. DEP can also be hardware-based by setting the NX bit on an Intel processor-based system. DEP can also be manually set/disabled in the system properties settings. On Windows, the DEP settings are by default set to “only apply DEP to system programs”, as applying DEP to all the programs, including third-party software can sometimes lead to errors and failure. Software DEP is still supported even if hardware DEP is not. And software DEP only prevents SEH attacks from using SAFESEH.

A simple bypass to DEP is the ROP attack technique, which essentially is a code-re-use attack, where the attacker will call certain memory addresses that already reside in the program which can build a chain of code via the code being associated with its memory address. Essentially your using code that already exists in the program to create another program which disables DEP. With a “ROP-chain”, every “gadget” or splice of code ends in a RETN Assembly instruction, as it will return to the next gadget in the chain. ROP is one of the more common attacks used by exploit-developers and hackers since DEP and other mitigations that require a ROP chain bypass are the norm in today’s age.


Address Space Layout Randomization (ASLR)

With Windows Vista’s release, ASLR was added to the Windows NT operation system, ASLR is exploitation prevention & mitigation technique designed to protect against attacks from being able to access and locate memory address and other positions in the system that may be used for writing an exploit. ASLRs randomization prevents mainly against buffer overflow attacks to prevent against the attacker from being able to use an address of a gadget like JMP ESP, CALL ESP, or a POP POP RET sequence. (These are all commonly associated with buffer overflow attacks). Every time the program is reloaded, these memory addresses will change, making it much harder for the attacker to write an exploit since the attacker will not know what the real addresses are.

There are a few ways to bypass an ASLR implementation, the easiest method is to simply use non-ASLR protected loaded modules for the program. And on Vista and some older system, a partial EIP overwrite made it possible to bypass ASLR. Another ASLR attack is to attempt to brute-force the targeted address, but this method is very time and resource-intensive.


SafeSEH

SafeSEH was introduced with Windows XP SP2. The SafeSEH mitigation when enabled instructs the linker at compile time to build a table of trusted exception handler addresses. And SafeSEH won’t pass control to an address that is not on the table, for example: when you exploit a SEH buffer overflow you take control of a SEH handler addres and have it point back to your code. SafeSEH protects against that by not allowing addresses that are not in the SafeSEH table to pass control onwards.

SafeSEH can be enabled in Visual Studios via the /SAFESEH compile-time command. And in today’s age, over 99% of modern Microsoft programs and libraries are compiled to participate in SafeSEH, so if your ever viewing Microsoft DLLs or modules, everything will have the SafeSEH mitigation enabled.

The problem with all security mitigations usually lies in having third-party programs DLL’s, when third-party program modules do not have SafeSEH enabled it will destroy the security of the entire program, rendering all of the other SafeSEH protected modules somewhat useless. Since the most common “SafeSEH bypass” is to just use a module that does not have these security mitigations enabled.


Structured Exception Handling Overwrite Protection (SEHOP)

SEHOP will insert a special record at the end of the SEH chain which is known as the “FinalExceptionHandler” record inside of ntdll.dll. SEHOP will verify that the SEH chain for the current thread is intact before proceeding to the Next SEH handler by checking that it reaches that special record still exists. So before the SEH chain passes to the NSEH pointer, it will walk the full SEH chain to verify that the “FinalExceptionHandler” record still exists and if it doesn’t, the processes will be terminated.

SEHOP was added as exploit mitigation in Windows Server 2008 and Windows Vista, originally it was disabled by default. A good example to understand why SEHOP is implemented is that nn SEH exploitation, the POP/POP/RET technique that an attacker uses will break the SEH chain, so SEHOP will detect that breakage if it can’t reach the Final REcord it creates, which results in automatically kill the process if this is detected.


Visual C++ /GS check (Stack cookie)

/GS has been around since 2002. Using the /GS compile-time exploit mitigation will add either a 32bit or a 64-bit “stack cookie” onto the stack, these are also known as “stack canaries” or “security cookies”. It’s enabled by default in VS 2010 and later, so if your coding is VS your probably going to have cookies added to your program at compile time. The cookie is generated when the module is loaded into memory. If a stack cookie is overrun, it would kill the process, hence acting as exploit mitigation.

To bypass stack cookies, an attacker can attempt to leak/guess/calculate the value of the cookie so you can overwrite it with your buffer. Another exploitation bypass is to raise an exception before the stack cookie and to use that, but this does mean you will run into SafeSEH/SEHOP again.


Heap cookies

Heap cookies started in Windows XP SP2 and windows server 2003, they are 8 bits in length and provide up to 256 keys that are used to protect a block of memory. So, if you’re exploiting a heap corruption vulnerability, it would theoretically work 1/256 times. Heap cookies are added to each heap entry’s header. This heap cookie is validated when the heap entry is freed. This is why it’s made possible to detect corruption when a chunk is deallocated.


Supervisor Mode Execution Protection (SMEP)

SMEP was added in 2011 on the Ivy Bridge Intel CPU architecture. SMEP is a Windows kernel exploit mitigation that acts like DEP on a kernel level, where SMEP will allow memory pages to be protected from supervisor-mode instruction fetches. So if SMEP is enabled, SMEP = 1, then the software operating in supervisor mode is not able to get instructions from the user-mode. This will act as mitigation against something like kernel driver exploits where you will communicate to exploit the kernel from a user-mode perspective. SMEP will detect Ring-0 code running in user-space.

SMEP has been enabled by default since Windows 8.0 and is heavily implemented to protect against local privilege escalation exploits (EOP exploits).

Some SMEP bypass methods include jumping the kernel heaps or using a ROP chain in kernel space to disable SMEP.


Control Flow Guard/Integrity (CFG/CFI)

CFI was released on Windows 8.1 in November 2014, it’s now deployed in over 500 million devices worldwide. You can use the /guard:cf linker flag when compiling your program to add CFI security. CFG is widely implemented to protect and combat against memory corruption vulnerabilities by adding tight restrictions on where an application can run code from. CFG extends previous and older exploit mitigation techniques like /GS, DEP, and ASLR. CFG works to stop the redirection of code by restricting indirect calls, jumps and return addresses, which is used to thwart attackers from conducting attacks against the system by redirecting the programs code to their own malicious code. There are a few methods for a CFI bypass, an easy to understand attack is to simply use an indirect call that’s not been protected by CFI. Or you can sometimes overwrite the function call that CFG uses to validate the addresses from being redirected. But this method was patched in March 2015.


Enhanced Mitigation Experience Toolkit (EMET)

The EMET tool kit is a freeware toolkit released by Microsoft which allows a user to easily enable/disable a large variety of security mitigations for specific pieces of software that may not be protected by default by the Windows system. EMET is mainly targeted towards System engineers.

In the earlier versions of EMET, there have been a couple of of methods demonstrated which can be used to disable or bypass EMET. In EMET versions 2,3,4,5 and onwards, there have been exploiting bypasses for EMET. EMET works by injecting emet.dll or emet64.dll (depending on the current systems architecture) into every selected and protected process.


Kernel address space layout randomization (KASLR)

KASLR is a Kernel implementation of ASLR, where KASLR makes Kernel exploitation virtually impossible and extremely difficult as it makes it almost impossible to find addresses such as the base address of a kernel driver directly. Which makes kernel driver exploitation ridiculously hard. There has been research done to bypass KASLR, some of the methods include kernel address leaks to retrieve addresses that an attacker would need. On some older versions of Windows 10, there have been exploits that force a kernel leak via using the Win32ThreadInfo pointer from the Thread Environment Block (TEB), or by using the Desktop Heap. Since the Desktop Heap is mapped in user-mode, which allows an attacker to search it.


Kernel Patch Protection (KPP)

KPP is also known as PatchGuard, and KPP is a feature on 64bit Windows systems that include Kernel protection, KPP aims to stop unsupported modification of the parts of the kernel. On 64bit systems the Windows Kernel is designed so that Kernel drivers have the same set of privileges as the kernel, putting the driver in KernelLand, drivers are expected to not modify or patch core systems structures in the Windows kernel, so KPP acts as a preventative for that.

Microsoft has never been supportive of patching the Kernel because it can lead to a variety of obvious security flaws or errors. KPP protects against things like rootkits from gaining access to KernelLand because Kernel level rootkits are almost impossible to detect from a malware analyst’s point of view.

In 2007 there was a paper published by “Skywing” and “Skape” which showed that KPP was to some extent bypassable since the design of the Windows kernel is to not 100% prevent patching and modification. There have been other concerns about KPP and it’s reliability. Some bypasses include using exploits that hijack memory management data structures like the HalPrivateDispatchTable.


Conclusion

Throughout the years, Microsoft has added and changed many of their exploit mitigations, exploit mitigations are used to prevent attackers from having an easier time when exploiting a program or system. Common exploit mitigations that a security researcher will encounter will be DEP, ASLR, and a couple of the others on the top of this article, if you get into exploit development and specifically Windows kernel exploit development, you will start to deal with a kernel exploit mitigations like KASLR and SMEP/SMAP.

All of the Windows exploit mitigations are configurable, make sure that when you compile and run the programs on your computer, make sure to enable and utilize the various exploit mitigations that Microsoft provides.

Some of the more difficult to understand mitigations and Microsoft preventions are CFG, KALSR, and SMEP/SMAP. These are very complex and are widely implemented in very new systems, so the resources are fairly slim. These mitigations should be researched more in-depth by anyone who wants to write exploits that bypass those mitigations.

Updated:

Leave a Comment