gdb 查看是否 栈溢出_Linux下的栈溢出案例分析-GDB调试操练

摘要:本文主要演示Linux平台下的栈溢出,首先根据理论对示例代码进行溢出攻击;结果是溢出攻击成立,但是与设想的有差别;然后采用GDB调试工具对发生的意外,进行深入的分析。

测试的平台:1.  Ubuntu 9;  gcc 4.4.1;  Gdb 7.0-ubuntu

2.  Ubuntu系统安装在VirtualBox 3.2.8虚拟机上;

示例代码如下:

#include

void overflow(char* arg)

{

char buf[12];

strcpy(buf, arg);

}

int main(int argc, char *argv[])

{

if(argc > 1)

overflow(argv[1]);

return 0;

}

如果按照一般的方式编译:

gcc –o stackoverflow stackoverflow.c

linux系统能够探测到程序中的stack  overflow,从而终止程序,如下图所示:

77f7dbce72a3e53b30d891142bd623e4.png

那有没有办法让系统不探测到stack overflow,此处可以在编译时,禁用堆栈保护,具体命令如下:

gcc –fno-stack-protector –o stackoverflow stackoverflow.c

然后采用gdb调试stackoverflow,

a479941171e7cc16109cc3b9e6f6d658.png

这里的输出跟设想的存在很大的差别,因为设想中的函数栈如下:

23906f46d2464b0e31391657d387f05c.png

前面的12个字节填充buf,然后接下来的4个字节填充ebp,最后的4个字节填充RET地址,那么照理说,这里的eip应该是0x65656565,那为什么此处是0x61616161,刚好是aaaa的值呢?

根据单步调试的结果,发现eip变为0x61616161是在main函数退出后达到的,按照设想应该是在overflow退出时,eip变为0x65656565。

为什么overflow退出后还能回到main函数?可能的原因:输入的字符串没有覆盖掉ret地址,但是字符串却意外地将main的返回地址给覆盖掉了?

但就算是覆盖,为什么覆盖的值没有采用e的值,而是采用的a的值?要知道a是在字符串的起始处?这点的确让人奇怪。

1. 我们还是采用一步步调试的方式来观察问题所在,先看下gcc编译后的反汇编代码:

使用到的命令:

set disassembly-flavor intel  //将汇编设定为intel风格;

disassemble main  //反汇编main函数;

Main函数:

1. push ebp

2. mvo ebp, esp

3. and esp, 0xfffffff0

4. sub esp, 0x10

5. cmp DWORD PTR [ebp+0x8], 0x1

6. jle  0x804841d

7. mov eax, DWORD PTR [ebp+0xc]

8. add eax, 0x4

9. mov eax, DWORD PTR [eax]

10. mov DWORD PTR [esp], eax

11. call 0x80483e4

12. mov eax, 0x0

13. leave

14. ret

然后再来看下,overflow的反汇编代码,命令:disassemble overflow

Overflow函数:

1. push ebp

2. mov ebp, esp

3. sub esp, 0x28

4. mov  eax, DWORD PTR[ebp+0x8]

5. mov  DWORD PTR[esp+0x4], eax

6. lea  eax, [ebp-0x14]

7. mov  DWORD  PTR [esp], eax

8. call  0x804831c

9. leave

10. ret

我们单步调试上述的指令,关注其中esp值的变化。总图如下,后面是对其中每一步的分析:

2e067e455b7f2b15296233339d9b5588.png

在完成main.1后,命令p $esp后,esp的值变为:Esp = 0xbffff438

Main.3后,esp的值变为0xbffff430,估计是用于对齐;

Main.4后,esp的值为0xbffff420;

Main.7-10,这里主要将argv[]的arg[1]字符串的首地址取出来,并且将其放置在esp中,此时esp的值为0xbffff420;

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值