Memory corruption bugs continue to plague us in all kinds of software – they often at the core of headline breaches and dangerous zero-day vulnerabilities. Over the years various mitigation technologies was developed to address this problem, such as EMET – a free suite of protections from Microsoft.
What memory bugs?
In unsafe languages like C and C++ working with memory is a direct responsibility of a developer, so he must manually track all his memory usage throughout the program. And here lies the problem – people make mistakes. As you might imagine, in any kind of complex software there are thousands to millions of objects that require memory manipulation, so it’s a constant source of bugs. Let’s take a look at them:
Buffer-overflow – Those typically occur when developer fails to check the bounds of user input while allocating buffer for it. So, if my program asks you for a user name and I’m assuming it can’t be more than 30 characters and allocating corresponding buffer of that size, but not actually performing a check – buffer overflow will occur if you type user name which is more than 30 characters. Those type of bugs include stack based overflow, heap-overflow and off-by-one. The problem with this, is that overflowing buffer overwrite adjacent memory positions which include return address for stack and pointer positions for heap. Think of it as a metadata that contain information where control should be passed next. Attackers typically abuse this by passing some kind of shellcode(instructions written in assembly that usually spawn a command shell) as input and overwriting return address to point into location where shellcode is now stored, thus hijacking flow of application and executing arbitrary code.
Dangling Pointers – Those typically occur when developer tries to use already freed memory. This can lead to unexpected behavior of a program such as data corruption, memory leak, crash or arbitrary code execution. Attackers typically abuse this by replacing freed data with their own, thus hijacking flow of application and executing arbitrary code. This includes bugs like Use-after-free, Double Free and Null Pointer Dereference.
Type-confusion – Those typically occur when developer fails to verify type of the object that is passed to some piece of code. Since different types represented differently in memory this can lead to out-of-bound memory access and lead to crashes or in some cases, code execution. Also , this problem is not specific to unsafe languages and can occur even in memory safe languages, for example, those types of bugs is common in Flash and Java platforms.
Integer bugs – Those typically occur when developer work incorrectly with integer types. Such bugs includes integer overflow and signed\unsigned conversions. It can lead to data corruption, logic errors and sometimes to code execution.
What is EMET?
EMET is a suite of memory protection technologies, that helps prevent exploitation of memory corruption bugs. EMET will terminate the application instead of running the exploit code when it detected exploitation attempt. It allows the flexibility of per application configuration of various memory protection technologies. I believe it is used as a testbed by Microsoft for testing various mitigation technologies that will be later incorporated into OS. It can be deployed to the enterprise via GPO or SCCM, provide ability to configure Certificate Pinning for IE and provide dedicated event log where detected exploitation attempts will be logged.
Let’s take a look at mitigation’s.
DEP(Data Execution Prevention)
This technology prevent code execution from data memory pages. Idea is very simple, if data structures supposed to hold only data and not code – enforce this and don’t allow execution of code stored in data pages. What this means in practice, is that attacker can’t just insert his own shellcode into input and execute it. This technology actually is very old and already embedded into OS since Windows XP SP2, but default settings for this – is application opt in, which means application must be compiled with /NXCOMPAT flag to take advantage of this. Otherwise only system services and applications have this feature enabled. However, you could change this and enforce DEP for everything with or without EMET – It’s settings located under Advanced System Settings – > Performance Options.
There is also two versions of this feature – hardware based and software based. All modern AMD and Intel processors have a hardware assisted DEP feature called NX or xD bit, which implements a full DEP protection. If your processor does not support this feature, then you have only software DEP, which is protecting you only from attacks on SEH(basically it‘s a SafeSEH), more on this later.
Over the years various bypasses was developed:
- ret2libc(return to libc) – The idea is to use system functions that already loaded, such as system() to invoke shell. So, instead of using your own shellcode, you jump into already existing function and this allows you to bypass DEP, because those functions must be executable and they are completely legitimate. This is largely developed into what is known as ROP(Return-Oriented Programming), which is a technique to craft your shellcode with existing code in memory from various pieces(rop gadgets).
- Disable DEP – Since DEP is optional, there is exist an API that allows you to disable DEP for a process such as NtSetInformationProcess, SetProcessDEPPolicy, VirtualAlloc or VirtualProtect. This is a variation of ret2libc bypass, but instead of constructing shellcode in memory, you just look for those specific functions and mark your memory region with data as executable or disable DEP altogether.
ASLR(Address space layout randomization)
This technology actually is not preventing anything, but rather makes it difficult to develop reliable exploits. It is a good example of when security by obscurity actually works. To exploit a bug you need to jump to some kind of memory address with shellcode, same thing is required to bypass DEP, you need to jump to address with needed functions. Without randomization, those addresses are static and well-known, making bypassing DEP and creating reliable exploits trivial. ASLR was developed to combat this. It randomize base memory addresses of loaded libraries and positions of stack and heap, so even if you got an exploit working in your environment – it won’t work on another PC due to randomization. Default settings is also Opt In, which means application must be specifically compiled with /DYNAMICBASE flag to take advantage of this feature. ASLR is also more effective on 64-bit platform because virtual address space is bigger. With EMET you could enforce ASLR for everything.
There are a couple of ways to bypass it:
- Bruteforce – If ASLR entropy is small and bug is not making the application crash, you could try to bruteforce the needed memory addresses. NOP-sleds(large portion of NOP instructions that does nothing) can increase the chances here.
- Use non-ASLR module – Not everything in application could be compiled with ASLR protection, so you could take advantage of addresses from those modules.
- Memory leak – If you able to read memory via some kind of vulnerability, then you can figure out current memory layout and addresses. You need to chain this vulnerability with you actual exploit to bypass ASLR.
Exception handling is a common task in software development. In Windows there exist default exception handling mechanism known as SEH(structured exception handling), you certainly saw one before – it’s those errors with message “Application has stopped working”, which means application is not handled exception and default Windows handler kicked in. Every application exception handler is registered with SEH which itself stores them on stack. Bad guys found a way to abuse this in buffer-overflow attacks and to bypass certain protections. So, instead of overwriting return address, attacker trigger exception with buffer overflow and overwrite SEH handler with his shellcode, so when application tries to find a handler for certain exception it will run shellcode instead. There was couple of mitigations developed to combat this:
- SafeSEH – If application was compiled with this flag, it will provide a list of addresses that can be used as exception handlers for application. So, when SEH kicks in, it will check if address it tries to jump for handling an error is in fact in this list, if not – program will terminate without invoking exception handler. This is also what happens when you have only software based DEP.
- SEHOP – This feature check an integrity of SEH chain making sure whole chain can be walked before calling a handler. It works by checking last handler record and making sure this value could be reached before executing a handler, if not – application will terminate without calling a handler, which would be a case when you overwrite a SEH handler, thus breaking SEH chain integrity. This is an OS level protection and will work regardless if application support it or not, and it was part of the OS since Vista.
You could enforce this option with EMET.
Bypassing SafeSEH & SEHOP
There are a couple of known bypasses for this:
- Use non SafeSEH module – you could use addresses from modules that is not compiled with SafeSEH.
- Use addresses outside a module range – if handler pointer is outside of current module memory range, it is considered safe and will be executed.
- SEHOP – there are couple of bypasses, here and here but it’s pretty good otherwise.
EMET also include additional memory protections besides major ones we looked at:
Let see what they are:
NullPage – This protection pre-allocates memory page at null ( 0 or 0x00000000 ) address to prevent null dereference attacks.
HeapSpray – This protection pre-allocates memory pages at addresses commonly used for spraying the heap (like 0x0a0a0a0a or 0x0c0c0c0c), thus preventing usage of them for delivering shellcode. Please note this is NOT a general heap spray mitigation.
EAF/EAF+(Export Address Table Access Filtering) – This protection filter read/write access to export address table from shellcode. This is a table which contain addresses of system libraries like ntdll.dll and kernel32.dll which is needed if shellcode invoke some kind of system API. EAF+ is an extension to that and contains additional checks that can be used independently. Unfortunately, I wasn’t able to find more details how exactly does it work.
MandatoryASLR/BottomASLR – ASLR, we already covered that.
ASR(Attack Surface Reduction) – This protection allows you to deny loading certain DLLs into certain processes. Like deny loading of flash in IE or Word. Would be handy against stuff like BadWinmail.
There is also quite a few aimed to prevent ROP-based exploits:
LoadLibrary – This protection prevent loading libraries via LoadLibrary API from UNC path(like \\hacker\1.dll)
MemProt – This protection prevent making stack executable, i.e. via VirtualProtect.
Caller – This protection prevent invoking critical functions via RET instruction. I wasn’t able to find what those critical functions are, but probably stuff like VirtualAlloc, VirtualProtect, ShellExecute, CreateProcess etc.
SimExecFlow – This protection detect ROP gadgets by simulating execution flow after RET. I wasn’t able to find details, I guess it tries to detect if you chaining multiple RETs to contstruct a rop gadget chain or something similar.
Stack Pivot – This protection detect if stack is being pivoted. Stack pivot is basically allows you to construct a fake stack structure redirecting flow from real stack into fake stack filled with rop gadgets.
There is also a couple of additional protections that developers could use:
Applications compiled with /GS flag will be protected with additional feature called stack cookie(or canary), that insert a random value in application which is then copied into stack just before the return address. So, application would check this value with generated at run-time and if there is no match – the program will terminate. It’s aimed to prevent buffer-overflow attacks, since they typically overwrite cookie too.
Bypassing stack cookies
SEH – Exceptions is not affected by this feature, so if you can trigger exception before cookie is checked, then you could bypass it and develop SEH-based exploit.
Insert your own – If you able to overwrite cookie value via some kind of vulnerability, then obviously you could replace it with your own value and add it to your own shellcode to have it validated.
Bruteforce – If cookies is not really random or just static, you could try to bruteforce it’s value.
Control Flow Guard
In Windows 10 and Windows 8.1 Update 3 there is new kind of mitigation is available. Applications compiled with /guard:cf flag will be protected with Control Flow Guard feature. Idea is to build a list of indirect calls that can be reached by application ahead of time and validate all indirect calls at runtime against this list, if check is failed – application will terminate, basically making sure that control flow of application is not altered. Most of the exploits hijack normal flow of applications and jump to unexpected location, thus they will trigger this protection.
EMET in action
Let’s see EMET in action. I will be using infamous Hacking Team Adobe Flash Use-after-free(CVE-2015-5119) exploit for demo with Firefox 44 and vulnerable flash player on Windows 7. Why? Well, it was quickly adopted by APT and cyber crime groups alike, so it will be interesting to look in retrospect, if it could be prevented by EMET as true 0day.
We’re going to use a fake Twitter web site with malicious iframe to simulate a strategic web compromise aka watering hole attack on a target, similar how it was used in the wild by APT groups.
Here is our victim visiting our Twitter page:
And we got him:
Now let’s install EMET, use maximum protection and add flash and firefox into protected processes:
Let’s see if EMET would prevent this exploit:
Flash crashed before exploit code was run and here is what attacker is seeing:
So exploit didn’t work and was successfully prevented by EMET! Impressive, isn’t it?
Considering it is a zero-day for this particular machine and it is running absolutely no defenses other than EMET.
It also should show a notification and log a record in Event Log, but for some reason it didn’t in my case. Here how those typically look:
Be aware that you need to specifically add your applications and plugins that must be protected with EMET, otherwise only a small amount of apps is covered. It also sometimes produce false-positives and crash applications, so test thoroughly with your apps before deploying it. I recommend to protect all applications that work with external data with EMET, such as:
Office suites and PDF readers
Video and music players
There is also a similar product from Malwarebytes called Anti-Exploit, which also have a free version.
I decided to try it as well:
It also worked without problems and successfully prevented exploitation.
Is EMET a 100% solution against zero-day exploits? Of course not, it was bypassed in the past and no software is perfect, so it could be bypassed in the future. But it also proven to work and definitely raising a bar for attackers, so I highly recommend to take advantage of this software.