tbh1
tbh1

Reputation: 671

Stack overflow - odd return address

I am working my way through an example in "The Shellcoder's Handbook". However, it is not going all that well. I am running a Debian 2.6.32-5-686 kernel, i386.

The following walkthrough is to guide the reader through the guts of what is happening when a buffer overflow occurs.

The program:

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

void return_input(void)
{
    char array[30];
    gets (array);
    printf("%s\n", array);
}

int main ()
{
    return_input();
    return 0;
}

The aim of the game to to pass "AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD" to the array which, in turn, will overwrite the return address with the excess 'D's.

I compiled like so:

gcc -ggdb -m32 -o test -fno-stack-protector -mpreferred-stack-boundary=2 test.c

I run gdb test and start investigating:

(gdb) disas return_input 
Dump of assembler code for function return_input:
0x080483f4 <return_input+0>:    push   %ebp
0x080483f5 <return_input+1>:    mov    %esp,%ebp
0x080483f7 <return_input+3>:    sub    $0x24,%esp
0x080483fa <return_input+6>:    lea    -0x1e(%ebp),%eax
0x080483fd <return_input+9>:    mov    %eax,(%esp)
0x08048400 <return_input+12>:   call   0x804830c <gets@plt>
0x08048405 <return_input+17>:   lea    -0x1e(%ebp),%eax
0x08048408 <return_input+20>:   mov    %eax,(%esp)
0x0804840b <return_input+23>:   call   0x804832c <puts@plt>
0x08048410 <return_input+28>:   leave  
0x08048411 <return_input+29>:   ret    
End of assembler dump.
(gdb) break *0x08048400
Breakpoint 1 at 0x8048400: file test.c, line 7.
(gdb) break *0x08048411
Breakpoint 2 at 0x8048411: file test.c, line 9.

At this point we introduced two break points. One just before the call to gets. And another just before the function returns. Now we run it:

(gdb) run
Starting program: ./test 

Breakpoint 1, 0x08048400 in return_input () at test.c:7
7       gets (array);
(gdb) x/20x $esp
0xbffff3ac: 0xbffff3b2  0xb7fca304  0xb7fc9ff4  0x08048440
0xbffff3bc: 0xbffff3d8  0xb7eb75a5  0xb7ff1040  0x0804844b
0xbffff3cc: 0xb7fc9ff4  0xbffff3d8  *0x0804841a*    0xbffff458
0xbffff3dc: 0xb7e9ec76  0x00000001  0xbffff484  0xbffff48c
0xbffff3ec: 0xb7fe18c8  0xbffff440  0xffffffff  0xb7ffeff4

This what the stack looks like just before the call to gets. I have marked the return address with asterisk (0x0804841a). Let's overwrite this:

(gdb) continue
Continuing.
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD

Breakpoint 2, 0x08048411 in return_input () at test.c:9
9   }
(gdb) x/20x 0xbffff3ac
0xbffff3ac: 0xbffff3b2  0x4141a304  0x41414141  0x41414141
0xbffff3bc: 0x42424242  0x42424242  0x43434242  0x43434343
0xbffff3cc: 0x43434343  0x44444444  *0x44444444*    0xbf004444
0xbffff3dc: 0xb7e9ec76  0x00000001  0xbffff484  0xbffff48c
0xbffff3ec: 0xb7fe18c8  0xbffff440  0xffffffff  0xb7ffeff4

The above is what the stack looks like just before returning from the function. As you can see, we've overwritten the return address with those excess 'D's. Result. Let's finish up:

(gdb) x/li $eip
0x8048411 <return_input+29>:    ret    
(gdb) stepi
Cannot access memory at address 0x44444448

Um, eh? This 0x44444448 has come from the arse-end of nowhere. Somehow gcc has modified the return address just before we return. Thanks.

Any ideas? Am I correct in assuming gcc has done its own internal checking whether the return address is valid. And if not, it's stuck some crap in it to prevent us from crafting a nasty return address?

Any way around this? I've tried everything here - http://www.madhur.co.in/blog/2011/08/06/protbufferoverflow.html. Same result.

Upvotes: 1

Views: 564

Answers (1)

Mackie Messer
Mackie Messer

Reputation: 7348

This is the expected result—a page fault. Your program ist stopped by the operating system because you are accessing virtual memory that is not assigned to any physical memory.

The message you see is just the debugger notifying you of that fact.

Upvotes: 4

Related Questions