缓冲区溢出攻击原理分析

缓冲区溢出攻击原理分析本文从C/C++语言的函数帧结构出发,分析缓冲溢出攻击如果修改eip进而控制执执行shellcode。

大家好,又见面了,我是你们的朋友全栈君。

缓冲区溢出攻击实践》以实践者角度介绍了初级缓冲区溢出攻击方法,本文从原理上对该方法做原理性介绍。


函数帧结构

现在高级语言C(或者C++),在函数开头的几指令要建立好函数帧结构,而函数返回时要撤消函数帧。当前在不同的CPU体系加构或者ABI标准,这些函数帧结构有一些差别,但原理上是相通的。

我们还是以之前的示例代码作为分析对象,讨论在fread函数填数据到buf变量前的栈结构。

下面是机器上对stack1程序 main函数反编译的结果:

(gdb) disassemble main
Dump of assembler code for function main:
   0x08048484 <+0>:     push   %ebp
   0x08048485 <+1>:     mov    %esp,%ebp
   0x08048487 <+3>:     and    $0xfffffff0,%esp
   0x0804848a <+6>:     sub    $0x40,%esp
   0x0804848d <+9>:     mov    $0x80485e0,%edx
   0x08048492 <+14>:    mov    $0x80485e2,%eax
   0x08048497 <+19>:    mov    %edx,0x4(%esp)
   0x0804849b <+23>:    mov    %eax,(%esp)
   0x0804849e <+26>:    call   0x80483c0 <fopen@plt>
   0x080484a3 <+31>:    mov    %eax,0x3c(%esp)
   0x080484a7 <+35>:    cmpl   $0x0,0x3c(%esp)
   0x080484ac <+40>:    jne    0x80484c1 <main+61>
   0x080484ae <+42>:    movl   $0x80485ea,(%esp)
   0x080484b5 <+49>:    call   0x8048380 <perror@plt>
   0x080484ba <+54>:    mov    $0x1,%eax
   0x080484bf <+59>:    jmp    0x80484ff <main+123>
   0x080484c1 <+61>:    lea    0x1c(%esp),%eax
   0x080484c5 <+65>:    mov    0x3c(%esp),%edx
   0x080484c9 <+69>:    mov    %edx,0xc(%esp)
   0x080484cd <+73>:    movl   $0x1,0x8(%esp)
   0x080484d5 <+81>:    movl   $0x400,0x4(%esp)
   0x080484dd <+89>:    mov    %eax,(%esp)
   0x080484e0 <+92>:    call   0x8048390 <fread@plt>
   0x080484e5 <+97>:    mov    $0x80485f0,%eax
   0x080484ea <+102>:   lea    0x1c(%esp),%edx
   0x080484ee <+106>:   mov    %edx,0x4(%esp)
   0x080484f2 <+110>:   mov    %eax,(%esp)
   0x080484f5 <+113>:   call   0x8048370 <printf@plt>
   0x080484fa <+118>:   mov    $0x0,%eax
   0x080484ff <+123>:   leave
   0x08048500 <+124>:   ret
End of assembler dump.

在函数体里面最先执行的几条指令,通常称为
function prologue
,它完成建立函数帧的功能。


0x08048484 <+0>  push %ebp 
0x08048485 <+1>  mov %esp,%ebp 
0x08048487 <+3> and $0xfffffff0,%esp 
0x0804848a <+6>  sub $0x40,%esp

它的功能是:先将调用者的ebp压到栈上,然后将此时的esp作为被调用者的ebp(栈顶),然后根据函数局部变量的大小,将esp将压地址扩展,作为被调用者的esp(栈底);这样ebp和esp这对寄存器描述的栈空间就函数帧的空间。

在函数返回时,它总执行以下两条指令,通常称为
function epilogue

0x080484ff <+123>   leave
0x08048500 <+124>   ret

它的功能是:先将当前函数的ebp赋给esp,然后再从栈中弹出(pop)调用者的ebp值到ebp寄存器,然后再从栈中弹出EIP值到pc寄存器。指令执行完后,ebp和esp就是父函数的函数帧。

