OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: Vinay A. Mahadik (vamahadianr.mcnc.org)
Date: Wed Apr 24 2002 - 01:45:22 CDT

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

    Hi,

    I was going through Mixter's tutorial on Buffer Overflows and ran into
    some unexpected behavior I would like to know the why's of. In what
    follows, I overwrite both EBP and RET on the stack with a new instruction
    address.(ix86)

    # cat blah.c
    #define BUF_SIZE 30 // bytes

    void lame (void) {
     char small[BUF_SIZE];

     gets (small); // Exploitable user i/p function

     printf("%s\n", small);
    }

    main() {
     lame ();
     return 0;
    }

    # cat ret.c
    main()
    {
     int i=0; char buf[48];
     for (i=0;i<=44;i+=4)
     *(long *) &buf[i] = 0x80484ba;
     puts(buf);
    }

    # gcc -O2 -ggdb ret.c -o ret

    # ./ret > input

    # gdb blah
    (gdb) break main
    Breakpoint 1 at 0x80484ba: file blah.c, line 12.
    (gdb) run < input
    Starting program: /root/security/bufferoverflows/blah < input

    Breakpoint 1, main () at blah.c:12
    12 lame ();
    (gdb) disas main
    Dump of assembler code for function main:
    0x80484b4 <main>: push %ebp
    0x80484b5 <main+1>: mov %esp,%ebp
    0x80484b7 <main+3>: sub $0x8,%esp
    0x80484ba <main+6>: call 0x8048490 <lame>
    0x80484bf <main+11>: xor %eax,%eax
    0x80484c1 <main+13>: leave
    0x80484c2 <main+14>: ret
    End of assembler dump.
    (gdb) display /i $pc
    1: x/i $eip 0x80484ba <main+6>: call 0x8048490 <lame>
    (gdb) nexti
    ?'

    Breakpoint 1, main () at blah.c:12
    12 lame ();
    1: x/i $eip 0x80484ba <main+6>: call 0x8048490 <lame>
    (gdb) nexti
    ?'
    13 return 0;
    1: x/i $eip 0x80484bf <main+11>: xor %eax,%eax
    (gdb) nexti
    14 }
    1: x/i $eip 0x80484c1 <main+13>: leave
    (gdb) print /x $ebp
    $1 = 0x80484ba
    (gdb) print /x $esp
    $2 = 0xbffff9c0
    (gdb) x /4xb $ebp
    0x80484ba <main+6>: 0xe8 0xd1 0xff 0xff
    (gdb) nexti
    0x080484c2 in main () at blah.c:14
    14 }
    1: x/i $eip 0x80484c2 <main+14>: ret
    (gdb) print /x $ebp
    $3 = 0xffffd1cc
    (gdb) print /x $esp
    $4 = 0x80484be
    (gdb)

    ----------

    What I couldn't get is the effect of the "leave" instruction on $ebp.
    Clearly if leave = movl %ebp, %esp & popl %ebp, $ebp should have been
    0xffffd1e8 as displayed above right? Where might it be getting that other
    address?

    Basically, I want to cause the buffer overflow to recall lame() as above
    but only without seg faulting later on. (I know the code can be modified
    to achieve that) It _is_ seg-faulting with this unexplained new EBP.
    Why isn't the EBP picking up the old EBP saved/placed in the immediate 4
    upward bytes from the present EBP value? (as it does when the EBP isn't
    corrupted)

    Could you throw some light on this please? I am new to
    assembly/disassembly btw.

    Thanks,
    Vinay.

    --
    Vinay A. Mahadik
    http://hickory.csc.ncsu.edu/