Over The Flow (Part 4)


In this post is the final and last post from the Over The Flow Series (you have to read and understand all previous 3 posts to figure out what is going on here). I will finally insert and execute a shell-code in our vulnerable application. But in this article we will also do further analysis on the SEH exploitation and I will try to fully describe exactly what happened in order to gain a remote shell. But first we should be the appropriate music: 

Note: Paranoia niiiiiiiiice music FYI.


To understand all the shit I’ll try to explain you, you should fulfill the following requisites:
  1. Basic X86 assembly.
  2. Debugging with ollydebug.
  3. Basic knowledge of exploitation basics in structured exception handling.
Note: Of course you would also have to read the previous three parts

Again a little about Structured Exception Handling  (as a reminder)

The Structured Exception Handler (SEH) is used to handle exceptions within Windows programs. Every process that an Operating System (OS) has is provided with a SEH capability, and when a Windows program generate an exception that it cannot handle itself, control is passed to a SEH address which contains the code that can be used to show a dialog box explaining that the program has crashed or to pass control to a debugger if one is running. When control from our original exception was passed from the debugger back to vulnerable server , the windows exception handler was actually involved in mediating the process. The fact that the windows exception handler become involved in this process allows some additional protections against SEH exploitation to be added, which we have to learn to work around when performing SEH overwrites on certain versions of Windows. 

SEH is an exception handler (from famous Corelan Team)

An exception handler is a piece of code that is written inside an application, with the purpose of dealing with the fact that the application throws an exception.  A typical exception handler looks like this :

try { //run program }
catch { //catch exception } 

Note: The syntax is very easy to understand, it is like any other exception handling.

I quick conceptual representation looks like that:

Note: "Address of exception handler" is just one part of a SEH record – the image above is an abstract representation, merely showing the various components

Windows has a default SEH (Structured Exception Handler) which will catch exceptions. If Windows catches an exception, you’ll see a “xxx has encountered a problem and needs to close” popup. This is often the result of the default handler kicking in.  It is obvious that, in order to write stable software, one should try to use development language specific exception handlers, and only rely on the windows default SEH as a last resort.

When using language EH’s, the necessary links and calls to the exception handling code are generated in accordance with the underlying OS and when no exception handlers are used, or when the available exception handlers cannot process the exception, the Windows SEH will be used (UnhandledExceptionFilter).  So in the event an error or illegal instruction occurs, the application will get a chance to catch the exception and do something with it. If no exception handler is defined in the application, the OS takes over, catches the exception, shows the popup (asking you to Send Error Report to MS).

In order for the application to be able to go to the catch code, the pointer to the exception handler code is saved on the stack (for each code block). Each code block has its own stack frame, and the pointer to the exception handler is part of this stack frame. In other words : Each function/procedure gets a fixed stack frame. If an exception handler is implemented in this function/procedure, the exception handler gets its own stack frame.  Information about the frame-based exception handler is stored in an exception_registration structure on the stack.

This structure (also called a SEH record) is 8 bytes and has 2 (4 byte) elements :
  1. A pointer to the next exception_registration structure (in essence, to the next SEH record, in case the current handler is unable the handle the exception).
  2. A pointer,  the address of the actual code of the exception handler. (SE Handler). 
Simple stack view on the SEH chain components :

Note: At the top of the main data block (the data block of the application’s “main” function, or TEB (Thread Environment Block) / TIB (Thread Information Block)), a pointer to the top of the SEH chain is placed. The bottom of the SEH chain is indicated by 0xFFFFFFFF. If the bottom of the SEH is reached then improper termination of the program will be triggered (and the OS handler will kick in).

More on SEH exploitation 

In the previous tutorial post, I have explained the basics of SEH based exploits. I have mentioned that in the most simple case of an SEH based exploit, the payload is structured like this :

[Junk] [next SEH] [SEH] [Shellcode]

I have indicated that SEH needs to be overwritten by a pointer to “pop pop ret” and that next SEH needs to be overwritten with 6 bytes to jump over SEH. You have to look to all registers, work with breakpoints, etc, to see where your payload / shellcode resides… look at your stack and then build the payload structure accordingly.

The vulnerable program stack

Initially when the stack of the program we are trying exploit (the Qualcomm WorldMail v3.0 stack) looks like that: 

Note: The stack of the program before we try to exploit it. No malicious string insertion is applied in the stack displayed above.

Normally, the pointer to the next SEH record contains an address. But in order to build an exploit, we need to overwrite it with small jumpcode to the shellcode (which should sit in the buffer right after overwriting the SE Handler).  The pop pop ret sequence will make sure this code gets executed.

In other words, the payload must do the following things:
  1. Cause an exception. Without an exception, the SEH handler (the one you have overwritten/control) won’t kick in.
  2. Overwrite the pointer to the next SEH record with some jumpcode (so it can jump to the shellcode).
  3. Overwrite the SE handler with a pointer to an instruction that will bring you back to next SEH and execute the jumpcode.
  4. The shellcode should be directly after the overwritten SE Handler. Some small jumpcode contained in the overwritten “pointer to next SEH record” will jump to it).

Using Metasploit and Olly to overwrite SEH and Next SEH

In order to overwrite the Wordlmail v3.0 SEH and Next SEH I am going to use the very well known tools found in metasploit the pattern_create.rb and pattern_offset.rb and an OllyDebug plugin that can identify binaries with no Safe SEH enabled found here. After we carefully examine the binary for our good luck we can see that the executable of the server is unprotected and therefore can be used to identify a PPR jump and a SEH address. But first lets check how can we overwrite the SEH and NextSEH addresses.

Step 1:First we run ./pattern_create.rb 1500

Note: The length of the buffer was identified in previous posts.

The generated pattern is this:


Step 2: We then insert that to our python code and inject that to the  running application:

Note: Take note that the in the buffer I added at the end the } character (which translate to \x7d in hex), so as to trigger the exception.  

