Windows SEH Based Buffer Overflow
For this post, we will find and exploit a SEH vulnerability in the Konica Minolta FTP server.
All I used can be download here:
You can download scripts in my github:
If you don’t have a solid knowledge about stack based buffer overflow I highly encourage you to read my first blog post: here.
What Do you mean about SEH?!
SEH is an acronym for Structured Exception Handler. We can deal with exception handler when developers of a software try to handle potential exception(s) during the execution of the program, in many cases it’s when we have a try catch statement.
Two different types of exception handler exists:
- The default Windows EH (UnhandledExceptionFilter) and
- The EHs that you implement with a specific development language;
The thing that we have to know is that the SEH is composed of two pointers, the pointer of the next SEH if the current EH is not able to handle the raised exception and the pointer of the EH. This structure of 8 bytes (2x 4 bytes) is called SEH record.
That’s what the SEH chain should look like:
To conclude, instead of overwriting EIP we will overwrite both the address of EH and the address of the next SHE in order to redirect the execution flow somewhere where we can execute the injected shellcode. Note, due to the fact it’s an 8 bytes structure we have to find instructions that will increase the stack by 8 bytes if we want to be redirected at the beginning of the next SEH. That’s where the POP POP RET method comes in.
Fuzzing the FTP Server
The first thing that we have to do when we have an unknown software is to fuzz it in order to find an entry point. The following Python script can be used to fuzz the CWD command in the FTP server.
After 1300 characters the server crash.
As explained in the previous section EIP is NOT overwritten, but if we take a look at the SEH record (ALT + S) we will see that we have a corrupted entry.
Controlling EH and nSEH pointers
We can replicate the crash with this Python script.
Let’s find with how many bytes we overwrite the next SEH pointer. Like in the first post I will use both the pattern_create tool and the mona.py findmsp command.
Apparently with 1037 bytes.
Now, we update the PoC and let’s see if we control EH and the next SEH.
As expected, the pointer of the EH is overwritten with our Cs and the pointer of the next SEH is overwritten with our Bs.
Redirecting the execution flow
Now, we have to find POP POP RET instructions in order to increase the stack pointer and to return at the beginning of the next SEH. For that, we use the seh mona.py command.
The first address given by mona can be use. Note, ASLR, SafeSEH and Rebase are disabled. Moreover, it’s not an OS based address, that means we can use it for all OS versions.
The updated PoC with the POP POP RET address should look like that:
At the crash we can execute Shift + F9 to pass the execution and reach the breakpoint.
If we execute these three instructions we will increase the stack by 8 bytes and the stack pointer (ESP) will point at the address of the next SEH so when the RET instruction is executed we return at the beginning of the next SEH.
Now, instead of using Bs for the next SEH we will use a JMP SHORT 8 instruction to jump over the EH address. We can use nasm_shell.rb from the Metasploit framework to find the hexadecimal representation of ASM instructions.
We update the PoC with the JUMP SHORT 8 instruction:
Finally, we successfully jump over the EH address.
For this post I will skip the research of badchars because I already explain how to do it in the first post. For this exploit badchars are: \x00\x0a\x0d
We can generate a reverse shell with msfvenom:
We add the shellcode to our PoC.
After all, we successfully gain a reverse shell.