为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

缓冲区溢出攻击的原理分析与防范

2019-03-30 22页 ppt 1MB 14阅读

用户头像 个人认证

黄红霞

本人自上班以来对工作兢兢业业,曾获得县劳动模范,优秀教师等荣誉称号。

举报
缓冲区溢出攻击的原理分析与防范1、前言1.1本课题的研究意义1.2缓冲区溢出国内外研究现状2、缓冲区溢出原理概述2.1、缓冲区溢出的概念2.2、堆栈的定义2.3缓冲区溢出攻击原理2.4缓冲区溢出攻击方式2.4.1在程序的地址空间里安排适当的代码的方法2.4.2控制程序转移到攻击代码的方法2.5缓冲区溢出影响及危害3、缓冲区溢出的防御方法3.1、写正确的代码的方法3.2、通过操作系统使得缓冲区不可执行,从而阻止攻击者植入攻击代码3.3、利用编译器的数组边界检查来实现缓冲区的保护3.4、在程序指针失效前进行完整性检查4、总结与展望4.1全文总结4.2展望5、参...
缓冲区溢出攻击的原理分析与防范
1、前言1.1本课题的研究意义1.2缓冲区溢出国内外研究现状2、缓冲区溢出原理概述2.1、缓冲区溢出的概念2.2、堆栈的定义2.3缓冲区溢出攻击原理2.4缓冲区溢出攻击方式2.4.1在程序的地址空间里安排适当的代码的2.4.2控制程序转移到攻击代码的方法2.5缓冲区溢出影响及危害3、缓冲区溢出的防御方法3.1、写正确的代码的方法3.2、通过操作系统使得缓冲区不可执行,从而阻止攻击者植入攻击代码3.3、利用编译器的数组边界检查来实现缓冲区的保护3.4、在程序指针失效前进行完整性检查4、总结与展望4.1全文总结4.2展望5、参考文献主要目录本课题的研究意义   随着信息与网络技术的发展,以及这些技术在军事领域的不断渗透,计算机网络已成为连接未来信息化战场的枢纽。对计算机的攻击,能够获得大量宝贵的情报以及达到其它武器系统所不能及的效果。因此对以计算机为基础的网络攻击与防护就自然成为军事领域密切关注的问题。近年来,缓冲区溢出漏洞的广泛性和破坏性受到国内外信息安全研究领域的极切关注。从1988年CERT(计算机紧急响应小组)成立以来,统计到的安全威胁事件每年以指数增长。缓冲区溢出攻击作为网络攻击一种主要形式占所有系统攻击总数的80%以上[1]。这种缓冲区溢出漏洞可以发生在不同的操作系统以及不同的应用程序上。  缓冲区溢出攻击是黑客攻击的主要手段,给网络信息安全带来了越来越大的危害。已有的防御手段研究相对滞后,目前国内外的研究大多集中在某个具体漏洞的利用与防范上,缺乏全面的研究。并且现有的缓冲区溢出防御手段也存在诸多不足之处。论文主要是对缓冲区溢出攻击的原理分析与防范进行深入研究。  论文首先介绍了缓冲区和堆栈的基本概念,研究并总结了缓冲区溢出的原理和过程,并介绍了一些常用的攻击方法。在此基础上,论文研究并总结了目前防御缓冲区溢出攻击的一些常用方法,主要从主客观两方面来讨论。主观方面,主要是要提高程序员编写代码的质量,形成良好的编程风格;客观方面,主要是从系统和软件做一些相关的检查和优化。缓冲区溢出国内外研究现状   缓冲区溢出攻击作为一种主流的攻击手法,早在20世纪80年代,国外就有人开始讨论溢出攻击,例如1988年的Morris蠕虫,利用的攻击方法之一就是Fingerd的缓冲区溢出,这次蠕虫攻击导致全球6000多台机器被感染,损失巨大,由此,缓冲区溢出问题逐渐得到人们的重视。1989年,Spafford提交了一份分析,描述了VAX机上的BSD版unix的Fingerd的缓冲区溢出程序的技术细节,从而引起了一部分安全人士对这个研究领域的重视。1996年AlephOne详细的描述了Linux系统中栈的结构和如何利用基于栈的缓冲区溢出。1997年,Smith综合以前的文章,提供了如何在各种Unix家庭中写缓冲区溢出Exploit更详细的指导原则。1998年来自“CultoftheDeadcow”的Dildog详细地介绍了如何利用Windows的溢出,他提出了利用栈指针的方法来完成跳转,返回固定的指向地址,不论是在出问题的程序中还是在动态链接库中,该固定地址都包含了用来利用栈指针完成跳转的汇编指令,这是缓冲区溢出利用一个重大的进步。 在国内,这方面技术的研究起步较晚,2000年左右,才有部分安全人士和黑客开始研究这个领域,最早中联绿盟的袁仁广做过一些工作,他使用暴力探索的办法来获取kernel32.dll的基址,代码量太多,也不够准确,2003年安全焦点峰会上Flashsky做了关于堆溢出的演讲[3],总结了堆溢出漏洞利用的方法。2005年San写了关于如何溢出WindowsCE的文章[4],WindowsCE是PDA和手机上使用非常广泛的嵌入式操作系统,该文介绍了WindowsCE内存管理,进程等基础知识,初步讨论了WindowsCE的缓冲区溢出问题,只是对Shellcode的解码效率不高。缓冲区溢出原理概述 缓冲区溢出的概念 缓冲区是内存中存放数据的地方,一般来说,它是“包含相同数据类型的实例的一个连续计算机内存块”[5],它保存了给定类型的数据。在C和C++中,缓冲区通常是使用数组和诸如malloc()和new这样的内存分配例程来实现的。最常见的缓冲区种类是简单的字符数组。 缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量,使得溢出的数据覆盖在合法数据上,理想的情况是程序检查数据长度并不允许输入超过缓冲区长度的字符,但是绝大多数程序都会假设数据长度总是与所分配的储存空间相匹配,这就为缓冲区溢出埋下隐患。操作系统所使用的缓冲区又被称为“堆栈”.。在各个操作进程之间,指令会被临时储存在“堆栈”当中,“堆栈”也会出现缓冲区溢出。比如这样或许你还不明白?堆栈的定义    堆栈是内存中的一个连续的块。一个叫堆栈指针的寄存器(SP)指向堆栈的栈顶,堆栈的底部是一个固定地址。堆栈有一个特点就是,后进先出。也就是说,后放入的数据第一个取出。它支持两个操作,PUSH和POP。PUSH是将数据放到栈的顶端,POP是将栈顶的数据取出。    在高级语言中,程序函数调用和函数中的临时变量都用到堆栈,参数的传递和返回值时也用到了堆栈,通常对局部变量的引用是通过给出它们对SP的偏移量来实现的。另外还有一个基址指针(FP,在Intel芯片中是BP),许多编译器实际上是用它来引用本地变量和参数的。通常,参数的相对FP的偏移是正的,局部变量是负的。当程序中发生函数调用时,计算机做如下操作:首先把参数压入堆栈;然后保存指令寄存器(IP)中的内容,作为返回地址(RET);第三个放入堆栈的是基址寄存器(FP);然后把当前的栈指针(SP)拷贝到FP,作为新的基地址;最后为本地变量留出一定空间,把SP减去适当的数值。缓冲区溢出攻击原理    缓冲区攻击指的是一种常见且危害很大的系统攻击手段,通过向程序的缓冲区写入超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其他的指令,以达到攻击的目的。当正常的使用者操作程序的时候,所进行的操作一般不会超出程序的运行范围,数据被添加到分配给该缓冲区的内存块之外,会发生缓冲区溢出,这时候就会出现数据泄漏或侵占了其它的数据空间。    缓冲区溢出的攻击原理就是越过缓冲区长度界限向程序中输入超出其常规长度的内容,造成缓冲区的溢出从而破坏程序的堆栈,使程序运行出现特殊的问题转而执行其它指令。 一般来说,单单的缓冲区溢出,并不会产生安全问题,如果将溢出送到能够以root权限或其它超级权限运行命令的区域去执行某些代码或者运行一个shell的时候,该程序就是以超级用户的权限控制了计算机。缓冲区溢出攻击方式 缓冲区溢出攻击的目的在于扰乱具有某些特权运行的程序的功能,这样可以使得攻击者取得程序的控制权,如果该程序具有足够的权限,那么整个主机就被控制了。一般而言,攻击者攻击root程序,然后执行类似“exec(sh)”的执行代码来获得root权限的shell。为了达到这个目的,攻击者必须达到如下的两个目标: (1)在程序的地址空间里安排适当的代码。 (2)通过适当的初始化寄存器和内存,让程序跳转到入侵者安排的地址空间执行。 缓冲区溢出攻击方式可以分为两种,一种在程序的地址空间里安排适当的代码的方法;另一种控制程序转移到攻击代码的方法。论文简介这两种攻击的方式。在程序的地址空间里安排适当的代码的方法 有两种在被攻击程序地址空间里安排攻击代码的方法: (1)、植入法: 攻击者向被攻击的程序输入一个字符串,程序会把这个字符串放到缓冲区里。这个字符串包含的资料是可以在这个被攻击的硬件平台上运行的指令序列。在这里,攻击者用被攻击程序的缓冲区来存放攻击代码。缓冲区可以设在任何地方:堆栈(stack,自动变量)、堆(heap,动态分配的内存区)和静态资料区。 (2)、利用已经存在的代码: 有时,攻击者想要的代码已经在被攻击的程序中了,攻击者所要做的只是对代码传递一些参数。比如,攻击代码要求执行“exec(“/bin/sh”)”,而在libc库中的代码执行“exec(arg)”,其中arg使一个指向一个字符串的指针参数,那么攻击者只要把传入的参数指针改向指向”/bin/sh”。攻击方式图示控制程序转移到攻击代码的方法 分类的基准是攻击者所寻求的缓冲区溢出的程序空间类型。原则上是可以任意的空间,实际上,许多的缓冲区溢出都是用暴力的方法来寻求改变程序指针的。这类程序的不同之处就是程序空间的突破和内存空间的定位不同。主要有以下三种: 1、活动纪录(ActivationRecords): 每当一个函数调用发生时,调用者会在堆栈中留下一个活动纪录,它包含了函数结束时返回的地址。攻击者通过溢出堆栈中的自动变量,使返回地址指向攻击代码。通过改变程序的返回地址,当函数调用结束时,程序就跳转到攻击者设定的地址,而不是原先的地址。这类的缓冲区溢出被称为堆栈溢出攻击(StackSmashingAttack),是目前最常用的缓冲区溢出攻击方式。 2、函数指针(FunctionPointers): 函数指针可以用来定位任何地址空间。例如:“void(*foo)()”声明了一个返回值为void的函数指针变量foo。所以攻击者只需在任何空间内的函数指针附近找到一个能够溢出的缓冲区,然后溢出这个缓冲区来改变函数指针。在某一时刻,当程序通过函数指针调用函数时,程序的流程就按攻击者的意图实现了。它的一个攻击范例就是在Linux系统下的superprobe程序。长跳转缓冲区(Longjmpbuffers): 在C语言中包含了一个简单的检验/恢复系统,称为setjmp/longjmp。意思是在检验点设定“setjmp(buffer)”,用“longjmp(buffer)”来恢复检验点。然而,如果攻击者能够进入缓冲区的空间,那么“longjmp(buffer)”实际上是跳转到攻击者的代码。象函数指针一样,longjmp缓冲区能够指向任何地方,所以攻击者所要做的就是找到一个可供溢出的缓冲区。一个典型的例子就是Perl5.003的缓冲区溢出漏洞;攻击者首先进入用来恢复缓冲区溢出的的longjmp缓冲区,然后诱导进入恢复模式,这样就使Perl的解释器跳转到攻击代码上了。缓冲区溢出影响及危害 在几乎所有计算机语言中,不管是新的语言还是旧的语言,使缓冲区溢出的任何尝试通常都会被该语言本身自动检测并阻止(比如通过引发一个异常或根据需要给缓冲区添加更多空间),但是有两种语言不是这样:C和C++语言。C\C++语言由于其针灵活应用的特性,通常允许让额外的数据乱写到其余内存的任何位置,而这种情况可能被利用从而导致意想不到的结果。而且,用C\C++编写正确的代码来始终如一地处理缓冲区溢出则更为困难;很容易就会意外地导致缓冲区溢出。更重要的一点就是C\C++的应用非常广泛,例如,RedHatLinux7.1中86%的代码行都是用C或C++编写的。因此,大量的代码对这个问题都是脆弱的,出现缓冲区溢出也就是常见的事情。  缓冲区溢出漏洞很容易被蠕虫病毒利用造成了很大的危害,如2001年7月19日,CodeRed蠕虫爆发,造成的损失估计超过20亿美元[2],2001年9月18日,Nimda蠕虫被发现,造成的损失更大,超过26亿美元,2002年Slapper蠕虫出现,2003年1月25日Slammer蠕虫爆发,2004年5月1日,“震荡波”被发现,这几个病毒对网络安全造成的破坏之大是前所未有的。而以上病毒都利用了缓冲区溢出漏洞。缓冲区溢出的防御方法 缓冲区溢出攻击占了远程网络攻击的绝大多数,这种攻击可以使得一个匿名的Internet用户有机会获得一台主机的部分或全部的控制权。如果能有效地消除缓冲区溢出的漏洞,则很大一部分的安全威胁可以得到缓解。 目前有4种基本的方法保护缓冲区免受缓冲区溢出的攻击和影响。 3.1、写正确的代码的方法   编写正确的代码是一件非常有意义的工作,特别象编写C语言那种风格自由而容易出错的程序,这种风格是由于追求性能而忽视正确性的传统引起的。尽管花了很长的时间使得人们知道了如何编写安全的程序,具有安全漏洞的程序依旧出现。因此人们开发了一些工具和技术来帮助经验不足的程序员编写安全正确的程序。   最简单的方法就是用grep来搜索源代码中容易产生漏洞的库的调用,比如对strcpy和sprintf的调用,这两个函数都没有检查输入参数的长度。事实上,各个版本C的库均有这样的问题存在。   此外,人们还开发了一些高级的查错工具,如faultinjection等。这些工具的目的在于通过人为随机地产生一些缓冲区溢出来寻找代码的安全漏洞。还有一些静态分析工具用于侦测缓冲区溢出的存在。   虽然这些工具帮助程序员开发更安全的程序,但是由于C语言的特点,这些工具不可能找出所有的缓冲区溢出漏洞。所以,侦错技术只能用来减少缓冲区溢出的可能,并不能完全地消除它的存在。通过操作系统使得缓冲区不可执行,从而阻止攻击者植入攻击代码 通过使被攻击程序的数据段地址空间不可执行,从而使得攻击者不可能执行被植入被攻击程序输入缓冲区的代码,这种技术被称为非执行的缓冲区技术。在早期的Unix系统设计中,只允许程序代码在代码段中执行。但是Unix和MSWindows系统由于要实现更好的性能和功能,往往在数据段中动态地放入可执行的代码,这也是缓冲区溢出的根源。为了保持程序的兼容性,不可能使得所有程序的数据段不可执行。 但是可以设定堆栈数据段不可执行,这样就可以保证程序的兼容性。Linux和Solaris都发布了有关这方面的内核补丁。因为几乎没有任何合法的程序会在堆栈中存放代码,这种做法几乎不产生任何兼容性问题,除了在Linux中的两个特例,这时可执行的代码必须被放入堆栈中: ⑴信号传递 Linux通过向进程堆栈释放代码然后引发中断来执行在堆栈中的代码来实现向进程发送Unix信号。非执行缓冲区的补丁在发送信号的时候是允许缓冲区可执行的。 ⑵GCC的在线重用 研究发现gcc在堆栈区里放置了可执行的代码作为在线重用之用。然而,关闭这个功能并不产生任何问题,只有部分功能似乎不能使用。 非执行堆栈的保护可以有效地对付把代码植入自动变量的缓冲区溢出攻击,而对于其它形式的攻击则没有效果。通过引用一个驻留的程序的指针,就可以跳过这种保护。其它的攻击可以采用把代码植入堆或者静态数据段中来跳过保护。 这种方法有效地阻止了很多缓冲区溢出的攻击,但是攻击者并不一定要植入攻击代码来实现缓冲区溢出的攻击,所以这种方法还是存在很多弱点的。利用编译器的数组边界检查来实现缓冲区的保护 数组边界检查能防止所有的缓冲区溢出的产生和攻击。这是因为只要数组不能被溢出,溢出攻击也就无从谈起。为了实现数组边界检查,则所有的对数组的读写操作都应当被检查以确保对数组的操作在正确的范围内。最直接的方法是检查所有的数组操作,但是通常可以采用一些优化的技术来减少检查的次数。目前有以下的几种检查方法: (1)Jones&Kelly:C的数组边界检查  RichardJones和PaulKelly开发了一个gcc的补丁,用来实现对C程序完全的数组边界检查。由于没有改变指针的含义,所以被编译的程序和其它的gcc模块具有很好的兼容性。更进一步的是,他们由此从没有指针的表达式中导出了一个“基”指针,然后通过检查这个基指针来侦测表达式的结果是否在容许的范围之内。当然,这样付出的性能上的代价是巨大的:对于一个频繁使用指针的程序,比如向量乘法,将由于指针的频繁使用而使速度比本来慢30倍。这个编译器目前还很不成熟;一些复杂的程序还不能在这个上面编译,执行通过。 (2)CompaqC编译器 Compaq公司为AlphaCPU开发的C编译器支持有限度的边界检查(使用check_bounds参数)。 这些限制是: 只有显式的数组引用才被检查,比如“a[3]”会被检查,而“*(a+3)”则不会。由于所有的C数组在传送的时候是指针传递的,所以传递给函数的的数组不会被查。带有危险性的库函数如strcpy不会在编译的时候进行边界检查,即便是指定了边界检查。   由于在C语言中利用指针进行数组操作和传递是如此的频繁,因此这种局限性是非常严重的。通常这种边界检查用来程序的查错,而且不能保证不发生缓冲区溢出的漏洞。 (3)Purify:内存存取检查 Purify是C程序调试时查看内存使用的工具。Purify使用“目标代码插入”技术来检查所有的内存存取。通过用Purify连接工具连接,可执行代码在执行的时候数组的所有引用来保证其合法性。这样带来的性能上的损失要下降3-5倍。 (4)类型-安全语言   所有的缓冲区溢出漏洞都源于C语言缺乏类型安全。如果只有类型-安全的操作才可以被允许执行,这样就不可能出现对变量的强制操作。如果作为新手,可以推荐使用具有类型-安全的语言如Java。但是作为Java执行平台的Java虚拟机是C程序,因此通过攻击JVM的一条途径是使JVM的缓冲区溢出。 这个方法使得缓冲区溢出不可能出现,从而完全消除了缓冲区溢出的威胁,但是相对而言代价比较大。在程序指针失效前进行完整性检查 程序指针完整性检查和边界检查有略微的不同,程序指针完整性检查在程序指针被引用之前检测到它的改变。因此,即使一个攻击者成功地改变了程序的指针,由于系统事先检测到了指针的改变,因此这个指针将不会被使用。   与数组边界检查相比,这种方法不能解决所有的缓冲区溢出问题;采用其它的缓冲区溢出攻击方法就可以避免这种检测。但是这种方法在性能上有很大的优势,而且在兼容性也很好,而且目前为止,只有很少一部分使用非指针变量的攻击能逃脱指针保护的检测。    最普通的缓冲区溢出形式是攻击活动然后在堆栈中植入代码。这种类型的攻击在1996年中有很多记录。而非执行堆栈和堆栈保护的方法都可以有效防卫这种攻击。非执行堆栈可以防卫所有把代码植入堆栈的攻击方法,堆栈保护可以防卫所有改变活动记录的方法。这两种方法相互兼容,可以同时防卫多种可能的攻击。  虽然这些工具帮助程序员开发更安全的程序,但是由于C语言的特点,这些工具不可能找出所有的缓冲区溢出漏洞。所以,侦错技术只能用来减少缓冲区溢出的可能,并不能完全地消除它的存在。除非程序员能保证他的程序万无一失,否则还是要用到以下部分的内容来保证程序的可靠性能。  剩下的攻击基本上可以用指针保护的方法来防卫,但是在某些特殊的场合需要用手工来实现指针保护。全自动的指针保护需要对每个变量加入附加字节,这样使得指针边界检查在某些情况下具有优势。最为有趣的是,缓冲区溢出漏洞--Morris蠕虫使用了现今所有方法都无法有效防卫的方法,但是由于过于复杂的缘故却很少有人用到。总结与展望 4.1全文总结  缓冲区溢出攻击与防御涉及到网络与信息安全的多个领域。网络与操作系统平台的复杂性、应用服务软件的多样性以及安全管理的复杂性等等因素交织在一起,不可避免的导致缓冲区溢出问题的复杂性,不同的缓冲区溢出漏洞存在不同的历史阶段,攻击不同的系统平台与应用软件,以往的研究基本上是针对某一类漏洞的分析,全面综合的研究相当缺乏,本文介绍了缓冲区和堆栈的基本概念,研究并总结了缓冲区溢出的原理和过程,并介绍了一些常用的攻击方法。并总结了目前防御缓冲区溢出攻击的一些常用方法。 4.2展望  缓冲区溢出的攻击与防御的技术正在日新月异的发展,各种网络渗透技术不断出现,而随着人们安全意识的加强,漏洞的利用越来越困难,要求的技术越来越高级,本文在这方面做了一些工作,但还有很多其他相关技术需要研究,现在Windows的内核溢出已经被发现,希望在以后的工作中,在这些方面都有进一步的研究。缓冲区的防御现在是一个大的难题,希望在以后的工作中能有所突破。参考文献 [1]CERT.CERT/CCstatistics.http://www.cert.org/stats/cert_stats.html,Feb.2005. [2]赵有恩,周守军,缓冲区溢出攻击的分析及防范,NADLQ@O2:--IRLLSSS2 T(9:F./2.8ULV1-*.;(LW$$X$YLX?YX2:-U; [3]flashSky.Windows2003堆溢出及其利用技术深入研究. http://www.xfocus.net/projects/Xcon/2003/Xcon2003_FlashSky.pdf.2003. [4]San.HackingWindowsCEPhrackMagazine,PhrackMagazine,06(63),2005. [5]Linux大本营,Linux操作系统下经典攻击软件大荟萃, http://www.linuxdby.com/?action_viewnews_itemid_724.html,2006-12-29。
/
本文档为【缓冲区溢出攻击的原理分析与防范】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索