缓冲区溢出分析和防御.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
缓冲区溢出分析和防御

缓冲区溢出分析和防御    从Morris编写了第一个蠕虫病毒以来,缓冲区溢出    攻击已成为目前世界上最主要、最具威胁性的网络攻击之一。据初步估计,美国每年因网络安全问题所造成的经济损失高达75亿美元。在过去的10年中,利用缓冲区溢出漏洞进行网络入侵占了网络攻击的70%以上。因此,深入研究缓冲区溢出的原理、其植入代码的结构特征,以及如何防范缓冲区溢出具有重要的意义。   缓冲区溢出内存模型和分类   缓冲区溢出的根本原因有两点:(1)缺少必要的边界检查。在C/C++等高级语言当中,数据被写入到缓冲区的时候,并不做边界检查。这样,一旦被复制的数据长度超过了缓冲区的大小,就必然会导致缓冲区溢出。(2)操作系统设计策略的隐患。这主要是指栈和堆数据区的可执行属性。Unix和Windows系统为了更好的性能和功能,往往在数据段当中动态放入可执行的代码,以保证程序的兼容性,从而使得堆和栈具有可执行属性。但是,赋予栈和堆的可执行属性并不是必要的。因为栈和堆的本质功能只是用来存储数据,对其赋予可执行权限对系统的安全性带来了不可避免的安全隐患。   在继续进行缓冲区溢出分析之前,先给出缓冲区溢出的内存模型和常见缓冲区溢出攻击的分类。   (一)缓冲区溢出内存模型   我们以针对栈的缓冲区溢出进行说明。针对堆的缓冲区溢出形式并不相同,但是其基本思想是一致的。   在某些高级语言,例如C程序中,每当调用函数时,就会自动处理堆栈分配。堆栈起到了保存有关当前函数调用上下文的容器的作用。许多内容都可能进入堆栈区,通常其内容与计算机体系结构和编译器相关。一般而言,如下内容都将被储存在堆栈中:函数的非静态局部变量值、堆栈基址、当函数返回时程序应该跳转到的地址以及传递到函数中的参数。   当发生函数调用时,编译器所执行的步骤如下:   (1)调用者。首先,调用者将被调用的函数所需的所有参数都压入堆栈,之后堆栈指针自动更改到指向当前栈顶。接着随系统不同,调用者可能压入一些其它数据来保护现场。完成后,调用者使用调用指令来调用函数。调用指令将返回地址(IP)压入堆栈,并相应更新堆栈指针。最后,调用指令将程序计数器设置为正被调用的函数地址,执行权交给被调用函数。进入第(2)步操作。   (2)被调用者。首先,被调用者将BP寄存器内容压入堆栈来保存调用者的堆栈基址,并更新堆栈指针到旧的基址。设置BP内容为自己的堆栈基址,亦即当前的堆栈指针。然后,被调用者按照局部变量的声明移动堆栈指针,为所有非静态局部变量分配足够的空间。执行被调用函数的操作。   (3)调用函数结束。当被调用函数执行完毕后,调用者更新堆栈指针以指向返回地址IP,调用ret指令将程序控制权交给返回地址上的程序。然后恢复被保存的运行环境。   从以上的过程中可以看到,发生函数调用时的堆栈分配过程中,非静态局部变量缓冲区的分配和填充不是同时进行的,并且依据不同的标准:局部变量缓冲区的分配是依据局部变量的声明,而填充则是依据其实际被赋予的值。因此这个过程中就出现了安全漏洞。图1说明了被调用函数执行时的堆栈情况。    图1 被调用函数执行时的堆栈情况   (二)缓冲区溢出分类   根据缓冲区溢出攻击手段的不同,主要分为以下三种方式:栈溢出、堆溢出和BSS 溢出,下面分别予以介绍。   (1)栈溢出。栈在函数调用的时候建立,包含以下信息:函数参数信息;函数返回地址信息;栈顶和栈底信息;局部变量的信息,具体可以参见图1。   栈的生长方向是从内存高地址向低地址生长的,其数据的压入和弹出操作由PUSH和POP完成,并且遵循后进先出的原则。当函数被调用时,其函数参数、函数返回地址、栈帧信息和局部变量依次压入到堆栈当中。这样,通过向栈中压入超长的数据,就有可能改变函数的返回地址,从而使得函数在返回的时候执行攻击者所期望执行的代码。例如:假设函数存在某个数组参数s[20],则当执行strcpy(s, attackstr)时,只要attackstr的长度足够长(20),就会覆盖函数返回地址IP,从而达到攻击目的。   (2)堆溢出。使用malloc()可以动态分配一段内存,并向用户返回一个内存地址,而实际上这个地址前面通常还有8Bytes 的内部结构,用来记录分配的块长度以及一些标志。图2是一个已分配的堆的内部结构示意图[4]。    图2 堆分配示意图   假设有如下定义:char * buf1 = ( char * )malloc (10) ; char * buf2 = ( char * )malloc (10) ;   通过事先向buf2 中写入10个B,之后再往buf1 写入10个A,可知堆的情况如图3所示。如果此时溢出指针buf1,将buf1当中写入18个A,则将

文档评论(0)

3471161553 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档