Presentation is loading. Please wait.

Presentation is loading. Please wait.

Bypassing MS Windows Memory Protections Shahriyar Jalayeri 1 st Iranian Confrence on Cybespace Security Incidents and Vulnerabilities.

Similar presentations


Presentation on theme: "Bypassing MS Windows Memory Protections Shahriyar Jalayeri 1 st Iranian Confrence on Cybespace Security Incidents and Vulnerabilities."— Presentation transcript:

1 Bypassing MS Windows Memory Protections Shahriyar Jalayeri Shahriyar.j@gmail.com 1 st Iranian Confrence on Cybespace Security Incidents and Vulnerabilities

2 Who am I ? Security researcher since 2005 Senior Member of Snoop Security Researching community Writer and Technical Editor of Snoop Magazine ( First Persian Technical Information Security Magazine ) University student

3 What is this talk about? Overview of Softwares Security Flaws Deep looking at OS protection mechanismes Explaining ways to bypass some of OS PM

4 Security Flaws Stack Based Buffer Overflow Heap Based Buffer Owerflow Format String etc

5 Stack Based Buffer Overflow an old story  – Programer Copy Buffer entry into stack without bound checking – Stack corrupted and FramePointer+Saved Return Address overwritten – The BAD ret Instruction

6 Stack Based Buffer Overflow ( Cont. ) – Stack.c #include Int main( int argc, char **argv){ char buff[100]; strcpy(buff,argv[1]); printf(“Hello, %s!\n”,buff); return 0; } Overflow occured here

7 Stack Based Buffer Overflow ( Cont. ) Args ---------------------- Saved Ret ---------------------- Saved FP ---------------------- B U F E R Stack Layout 0xHighMemAddr 0xLowStackAddr Args ---------------------- Saved Ret ---------------------- Saved FP ---------------------- B U F E R 0xLowMemAddr 0xHighStackAddr AAAAAAAAAAAAAAAAAAAAAAAA Overflow

8 Stack Based Buffer Overflow ( Cont. ) – The BAD ret instruction ( and also leave :D ) 004012DC |. 83C4 10 ADD ESP,10 004012DF |. C9 LEAVE 004012E0 \. C3 RETN Args ---------------------- Saved Ret ---------------------- Saved FP ---------------------- B U F E R EIP Boom AAAAAAAAAAAAAAAAAAAAAAAA Overflow

9 Heap Overflow – Heap Structure LIST_ENTRY Structure ( WinNT.h ) FreeList array – Pointer to free heap blocks typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;

