Understanding Structured Exception Handlers

To understand an Structured Exception Handlers (SEH) think of when programming and you use a try … except(NullPointerException e). This will create an SEH struct to handle a null pointer. A program may have a list of SEH structs that are linked to each other. Each of these are able to handle a specific error and when an error occurs the operating system goes through each SEH struct until it finds the one that fits, otherwise it defaults to the OS error handler where the program crashes and you get the message “*** has encountered a problem”.

For every block of code in memory that contains an exception handler will have an SEH struct added to it’s stack frame.

Each SEH struct will have two pointers that we care about. One is a pointer to the Exception Registration Record (SEH) and the other is the pointer to the Next Exception Registration Record (nSEH). Our goal is to overwrite both of these pointers with instructions or a memory address to our our shellcode.

Let’s See SEH In Action

I wrote an exploit of my own for this example. I found a PoC of a vuln on ExploitDB so I created this exploit for it. Fire up you Windows XP box and download the vulnerable software: AVS Audio Converter

Once you have it installed on your Windows XP machine, fire up Immunity Debugger and attach to the AVS Audio Converter process then press Play. Open up Notepad++ and let’s create an exploit script.

Run your exploit and copy the payload from evil.txt. Now with AVS running and Immunity attached to it, paste the payload into the field Output Folder and press Browse… and then return to Immunity Debugger. We have overwritten EIP it looks like, but let’s take a look at that SEH chain.

In the toolbar go to View and then SEH Chain. You can see we have overwritten both the SE handler and next SE Handler. Copy the address of the SEhandler by right clicking on it and Copy To Clipboard and then Address. Go back to the CPU – Main Thread by going to Windows -> CPU – Main Thread. In the stack column in the bottom right, right click and click Goto Expression and enter your SEH handler address. You can see we the composition of the stack now that we overwrote it.

Let’s get Mona back to work. We need to create another Metasploit pattern to understand the structure of the SE handler that we have overwritten. In the command line of Immunity use the command !mona pattern_create 1500. Go to C:\Program Files\Immunity Inc\Immunity Debugger and open pattern.txt. Copy the Hex patter and replace buffer in your exploit script.

Follow the steps to crash AVS Audio Converter with your payload and go back to Immunity Debugger. This time we are going to use Mona to find where the SEH chain has been overwritten. In the command line use the command !mona findmsp. When Mona completes it’s work we see we overwrite SEH starting at 260 bytes in.

Now we need to re-write our exploit to include nSEH and SEH pointers. We can see from the stack that SEH is 4 bytes and nSEH is next 4 bytes to follow. Because our stack grows downwards we need to place nSEH first and our exploit will look like this.

Devise An Attack Strategy

Now we have control of two pointers but what do we do with them. The SEH trick is to find an address in memory that contains the instructions POP POP RET and place this address in our SEH buffer. When this set of instructions are executed the program will POP SEH off the stack and then POP nSEH off the stack and RET on nSEH essentially executing whatever instructions are in nSEH.

Let’s find a POP POP RET address using Mona. In the Immunity Command Line use the command !mona seh and Mona will return all of the POP POP RET address found in memory. Remember to use an address that doesn’t contain any null bytes or bad characters.

I found 0x74c9ea1e to be a good address to use. It’s an OS address so that’s a downside but the application addresses all start with a null byte so they are of no use. Let’s update SEH in our exploit, run AVS and set a break point in Immunity at SEH.

When you paste your payload into AVS and hit browse you will hit your breakpoint in Immunity. Press F7 3 times to step through the POP POP RET instructions. Now you will see that you are at the start of your nSEH buffer and our Ds lie right after our SEH buffer. We need a set of instructions that are 4 bytes long and jump over SEH to put into nSEH.

In Immunity’s Disassembler window, you should see it is highlighted at the first byte of your nSEH buffer. Double click the instruction and you’ll see an Assemble dialog appear. In that dialog type jmp 0012FA80 (this is where our Ds start). You will see the instructions EB 06. This is an instruction to jump forward 6 bytes. This is only a two byte instruction so we add 2 bytes of nops to get “\xEB\x06\x90\x90”.

AVS Audio Converter PWND!

Now we have an attack plan. Let’s finish this off and pwn AVS Audio Converter. Update the exploit script with your new nSEH buffer and some shellcode after the SEH buffer. Add some nops first to ease it in.

Run your exploit, copy the payload and paste it into AVS to complete the pwn! You have just pwnd AVS Audio Converter by attacking it’s Structured Exception Handlers you should be proud!

Thanks for reading and following along. If you have any questions or comments feel free to drop a comment below or hit me up on Twitter. I’ll be coming out with Part 3: Unicode Buffer Overflows soon so check back!