gpt4 book ai didi

c - 堆栈缓冲区溢出导致的怪异执行路径

转载 作者:太空宇宙 更新时间:2023-11-04 00:09:16 24 4
gpt4 key购买 nike

我读了一些关于堆栈缓冲区溢出的文章,比如 this一,并了解了攻击者如何通过覆盖函数指针来利用堆栈缓冲区溢出错误。然后我写了一个小程序来演示攻击:

#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;
}

该程序是在 Fedora 14 x86 下使用 GCC 4.5.1 编译的。以下是输出:

$ ./exp01

Address of fun2: 0x8048452

In fun1, buffer= abcdefghijklmnopqrstuvR�

HELLO fun2!

HELLO fun2!

我们可以看到fun2()调用成功了,但是不知道为什么跑了两次。然后我 GDBed 它(见下文)。 (我只知道一些关于GDB的基本说明╮( ̄▽ ̄)╭)

我在谷歌上搜索了一些关键字,如“__libc_csu_fini()”,但没有找到一个明确的方法来帮助我理解程序的执行路径。我对编译器和进程的内部结构知之甚少,所以我认为我可能必须找到一些详细描述这些东西的书籍或文章。有什么建议吗?谢谢!


GDB 记录:

(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)

最佳答案

当在 gdb 中运行您的程序时,在 strcpy() 之前不久中断并查看栈帧(即保存 eip 的存储位置)。然后运行直到 printf() 之后不久,再次查看存储的 eip(命令是 info frame)。

由于您将函数 fun2() 的地址传递给 fun1() 它将覆盖保存的 eip,并且一旦调用返回(在您的情况下是隐含的)将执行下一条指令(由 eip 给出,在您的情况下它是 fun2() 的地址)

别忘了阅读 Smashing the stack for fun and profit通过 aleph1

关于c - 堆栈缓冲区溢出导致的怪异执行路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9530957/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com