10 Heap Overflow ( cont. ) – Heap.c HANDLE h = HeapCreate(0, 0, 0); DWORD vulner(LPVOID str) { LPVOID mem = HeapAlloc(h, 0, 128); // strcpy(mem, str); // LPVOID mem2 = HeapAlloc(h, 0, 128); // return 0; } Overflow Affected Memory

11 Heap Overflow ( cont. ) – Freeing Scenario and Pointers ( without Safeunlinking ) BOOLEAN RemoveEntryList(IN PLIST_ENTRY Entry) { PLIST_ENTRY Blink; PLIST_ENTRY Flink; Flink = Entry->Flink; // what Blink = Entry->Blink; // where Blink->Flink = Flink; // *(where) = what Flink->Blink = Blink; // *(what+4) = where return (BOOLEAN)(Flink == Blink); }

12 Heap Overflow ( Cont. ) – Freeing Scenario and Pointers ( without Safeunlinking ) Disass... – Exploitation Scenario mov dword ptr [ecx],eax mov dword ptr [eax+4],ecx EAX - Flink ECX - Blink ECX = Function Pointer EAX = Instruction which transfer execution to shellcode

13 Heap Overflow ( Cont. ) – Function pointers which can overwrite during unlinking ( ECX ) Unhandled Exception Filter Vector Exception Handling ( VEH ) PEB Pointers TEB Pointers Your own pointer !

14 Format String – Using format specified functions in wrong way Printf(buffer) – We are able to overwrite arbitrary address Mentioned pointers can be good target Saved Return Address !!!

15 Memory Protections Protections against buffer overflow – Guard Stack ( a.k.a /GS ) – Data Execution Prevention ( a.k.a DEP or /NXCOMPAT ) – Safe SEH Table ( a.k.a /SafeSEH ) – SEH Overwrite Protection ( a.k.a SEHOP ) – Address Space Layout Randomization ( a.k.a ASLR or /DYNAMICBASE )

16 Guard Stack ( /GS ) Protection – Compiler Insert Cookie after Function Stack Frame – There is also a copy of cookie in.data section – Before function return cookie check with.data saved cookie – If dose not match, Ret instruction never execute – In overflow situation we have to overwrite cookie befor reaching “Saved Return Address” – Now what ?

17 Guard Stack ( /GS ) Protection ( cont. ) Memory Layout Parameters Return Address Frame Pointer Locals Parameters Return Address Frame Pointer Exception Handler Frame Locals Parameters Return Address Frame Pointer Exception Handler Frame Locals Safe Parameters Cookie (1) (2) (3) (1)Without Cookie (2)MSVC++ 2003 (3)MSVC++ 2005

18 Guard Stack ( /GS ) Protection ( cont. ) – Q : What is Safe Parameters ? – A : Function pointer overwrite prevention trick – Prevention is better than cure :D #include int main(int argc, char *argv[]){ HMODULE Lib=NULL; unsigned int FuncAddress = 0; int err = 0; Lib = LoadLibrary("msvcrt.dll"); FuncAddress = GetProcAddress(Lib,"printf"); err = DoStuff(argv[1],FuncAddress); return 0; } int DoStuff(char *buf, FARPROC fnk){ char buffer[20]=""; strcpy(buffer,buf); (fnk)(buffer); __asm add esp,4 return 0; }

19 Guard Stack ( /GS ) Protection ( cont. ) – When /GS dose not protect your Code ? The optimization (O) option is not enabled The function does not contain a stack buffer The function is marked with naked in C++ The function has a variable argument list The function begins with inline assembly code The compiler determines that the function’s variables are used only in ways that are less likely to be exploitable

20 Guard Stack ( /GS ) Protection ( cont. ) – Implementation ___security_init_cookie() Protected function prologue changes Protected function epilogue changes __security_check_cookie() ___report_gsfailure()

21 Guard Stack ( /GS ) Protection Reversing in Action Just trigger IDA

22 /GS Reversing – ___security_init_cookie() Security Init Cookie void __cdecl __security_init_cookie(void){ UINT_PTR cookie; if (__security_cookie != DEFAULT_SECURITY_COOKIE && (__security_cookie & 0xFFFF0000) != 0 ){ __security_cookie_complement = ~__security_cookie; return; } GetSystemTimeAsFileTime(&systime.ft_struct); cookie = systime.ft_struct.dwLowDateTime; cookie ^= systime.ft_struct.dwHighDateTime; cookie ^= GetCurrentProcessId(); cookie ^= GetCurrentThreadId(); cookie ^= GetTickCount(); QueryPerformanceCounter(&perfctr); cookie ^= perfctr.LowPart; cookie ^= perfctr.HighPart; if (cookie == DEFAULT_SECURITY_COOKIE){ cookie = DEFAULT_SECURITY_COOKIE + 1; } else if ((cookie & 0xFFFF0000) == 0){ cookie |= cookie << 16; } __security_cookie = cookie; __security_cookie_complement = ~cookie; }

23 UINT_PTR cookie_temp_storage,cookie_global; cookie_temp_storage = 0xCCCCCCCC; cookie_temp_storage = __security_cookie; // cookie_temp_storage = cookie_temp_storage ^ EBP; // cookie_global = cookie_temp_storage; __asm { xor cookie_temp_storage, ebp mov dword prt [ebp-4],cookie_temp_storage } /GS Reversing – Protected function prologue changes Prologue

24 cookie_temp_storage = cookie_global; // cookie_temp_storage = cookie_temp_storage ^ EBP; __asm{ xor cookie_temp_storage, ebp } __security_check_cookie(); /GS Reversing – Protected function eplilogue changes Epilogue

25 void __security_check_cookie(){ if ( cookie_temp_storage == __security_cookie ) return; __report_gsfailure(); } /GS Reversing – __security_check_cookie() Memory Protections

26 void __report_gsfailure(){ // rise an fake exception // saving the contex record codes skiped :D GS_ContextRecord.ContextFlags = CONTEXT_CONTROL; GS_ExceptionRecord.ExceptionAddress = (PVOID)(ULONG_PTR)GS_ContextRecord.Eip; GS_ExceptionRecord.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN; GS_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; cookie[0] = __security_cookie; cookie[1] = __security_cookie_complement; if ( IsDebuggerPresent() ) _CRT_DEBUGGER_HOOK(_CRT_DEBUGGER_GSFAILURE); SetUnhandledExceptionFilter(NULL); UnhandledExceptionFilter((EXCEPTION_POINTERS *)&GS_ExceptionPointers); TerminateProcess(GetCurrentProcess(), STATUS_STACK_BUFFER_OVERRUN); } /GS Reversing – ___report_gsfailure() Report Gs Failure

27 – Puting shellcode into buffer – Overwrite EXCEPTION_REGISTRATION Next = jump to shellcode Handler = call [ebp+30] or pop,pop,ret or... – Causing an exception before coockie check – BOOOOM!!! Defeating /Gs Scenario

28 – When exception occured os call _except_handler() function – The location of handler function is store into stack by EXCEPTION_REGISTRATION structure ( E_R ) – Os find address of first regsiter E_R by accessing to fisrt 4 byte of thread TEB – OS access to TEB through fs register – Fs[0] alwayes point to first installed E_R in TEB Exception Handling Overview typedef struct EXCEPTION_REGISTRATION{ EXCEPTION_REGISTRATION *next; PEXCETION_HANDLER *handler; }EXCEPTION_REGISTRATION, *PEXCEPTION_REGISTRATION;

29 – There is chain of E_R structures in stack – If one hanlder faild to handle exception, chain traversealed to find a proper handler Exception Handling Overview ( cont. )

30 – We can control value of both next and handler elements of a registerd E_R – Overwiting handle with shellcode address and cusing an exception,then boom ??? No !!! There is some problems  – If handler address is in stack, handler never execute – If handler address is in heap, handler execute » Finding writeable heap address in stack overflow situation is usualy impossible  Now what ? Abusing registered E_R

31 – Rules are implemnted just for handler, we still have control over next pointer – Secund parameter of _except_handler() function which is EstablisherFrame point to curent EXCEPTION_REGISTRATION frame – We can access to this address by poping off two value from stack and then returning to it : pop,pop,ret – There is also other instructions which work same as pop,pop,ret sequence, such as : Call dword ptr[ebp+30] Jmp dword ptr [esp+8] Abusing registered E_R ( cont. )

32 – Our attack scenario : – Puting shellcode into buffer – Overwriting handler with pop,pop,ret instructions – Overwriting next with jump to the buffer – Cuasing an exception – Boom !!! – But there is another problem : /SafeSEH  Abusing registered E_R ( cont. )

33 – Create a table of safe handlers – Compare each handler value with table values – If handler value is in safe table, handler excecute – If not, go to treminate process with STATUS_STACK_BUFFER_OVERRUN flag /SafeSEH Protection

34 – If program doesnt compile with /SafeSEH every handlers are valid and execute – If handler address is in module which doesnt handle with /SafeSEH, handler execute – If handler address is outside of loaded module, handler execute /SafeSEH Protection Weaknesses

35 Bypassing /GS, /SafeSEH attack scenario Target : Vista SP1 EN XP SP3 EN NOP Shellcode Return Address 0x41414141 Jmp to Jmp 0xbuffer Handler Jump to Buffer instructions Adress of Pop,Pop,Ret or Call dword ptr [ebp+30] instruction

36 Bypassing /GS, /SafeSEH Protection in Action Just trigger debuuger

37 – In this case we can use 0x00 in data – If can’t ? Find address for pop,pop,ret which dosen’t contain 0x00 Put shellcode after overwrited E_R Overwrite next with jmp forward to shellcode Boom! /GS Null Byte problem

38 – Data Execution Prevention (DEP) is a system-level memory protection feature that is built into the operating system – DEP enables the system to mark one or more pages of memory as non-executable – DEP prevents code from being run from data pages such as the default heap, stacks, and memory pools – If an application attempts to run code from a data page that is protected, a memory access violation exception occurs – if the exception is not handled, the calling process is terminated Data Execution Prevention

39 – Hardware-enforced DEP enables the NX bit on compatible CPUs, through the automatic use of PAE kernel in 32-bit Windows – The NX bit ( XD/EVP), which stands for No eXecute, is a technology used in CPUs to segregate areas of memory for use by either storage of processor instructions or for storage of data – Physical Address Extension (PAE) is a feature of x86 and x86-64 processors that enable the use of more than 4 gigabytes[1] of physical memory to be used in 32-bit systems – In traditional 32-bit protected mode, x86 processors use a two- level page translation scheme, where the control register CR3 points to a single 4 KB long page directory, which is divided into 1024 × 4 byte entries – The NX bit flag in the page directory, in bit 63, to mark pages as "No eXecute" – Similat technologies : W^X, PAX, Exec Shield Data Execution Prevention ( Implementation )

40 – Software DEP, while unrelated to the NX bit, is what Microsoft calls their enforcement of "Safe Structured Exception Handling“ – Software DEP/SafeSEH simply checks when an exception is thrown to make sure that the exception is registered in a function table for the application – requires the program to be built with it Data Execution Prevention ( Implementation Cont. )

41 – OptIn: DEP is enabled by default for limited system binaries and programs that "opt in". With this option, only Windows system binaries are covered by DEP – OptOut: DEP is enabled by default for all processes. A list of specific programs that should not have DEP applied can be entered using the System dialog box in Control Panel. – AlwaysOn: This setting provides full DEP coverage for the whole system. All processes always run with DEP applied. The exceptions list to exempt specific programs from DEP protection is not available. – AlwaysOff: This setting does not provide any DEP coverage for any part of the system, regardless of hardware DEP support. Data Execution Prevention (Configuration )

42 – The very easy way Using newly added DEP related API – SetProcessDEPPolicy Fucntion – Thr easy way: Filling buffer with shellcode Calling NtSetInformationProcess with Desire parameters to disable DEP for Current Process Jumping into buffer ( jmp esp) – The hard way : Filling buffer with shellcode Making a page RWX by calling VirtualAlloc function Copying Shellcode to RWX memry region through calling memcpy Jumping to RWX memory region Bypassing DEP Scenario

43 – We can change DEP policy for spesific process at run-time. – We will use SetProcessDEPPolicy with desire parameters setting dwFlags to 0 disables DEP for the process – Jump back to shellcode The very easy way BOOL WINAPI SetProcessDEPPolicy( DWORD dwFlags );

44 Finall attack scenario The very easy way Target : XP SP3 EN NOP Shellcode Return Address SetProcessDEPPolicy Shellcode addr 0x00000000

45 Bypassing DEP Protection ( very easy way ) in Action Just trigger debugger

46 – We can change DEP policy for spesific process at run-time. – LdrpCheckNXCompatibility determine whether or not NX support should be enabled for the process – As a result of these checks, NX support is either enabled or disabled through a new PROCESSINFOCLASS named ProcessExecuteFlags (0x22). – When we calling NtSetInformationProcess 4 byte bit-mask parameter push to the buffer as parameter for MmSetExecuteOptions – MmSetExecuteOptions perform appropriate operation to set the executio flag – Parameters which we can pass to NtSetInformationProcess are : MEM_EXECUTE_OPTION_ENABLE ( 0x1 ) MEM_EXECUTE_OPTION_DISABLE (0x2 ) – So,all we have to do is calling NtSetInformationProcess with mentioned parameters for current process at the overflow time The easy way

47 Take a quick look at NtSetInformationProcess : We can find NtSetInformationProcess Calling with desire parameters in a few dlls, such as : ntdll.dll, acgenral.dll,.... In exploit code i use ntdll instruction sequence becaus : – is more interesting than direct call in acgenrall.dll.... – Maybe our program dosnt load acgenral.dll... For acgenral.dll call,Just search this sequence of byte in selected dll by msfpescan: – Msfpescan –r "\x6A\x04\x8D\x45\x08\x50\x6A\x22\x6A\xFF“ The easy way ( cont. ) NtSetInformationProcess( NtCurrentProcess(), // (HANDLE)-1 ProcessExecuteFlags, // 0x22 &ExecuteFlags, // ptr to 0x2 sizeof(ExecuteFlags)); // 0x4 push 4;lea eax, [ebp+arg_0];push eax;push 22h;push 0FFFFFFFFh

48 IDA View :D The easy way ( cont. )

49 Finall attack scenario The easy way Target : XP SP3 EN NOP Shellcode Return Address NtSetInformationProcess Some Pad NtSetInfo Return Address Jump to Buffer

50 Bypassing DEP Protection ( easy way ) in Action Just trigger debugger

51 – calling VirtualAlloc function as return address and allocate commited memory with RWX protection mode – set flAllocationType to MEM_COMMIT – And flProtect to PAGE_EXECUTE_READWRITE The Hard way LPVOID WINAPI VirtualAlloc( __in LPVOID lpAddress, __in SIZE_T dwSize, __in DWORD flAllocationType, __in DWORD flProtect );

52 – After VirtualAlloc returned, we call memcpy and copy shellcode into allocated RWX memory region – set dest to Allocated unit by VirtualAlloc – And scr to shellcode address in buffer – Trick : You can also call VirtualProtect to make shellcode location executable ( no memcpy needed ) The Hard way ( cont. ) void *memcpy( void *dest, const void *src, size_t count );

53 – VirtualAlloc function has __cdecl calling convention – So,Calling function pops it’s the arguments from the stack – What we have to do if we want to call another function which has calling convention that not clear stack after call ? – We can use pop,ret instruction The Hard way ( cont. ) Pop reg ret N time N = function arguments count

54 Finall attack scenario The hard way Target : XP SP3 EN Shellcode VirtualAlloc Memcpy Mem Addr Shellcode Size MEM_COMMIT PAGE_EXECUTE_READWRITE Mem Addr Shellcode Addr Mem Addr Shellcode Size Saved Return Address

55 Bypassing DEP Protection ( hard way ) in Action Just trigger debuuger

56 – In this case we can use 0x00 in data – If can’t ? Use swquence of functions which dosent need 0x00 in arguments Use NtSetInformationProcess method which dosnt need any null byte DEP Null Byte problem

57 – In Windows Vista, NX cannot be disabled once turned on for a process – now? If can use null byte, VirtualAlloc+memcpy or VritualProtect functions are handy ! ( without ASLR, in browser exploitation also with ASLR ) If cant, i dont know the asnwer... DEP Vista problem

58 – ASLR randomizes the location of images (PE files mapped into memory), heaps, stacks,the PEB and TEBs – When a new address is being selected as an image base for an executable, a random delta value – is added to or subtracted from the ImageBase value in the executable's PE header – This delta value is calculated by taking a random 8-bit value from the RDTSC counter and multiplying it by 64KB Address Space Layout Randomazation

59 – Heap Randmoazation 5-bit random value is generated multiplied by 64K This value used as an offset from the base address returned by the NtAllocateVirtualMemory Address Space Layout Randomazation ( cont. )

60 – Stack Randmoazation base of the stack is chosen randomly offset into the initial page where the stack starts getting used is also chosen at random Address Space Layout Randomazation ( cont. )

61 – Heap Spray Allocating larg amount of heap blocks Filling Heap Blocks withNop and Shellcode Use randomly address base on allocated units base address and 64kb alignment Filling buffer with return address JavaScript !!! Browser dependent limitation ( or every progarm which allow us to make big block of heaps) Bypassing ASLR Scenario

62 Memory Protections Demo HeapSpray Technique

63 – IE disallow address which contain non-ascii bytes – Address most be taken base on heap blocks count – Using ascii sequnce address are highly recommend – Address such as : 0x05050505, 0x0d0d0d0d, 0x0a0a0a0a – You can also use Heap-Feng-Shui method instead of HeapSpray Heap Spray notes

64 Bypassing ASLR Protection in Action Just trigger debugger

65 – FinalExceptionHandler function in NTDLL.DLL is registered as the first exception handler in all theads – As additional exception handlers are registered, they form a linked list with the last record always pointing to FinalExceptionHandler – The exception dispatcher walks this linked list and verifies that the last record still points to that Function – If an attacker overwrites the Next field of an exception handler record, the validation loop will not reach the last record and the SEH chain corruption will be detected SEH Overwrite Protection ( SEHOP )

66 – Skape offer ( current implementation is abit diff ) SEHOP ( Implementation ) CurrentRecord = fs:[0]; ChainCorrupt = TRUE; while (CurrentRecord != 0xffffffff) { if (IsInvalidAddress(CurrentRecord->Next)) break; if (CurrentRecord->Next == ValidationFrame) { ChainCorrupt = FALSE; break; } CurrentRecord = CurrentRecord->Next; } if (ChainCorrupt == TRUE) ReportExploitationAttempt();

67 – Exist theory One potential way to bypass this protection is to point the overwritten Next pointer to a fake SEH record that points to the FinalExceptionHandler function. However, the ASLR implementation inVista randomizes the address of the function and makes it impossible to for an attacker to terminate the SEH chain unless they have a way to bypass ASLR – My theory SEHOP bypassing theories

68 – /Gs, /SafeSEH – /Gs, /SafeSEH, DEP – ASLR, DEP – /Gs, /SafeSEH, ASLR, DEP Combined Protections Bypassing Scenarios

69 Bypassing Combined Protection in Action Just trigger debugger

70 Question ? Thank you for attending


Download ppt "Bypassing MS Windows Memory Protections Shahriyar Jalayeri 1 st Iranian Confrence on Cybespace Security Incidents and Vulnerabilities."

Similar presentations


Ads by Google