【问题标题】:Dillema with buffer overflow缓冲区溢出的困境
【发布时间】:2012-06-19 15:24:04
【问题描述】:

我正在玩一个堆栈溢出示例。此示例如下所示:

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

 }

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

所有这些代码都在名为overflow.c 的文件中。我们有一个名为 return_input 的易受攻击的函数,特别是它是 30 字节的字符数组。我编译它并在 gdb 中打开易受攻击的函数并得到以下输出:

 (gdb) disas return_input
 0x08048464 <+0>:   push   %ebp
 0x08048465 <+1>:   mov    %esp,%ebp
 0x08048467 <+3>:   sub    $0x48,%esp
 0x0804846a <+6>:   mov    %gs:0x14,%eax
 0x08048470 <+12>:  mov    %eax,-0xc(%ebp)
 0x08048473 <+15>:  xor    %eax,%eax
 0x08048475 <+17>:  lea    -0x2a(%ebp),%eax
 0x08048478 <+20>:  mov    %eax,(%esp)
 0x0804847b <+23>:  call   0x8048360 <gets@plt>
 0x08048480 <+28>:  lea    -0x2a(%ebp),%eax
 0x08048483 <+31>:  mov    %eax,(%esp)
 0x08048486 <+34>:  call   0x8048380 <puts@plt>
 0x0804848b <+39>:  mov    -0xc(%ebp),%eax
 0x0804848e <+42>:  xor    %gs:0x14,%eax
 0x08048495 <+49>:  je     0x804849c <return_input+56>
 0x08048497 <+51>:  call   0x8048370 <__stack_chk_fail@plt>
 0x0804849c <+56>:  leave  
 0x0804849d <+57>:  ret    
 End of assembler dump.

正如您从函数序言中看到的,我们在堆栈上为局部变量保留了 hex48(dec 72) 字节。首先,我试图找到易受攻击的数组在堆栈上的起始地址。我认为是-0x2a(%ebp),对吗? Hex2a 是十进制的 42。据我了解,这意味着我们可以在开始覆盖堆栈中保存的 EBP 之前安全地写入 42 个字节。但是当我运行这个例子时,只需要纠正 37 个字节就可以得到分段错误:

rustam@rustam-laptop:~/temp/ELF_reader$ ./overflow
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)

37 字节如何足以溢出缓冲区?如果我们的本地 char 数组是保存的 EBP 中的 -42 字节

【问题讨论】:

  • 不相关,但this question非常相似。
  • 在 C 中,将 31 个字节写入 30 字节数组就足以使该数组溢出(并导致未定义行为)。

标签: c assembly buffer-overflow


【解决方案1】:

不看函数的整个反汇编很难说。

但是,我的猜测是存储在 -0xc(%ebp) 的 %gs:0x14 可能是您的stack canary,如果检测到堆栈损坏,它会导致干净退出。 所以这个值存储在 -0xc(%ebp),这意味着你的缓冲区实际上只有 30 字节大,后面是任何内容。

【讨论】:

  • 谢谢老兄,在没有gcc堆栈保护的情况下重新编译,汇编代码正确地给出了所有值。
猜你喜欢
  • 2015-12-16
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-06
  • 2013-04-11
相关资源
最近更新 更多