- 1、本文档共14页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
缓冲区溢出攻击详细讲解
缓冲区溢出(Buffer Overflow)是计算机安全领域内既经典而又古老的话题。随着计算机系统安全性的加强,传统的缓冲区溢出攻击方式可能变得不再奏效,相应的介绍缓冲区溢出原理的资料也变得“大众化”起来。 其中看雪的《0day 安全:软件漏洞分析技术》一书将缓冲区溢出攻击的原理阐述得简洁明了。本文参考该书对缓冲区溢出原理的讲解,并结合实际的代码实例进行验证。不过即便如此,完成一个简单的溢出代码也需要解决很 多书中无法涉及的问题,尤其是面对较新的具有安全特性的编译器——比如MS 的 Visual Studio2010。接下
来,我们结合具体代码,按照对缓冲区溢出原理的循序渐进地理解方式去挖掘缓冲区溢出背后的底层机制。
一、代码 = 数据
顾名思义,缓冲区溢出的含义是为缓冲区提供了多于其存储容量的数据,就像往杯子里倒入了过量的水一 样。通常情况下,缓冲区溢出的数据只会破坏程序数据,造成意外终止。但是如果有人精心构造溢出数据的内 容,那么就有可能获得系统的控制权!如果说用户(也可能是黑客)提供了水——缓冲区溢出攻击的数据,那么 系统提供了溢出的容器——缓冲区。
缓冲区在系统中的表现形式是多样的,高级语言定义的变量、数组、结构体等在运行时可以说都是保存在缓 冲区内的,因此所谓缓冲区可以更抽象地理解为一段可读写的内存区域,缓冲区攻击的最终目的就是希望系统能 执行这块可读写内存中已经被蓄意设定好的恶意代码。按照冯·诺依曼存储程序原理,程序代码是作为二进制数据 存储在内存的,同样程序的数据也在内存中,因此直接从内存的二进制形式上是无法区分哪些是数据哪些是代码 的,这也为缓冲区溢出攻击提供了可能。
图 1 进程地址空间分布
图 1 是进程地址空间分布的简单表示。代码存储了用户程序的所有可执行代码,在程序正常执行的情况下, 程序计数器(PC 指针)只会在代码段和操作系统地址空间(内核态)内寻址。数据段内存储了用户程序的全局变量,文字池等。栈空间存储了用户程序的函数栈帧(包括参数、局部数据等),实现函数调用机制,它的数据增 长方向是低地址方向。堆空间存储了程序运行时动态申请的内存数据等,数据增长方向是高地址方向。除了代码 段和受操作系统保护的数据区域,其他的内存区域都可能作为缓冲区,因此缓冲区溢出的位置可能在数据段,也 可能在堆、栈段。如果程序的代码有软件漏洞,恶意程序会“教唆”程序计数器从上述缓冲区内取指,执行恶意 程序提供的数据代码!本文分析并实现栈溢出攻击方式。
二、函数栈帧
栈的主要功能是实现函数的调用。因此在介绍栈溢出原理之前,需要弄清函数调用时栈空间发生了怎样的变 化。每次函数调用时,系统会把函数的返回地址(函数调用指令后紧跟指令的地址),一些关键的寄存器值保存
在栈内,函数的实际参数和局部变量(包括数据、结构体、对象等)也会保存在栈内。这些数据统称为函数调用 的栈帧,而且是每次函数调用都会有个独立的栈帧,这也为递归函数的实现提供了可能。
图 2 函数栈帧
如图所示,我们定义了一个简单的函数function,它接受一个整形参数,做一次乘法操作并返回。当调用function(0)时,arg 参数记录了值 0 入栈,并将 call function 指令下一条指令的地址 0x00bd16f0 保存到栈内, 然后跳转到 function 函数内部执行。每个函数定义都会有函数头和函数尾代码,如图绿框表示。因为函数内需要用 ebp 保存函数栈帧基址,因此先保存 ebp 原来的值到栈内,然后将栈指针esp 内容保存到 ebp。函数返回前 需要做相反的操作——将 esp 指针恢复,并弹出 ebp。这样,函数内正常情况下无论怎样使用栈,都不会使栈失去平衡。
sub esp,44h 指令为局部变量开辟了栈空间,比如ret 变量的位置。理论上,function 只需要再开辟 4 字节空间保存 ret 即可,但是编译器开辟了更多的空间(这个问题很诡异,你觉得呢?)。函数调用结束返回后,函数栈帧恢复到保存参数 0 时的状态,为了保持栈帧平衡,需要恢复esp 的内容,使用 add esp,4 将压入的参数弹
出。
这个函数没有做什么有“意义”的事情(这里主要是为了简化问题),但是它是一个典型的栈溢出代码。在使用不安全的 strcpy 库函数时,系统会盲目地将 data 的全部数据拷贝到 buffer 指向的内存区域。buffer 的长度
这个函数没有做什么有“意义”的事情(这里主要是为了简化问题),但是它是一个典型的栈溢出代码。在
使用不安全的 strcpy 库函数时,系统会盲目地将 data 的全部数据拷贝到 buffer 指向的内存区域。buffer 的长度
是有限的,一旦 data 的数据长
文档评论(0)