Exploit techniques - a quick review


Published on

A quick summarization of major exploiting techniques based on Corelan Team's pubblications.

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Exploit techniques - a quick review

  1. 1. ===================================EXPLOIT TECHNIQUES - A QUICK REVIEW===================================Last Modify: 08/12/2011Author: luca.mella@studio.unibo.itThanks to Corelan Team :)*************************************************************************** jmp2reg based exploit *********************************************************************************************************************jump (or call) a register that points to the shellcode: With this technique, you basically use a register that contains the addresswhere the shellcode resides and put that address in EIP. You try to find the opcode of a jump or call to that register in one of thedlls that is loaded when the application runs. When crafting your payload, instead of overwriting EIP with an address inmemory, you need to overwrite EIP with the address of the jump to the register. Of course, this only works if one of the available registers contains anaddress that points to the shellcode. This is how we managed to get our exploit to work in part 1, so Im not goingto discuss this technique in this post anymore. [CLASSICAL]pop return : If none of the registers point directly to the shellcode, but you can see anaddress on the stack (first, second, address on the stack) that points to the shellcode, then youcan load that value into EIP by first putting a pointer to pop ret, or pop pop ret, or pop pop pop ret (all depending onthe location of where the address is found on the stack) into EIP.push return : this method is only slightly different than the call register technique. If you cannot find a <jump register> or <call register> opcode anywhere, youcould simply put the address on the stack and then do a ret. So you basically try to find a push <register>, followed by a ret [ ROPGADGET ? ]. Find the opcode for this sequence, find an address that performs thissequence, and overwrite EIP with this address. [NICE :D]jmp [reg + offset] : If there is a register that points to the buffer containing the shellcode,but it does not point at the beginning of the shellcode, you can also try to find an instruction in one of the OS or application dlls,which will add the required bytes to the register and then jumps to the register. Ill refer to this method as jmp [reg]+[offset] blind return : in my previouspost I have explained that ESP points to the current stack position (bydefinition). A RET instruction will pop the last value (4bytes) from the stack and willput that address in ESP. So if you overwrite EIP with the address that will perform a RET instruction,
  2. 2. you will load the value stored at ESP into EIP. If you are faced with the fact that the available space in the buffer (afterthe EIP overwrite) is limited, but you have plenty of space before overwriting EIP,then you could use jump code in the smaller buffer to jump to the main shellcode inthe first part of the buffer.========================================================================References: http://www.corelan.be/index.php/2009/07/23/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-2/*************************************************************************** SEH based exploit *************************************************************************************************************************TODO: no time to summarize it :(User exception handler in the stack: http://www.corelan.be:8800/wp-content/uploads/2009/07/image25.pngDetail on the exception handlers list (chain): http://www.corelan.be:8800/wp-content/uploads/2009/07/image45.pngSEH exploiting technique (keep in mind the ESP position for understanding it): http://www.corelan.be:8800/wp-content/uploads/2010/08/image13.png========================================================================References: http://www.corelan.be/index.php/2009/07/25/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-3-seh/*************************************************************************** Bypass ALSR+DEP - ROP based exploit *******************************************************************************************************Windows DEP options: OptIn : Only a limited set of Windows system modules/binaries are protectedby DEP. OptOut : All programs, processes, services on the Windows system areprotected, except for processes in the exception list AlwaysOn : All programs, processes, services, etc on the Windows system areprotected. No exceptions AlwaysOff : DEP is turned off. + MS Permanent DEP : uses SetProcessDEPPolicy(PROCESS_DEP_ENABLE) to make sureprocesses are DEP enabled.Windows DEP defaults: Windows XP SP2, XP SP3, Vista SP0 : OptIn Windows Vista SP1 : OptIn + Permanent DEP Windows 7: OptIn + Permanent DEP Windows Server 2003 SP1 and up : OptOut Windows Server 2008 and up : OptOut + Permanent DEPChange DEP behavior: XP and 2003 server via boot.ini parameter /noexecute=[OptIn|OptOut|AlwaysOn|lwaysOff] Vista/Windows 2008/Windows 7 via bcdedit command bcdedit.exe /set nx [OptIn|OptOut|AlwaysOn|AlwaysOff]Windows API functions for bypassing DEP VirtualAlloc(MEM_COMMIT + PAGE_READWRITE_EXECUTE) + copy memory : new
  3. 3. executable memory region, copy shellcode, execute HeapCreate(HEAP_CREATE_ENABLE_EXECUTE) + HeapAlloc() + copy memory SetProcessDEPPolicy() : Vista SP1, XP SP3, Server 2008, only if DEP Policy=OptIn|OptOut VirtualProtect(PAGE_READ_WRITE_EXECUTE) :change the access protection level of a given memory page WriteProcessMemory() : the target location must be writable and executableNOTE : Each one of those functions requires the stack or registers to be setup in a specific way. Parameters to the function are placed at the top of the stack (= atESP).Primary goal: craft these values on the stack, in a generic and reliable way,without executing any code from the stack itself.After crafting the stack, you will most likely end up calling the API. ESP mustpoint at the API function parameters. --------------------------------------------------------- | junk | | rop gadgets to craft the stack | |ESP-> function pointer (to one of the Windows APIs) | | junk (4 bytes) | | Function parameter | | Function parameter | | Function parameter | | Maybe some more rop gadgets | | nops | | shellcode | | more data on the stack | ---------------------------------------------------------At that time, a simple "RET" instruction will jump to that address. This will callthe function and will make ESP shift with 4 bytes.If all goes well, the top of the stack (ESP) points at the function parameters,when the function is called.Example:VirtualAlloc + memcpy. Part of crafted stack.. ---------------------------------------------------------------------------- [..] | Pointer to VirtualAlloc | ESP points here for start the call. | 4 bytes junk | Necessary because when entering inVirtualAlloc, VirtualAlloc will PUSH EIP. He think it is a regular call. | pointer to memcpy | Return address field of VirtualAlloc()).When VirtualAlloc ends, it will return to this address | lpAddress | arbitrary address (where toallocate new memory. Example 0×00200000) | size | (how big should new memoryallocation be) | flAllocationType | 0×1000 : MEM_COMMIT | flProtect | 0×40 : PAGE_EXECUTE_READWRITE | Arbitrary address | Return address for memcpy (same as
  4. 4. lpAddress). used to jump to shellcode after memcpy() returns. | 4 bytes junk | Necessary because when entering inmemcpy, memcpy will PUSH EIP. He think it is a regular call. | Arbitrary address | same address as lpAddress. Parameter herewill be used as destination address for memcpy(). | Address of shellcode | source parameter for memcpy(). | Size | size parameter for memcpy(). [..] ----------------------------------------------------------------------------NOTE ON PORTABILITY:It might be a good idea to verify if the application uses the function that youwant to use to bypass DEP, and see if you can callthat functions using an application/module pointer. That way, you can still makethe exploit portable, without having to generate thefunction address, and without having to hardcode addresses from an OS dll.SUMMARY - HOW TO:What technique? (Windows API) used to bypass DEP and what are the consequences in terms ofstack setup/parameters.What is the current DEP policy?What are the ROP GADGETS I can use ? (This will be your toolbox and will allow you to craft your stack.)How to start the chain? How to pivot to your controlled buffer ? (stack pivot) In a direct RET exploit, you most likely control ESP, so you can simplyoverwrite EIP with a pointer to RETN to kick start the chainHow will you craft the stack ? As seen before, we will need to pass a number of parameters to this function. These parameters need to sit at the top of the stack at the time the functiongets called. option 1) Put the required values in registers and then PUSHAD option 2) put some of the params (the static ones/the ones without nullbytes) on the stack already, use ROP GADGETS to calculate the other params andwrite them onto the stack.[ROP GADGET = any instruction followed by a RET] ---------------------------------------------------------------------------------- | | junk | | eip eg. points to a RETinstruction (or a stack pivot?) | | junk | | rop pointer to gadgets andat least jmp to syscall |ESP points here| parameters parameters that will be popped bysyscall | | more rop | | padding / nops | | shellcode | | junk ---------------------------------------------------------------------------------->>> ROP EXPLOIT EXAMPLE >>> [Watch picture @ http://www.corelan.be:8800/wp-content/uploads/2010/06/ropstructure1.png]
  5. 5. >>> Stage 1 : SAVE ESP and JMP over the parameters 2 of our VirtualProtect() function parameters need to point at our shellcode. payload is in the stack, so taking the current stack pointer and storing itin a register is smart. Advantages: 1) Easily add/sub the value the reg to make it point at yourshellcode. ADD, SUB, INC, DEC instructions are common. 2) Initial value points is pretty close to the stack address wherethe pointer to VirtualProtect() is located. 3) Close to the stack location of the parameter placeholders. "mov dword ptr ds:[register+offset],register" instruction tooverwrite the parameter placeholder. # PUSH ESP # MOV EAX,EDX # POP EDI # RETN ---> MOV ESP, EDI (EDI is uncommonregister, so this is a good place to store) # PUSH EDI # POP EAX # POP EBP # RETN ---> MOV EDI,EAX + POPJunk (old ESP = EDI = EAX) Now, jump over params with a gadget like # ADD ESP,20 # RETN>>> Stage 2 : crafting the first parameter of VirtualProtect() [return address] Shellcode is right after the nops... # ADD EAX,100 # POP EBP # RETN ---> ADD EAX,0x100 ; So eax = old ESP +0x100 ...hope will hit the nop sled # MOV DWORD PTR DS:[ESI+10],EAX # MOV EAX,ESI # POP ESI # RETN ---> writethis value onto the stack [..]>>> Stage 3 : crafting the second parameter (lpAddress = location that needs to bemarked executable) This means that we can - more or less - repeat the entire sequence from stage2, but before we can do this, we need to reset our start values. # PUSH EAX # POP ESI # RETN ---> EAX still holds the initial saved stackpointer. We have to put it back in ESI increase the value in EAX again (add 0x100) increase the value in ESI with 4 bytes [ # INC ESI # RETN (4 times)]>>> Stage 4 and 5 : third and fourth parameter (size and protection flag) The technique to write the resulting value as a parameter is exactly the sameas with the other parameters Save EAX into ESI Change EAX (XOR EAX,EAX : 0x100307A9, and then ADD EAX,100 + RET, 3times in a row : 0x1002DC4C) Increase ESI with 4 bytes Write EAX to ESI+0x10 The fourth parameter (0x40) uses the same principle again : Save EAX into ESI Set EAX to zero and then add 40 (XOR EAX,EAX + RET : 0x100307A9 /
  6. 6. ADD EAX,40 + RET : 0x1002DC41) Increase ESI with 4 bytes Write EAX to ESI+0x10>>> Final stage : jump to VirtualProtect All we need to do now is find a way to make ESP point to the location wherethe pointer to VirtualProtect() is stored. In this eample EAX already points at this address. #SUB EAX,4 # RET ---> just cause eax doesnt point directly @virtualprotect pointer # PUSH EAX # POP ESP # MOV EAX,EDI # POP EDI # POP ESI # RETN ---> MOVEAX,ESP ; GOGOGO!========================================================================References: https://www.corelan.be/index.php/2010/06/16/exploit-writing-tutorial-part-10-chaining-dep-with-rop-the-rubikstm-cube/*************************************************************************** Egg Hunting ******************************************************************************************************************************* Find shellcode into program memory and jump into it. TODO: no time to summarize it :(========================================================================References: http://www.corelan.be/index.php/2010/01/09/exploit-writing-tutorial-part-8-win32-egg-hunting/ https://www.corelan.be/index.php/2011/05/12/hack-notes-ropping-eggs-for-breakfast/