I read some articles about Stack Buffer Overflow, like this one, and learned how attackers can exploit a Stack Buffer-Overflow bug by overwriting function pointers. Then I wrote a small program to demonstrate an attack:
#include <stdio.h>
#include <string.h>
void fun1 ( char * input ) {
char buffer[10];
strcpy( buffer, input );
printf( "In fun1, buffer= %s\n", buffer );
}
void fun2 ( void ) {
printf ( "HELLO fun2!\n" );
}
int main ( int argc, char * argv[] )
{
printf ( "Address of fun2: %p\n", fun2 );
fun1( "abcdefghijklmnopqrstuv\x52\x84\x04\x08" );
return 0;
}
The program was compiled with GCC 4.5.1, under Fedora 14 x86. Below is the output:
$ ./exp01
Address of fun2: 0x8048452
In fun1, buffer= abcdefghijklmnopqrstuvR�
HELLO fun2!
HELLO fun2!
We can see that fun2() was called successfully, but I don't know why it ran twice. Then I GDBed it (See Below). (I know only some basic instruction about GDB ╮( ̄▽ ̄)╭ )
I Googled some key words such as "__libc_csu_fini ()", but didn't find a clear way that can help me to understand the program's execution path. I know too little about compiler and the inner structure of a process, so I consider that I may have to find some books or articles that describe these stuff in detail. Any suggestion? Thank you!
GDB Record:
(gdb) list
7 printf( "In fun1, buffer= %s\n", buffer );
8 }
9
10 void fun2 ( void ) {
11 printf ( "HELLO fun2!\n" );
12 }
13
14 int main ( int argc, char * argv[] )
15 {
16 printf ( "Address of fun2: %p\n", fun2 );
(gdb)
17 fun1( "abcdefghijklmnopqrstuv\x52\x84\x04\x08" );
18 return 0;
19 }
(gdb) break 16
Breakpoint 1 at 0x804846f: file hello.c, line 16.
(gdb) run
Starting program: /home/yuliang/test/hello
Breakpoint 1, main (argc=1, argv=0xbffff394) at hello.c:16
16 printf ( "Address of fun2: %p\n", fun2 );
Missing separate debuginfos, use: debuginfo-install glibc-2.13-2.i686
(gdb) step
Address of fun2: 0x8048452
17 fun1( "abcdefghijklmnopqrstuv\x52\x84\x04\x08" );
(gdb)
fun1 (input=0x804859a "abcdefghijklmnopqrstuvR\204\004\b") at hello.c:6
6 strcpy( buffer, input );
(gdb)
7 printf( "In fun1, buffer= %s\n", buffer );
(gdb)
In fun1, buffer= abcdefghijklmnopqrstuvR�
8 }
(gdb)
fun2 () at hello.c:10
10 void fun2 ( void ) {
(gdb)
11 printf ( "HELLO fun2!\n" );
(gdb)
HELLO fun2!
12 }
(gdb)
0x08048500 in __libc_csu_fini ()
(gdb)
Single stepping until exit from function __libc_csu_fini,
which has no line number information.
fun2 () at hello.c:10
10 void fun2 ( void ) {
(gdb)
11 printf ( "HELLO fun2!\n" );
(gdb)
HELLO fun2!
12 }
(gdb)
Cannot access memory at address 0x76757477
(gdb)
Single stepping until exit from function __libc_csu_init,
which has no line number information.
0x009aae36 in __libc_start_main () from /lib/libc.so.6
(gdb)
Single stepping until exit from function __libc_start_main,
which has no line number information.
Program exited with code 0241.
(gdb)