Step 3: Start thew IMAP server from the services:

 Step 4: Now we launch the app, attach to OllyDebuger and run the python script:

Step 5: Execute the python script and crush the server, then go View -> SafeSEH:

Note: In this OllyDebugger windows we see that the address was overwritten by the value 41387a41.

Step 6: After we do that, I copy in the clipboard the file, open a bash shell and paste the value to the bash to find the offset using this command ./pattern_offset.rb 41387a41, the repsonse we get back is:
[*] Exact match at offset 774.

Note: We should point out at this stage that the value is written in the NextSEH and not the SEH pointer. Also that the tool patten_create when used always generates the same pattern (e.g. a generated pattern of 1500 long would be always be the same). And that the pattern_offset due to the fact that the stack will always have the same start address 0x00000000 and same ending address 0xFFFFFFFF (see windows memory management) would be able to easily translate the position of the desired value always. 

Step 7: We modify the python script show as to mark with B's the NextSEH and verify our assumption using the following script:

This is the outcome of our python script:

Note: And voila, a quick view to the stack dump shows us that the Next SEH pointer was overwritten with the B's.

Positioning the shell 

Based on the explanations given previously the buffer should have the following format:

 [Junk] [next SEH] [SEH] [Shellcode]

Note: Further investigation will make see that there not enough space for the shell after the SEH. This means that we would have to find space in a different part of the stack. In our example the Shellcode is placed directly after the SEH, but the Wordmail situation we would have to make some memory manipulation and jump back in the stack.

The following OllyDebug picture shows the space left after the SEH pointer:

Note: The address we are looking for is 01b9ffac.

And the address end of the stack is:

Note: The address we are looking for is 01b9fff4. This is going to give us roughly the size of the space left to inject out shellcode.

Approximate size to insert our shell: 01b9fff4 - 01b9ffac = 48 bytes

So the final buffer would look like this:

  [Junk][Shellcode][Junk][next SEH] [SEH] [BackJump][Junk]

Note: In our situation the junk section of the buffer are nops (\x90).

The reason we do that is because:
  1. The final shellcode will be encoded for avoiding bad characters (e.g. \x00, \xff, \x0a, \x0d etc.) so when it executes it would need to unfold itself and expand within the stack. So surrounding the shell with nops (No Operation Hex = \x90) is always a good idea because it will give space for our shellcode to breath.
  2. When the shellcode is surrounded with nops, even if we make mistakes as far as jump address is concerned or we cannot jump directly to the beginning of the shell the nops are going to help us slide to the beginning of our shellcode.
  3. Back jumping will give us flexibility as far as the space available to for our shell is. 
Now the only think left to do is generate a shellcode using msfpayload, appropriate for our reasons, and then identify the size of the desired shellcode simulate the shellcode with breaks points (break = \xcc) inject that to the IMAP server and see if the break points occupy a continuous space in the stack.

So based on what just described this is how our new buffer should look like:

[ \x90's ][\xCC's][ \x90's ][next SEH] [SEH] [BackJump][ \x90's ]

After we do that in a similar way we calculate the the space, which is 700 bytes (plenty of space) and we create a Reverse Backward  Jump for 700 bites which is this one \xe9\x44\xfd\xff\xff. Our back jump does not have to be very accurate because we placed the nops to slide to our shell.

Finding the proper addresses

Step 1: The next step would be to find the POP POP RET sequence. In order to do that we relaunch the application, attach the application to the debugger select the CPU area and do right click do a Search for -> Sequence of Commands.

Note: The identified address is 7c901d6d, of course we can also use other tools to search for a ppr. Another way would be to use msfpescan from metasploit toolkit.

Step 2: The last step would be to insert after SEH address back jump and voila our exploit is ready to go.

Note:  I am not going to explain how the payload is generated, this is covered in previous post.

And the final exploit is:

Note: Important lessons learned from this exploit. During my effort to reproduce the exploit I learned the hard way that using poor old ollyDebug or IdaPro without other complementary tools is going to be very stressful and time consuming process. The same process if mona.py tools or other appropriate tools were used would have taken me a lot less.

  1. http://www.exploit-db.com/wp-content/themes/exploit/docs/17971.pdf 
  2. https://www.corelan.be/index.php/2009/07/25/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-3-seh/
  3. https://www.corelan.be/index.php/2009/07/28/seh-based-exploit-writing-tutorial-continued-just-another-example-part-3b/
  4. http://grey-corner.blogspot.com/2010/01/seh-stack-based-windows-buffer-overflow.html
  5. http://www.exploit-db.com/wp-content/themes/exploit/docs/40.pdf  
  6. The Shellcoder's Handbook SECOND EDITION by Chris Anley, Felix FX, Gerardo Richarte and John Heasman
  7. http://bap.ece.cmu.edu/ 
  8. http://www.immunityinc.com/products-immdbg.shtml 
  9. http://www.openrce.org/downloads/details/244/OllySSEH 
  10. http://www.offensive-security.com/metasploit-unleashed/Writing_An_Exploit 
  11. http://thestarman.pcministry.com/asm/2bytejumps.htm