示例程序的栈帧结构


根据上面stack1中main的反编译结果,画出如图1的栈结构:

缓冲区溢出攻击原理分析
图1: fread函数调用函数,栈帧结构图

这里重点关注一下buf变量在栈中的位置,当buf变量发生溢出时,就会往高地址空间覆盖。先是覆盖main函数的其它局部变量(图1没有画出来),然后是父函数的ebp,再次重点是eip,最后是父函数的栈空间。我们不关心覆盖父函数的栈空间,因为我们根本不打算返回父函数执行。

缓冲区溢出后栈内容


当前fread从bad.txt读取文件内容到buf缓冲区并发生溢出后,整个栈空间内容如图2所示:

缓冲区溢出攻击原理分析

图2:fread从bad.txt文件读取数据产生溢出后的栈数据


当函数返回时,ret指令将0xffffd710弹给pc寄存,就开始执行shellcode了。

小结


本文以示例程序为蓝本,分析程序的栈帧结构,以及攻击方法如何利用该结构控制EIP,改变程序执行流程,从而让程序掉到shellcode的坑里面。

Locations of visitors to this page
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158142.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • .pyd是什么文件_python解析html

    .pyd是什么文件_python解析html有的时候,为了对python文件进行加密,会把python模块编译成.pyd文件,供其他人调用。拿到一个.pyd文件,在没有文档说明的情况下,可以试试查看模块内的一些函数和类的用法。首先importXXX(pyd的文件名)然后直接print(dir(XXX))print(help(xxx))其中dir()列出了属性和方法而hlep()直接列出了其中的函数以及参数,并且是源码的函数名和类型,…

    2025年7月25日
    2
  • MacBook Pro最全快捷键指南——高效型选手必备

    MacBook Pro最全快捷键指南——高效型选手必备剪切、拷贝、粘贴和其他常用快捷键Command-X:剪切所选项并拷贝到剪贴板。Command-C:将所选项拷贝到剪贴板。Command-V:将剪贴板的内容粘贴到当前文稿或应用中。Command-Z:撤销前一个命令。随后您可以按Command-Shift-Z来重做,从而反向执行撤销命令。Command-A:全选各项。Command-F:查找文稿中的项目或打开“查找”窗…

    2022年5月25日
    50
  • 如何线上推广引流?百度知道实现精准引流

    如何线上推广引流?百度知道实现精准引流百度如何做推广精准吸粉的,百度知道的4个精准吸粉技巧!众所周知,百度是全球最大的中文搜索引擎,百度一下你就知道,这是我们非常熟悉的广告词之一。因为它的流量非常大,所以很多人都在那里努力分流。但是一部分人吸粉的效果不太好。为什么呢?因为流量的准确性不够!百度的百度知道是一个精准的流量池,这样我们就可以正确地把流量流到自己的平台上。你知道百度是如何引流的吗?今天,兴棋就给大家分享一下它的玩法,希望对大家有所帮助!一、做百度知道引流的两大优点!1、是能够带来直接的流量,如果你回答的问题能够带上链接,那

    2022年5月23日
    131
  • c++-析构函数

    c++-析构函数

    2021年9月29日
    59
  • java中获取绝对值的方法_java取绝对值math.abs函数使用方法「建议收藏」

    取绝对值用到Math类java.lang.Math函数了,下面我们一起来看看关于取绝对值用到Math类java.lang.Math使用方法,有兴趣的朋友可进入参考。兼容类型如下staticdoubleabs(doublea)返回double值的绝对值。staticfloatabs(floata)返回float值的绝对值。staticintabs(inta)返回int…

    2022年4月10日
    48
  • 按位取反运算符~_c语言∧按位异或运算符

    按位取反运算符~_c语言∧按位异或运算符https://www.cnblogs.com/shy1766IT/p/6184874.html二进制数在内存中以补码的形式存储。按位取反:二进制每一位取反,0变1,1变0。~9的计算步骤:转二进制:01001计算补码:01001按位取反:10110转为原码:按位取反:11001末位加一:11010符号位为1是负数,即-10varx…

    2022年8月14日
    11

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号