缓冲区溢出攻击的原理分析与防范
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
• •
• •
长跳转缓冲区(Longjmp buffers):
• 在C语言中包含了一个简单的检验/恢复系统, 称为setjmp/longjmp。意思是在检验点设定 “setjmp(buffer)”,用“longjmp(buffer)”来恢复检 验点。然而,如果攻击者能够进入缓冲区的空间, 那么“longjmp(buffer)”实际上是跳转到攻击者的 代码。象函数指针一样,longjmp缓冲区能够指向 任何地方,所以攻击者所要做的就是找到一个可 供溢出的缓冲区。一个典型的例子就是Perl 5.003 的缓冲区溢出漏洞;攻击者首先进入用来恢复缓冲 区溢出的的longjmp缓冲区,然后诱导进入恢复模 式,这样就使Perl的解释器跳转到攻击代码上了。
比如
这wk.baidu.com 或许 你还 不明 白?
堆栈的定义
• 堆栈是内存中的一个连续的块。一个叫堆栈指针的寄存器(SP) 指向堆栈的栈顶,堆栈的底部是一个固定地址。堆栈有一个特点就是, 后进先出。也就是说,后放入的数据第一个取出。它支持两个操作, PUSH和POP。PUSH是将数据放到栈的顶端,POP是将栈顶的数据 取出。 • 在高级语言中,程序函数调用和函数中的临时变量都用到堆栈, 参数的传递和返回值时也用到了堆栈,通常对局部变量的引用是通过 给出它们对SP的偏移量来实现的。另外还有一个基址指针(FP,在 Intel芯片中是BP),许多编译器实际上是用它来引用本地变量和参数 的。通常,参数的相对FP的偏移是正的,局部变量是负的。当程序中 发生函数调用时,计算机做如下操作:首先把参数压入堆栈;然后保 存指令寄存器(IP)中的内容,作为返回地址(RET);第三个放入堆栈的 是基址寄存器(FP);然后把当前的栈指针(SP) 拷贝到FP,作为新的 基地址;最后为本地变量留出一定空间,把SP减去适当的数值。
•
•
缓冲区溢出攻击方式
• 缓冲区溢出攻击的目的在于扰乱具有某些特权运行的程 序的功能,这样可以使得攻击者取得程序的控制权,如果 该程序具有足够的权限,那么整个主机就被控制了。一般 而言,攻击者攻击root程序,然后执行类似“exec(sh)” 的执行代码来获得root权限的shell。为了达到这个目的, 攻击者必须达到如下的两个目标: • (1)在程序的地址空间里安排适当的代码。 • (2)通过适当的初始化寄存器和内存,让程序跳转到入 侵者安排的地址空间执行。 • 缓冲区溢出攻击方式可以分为两种,一种在程序的地址 空间里安排适当的代码的方法;另一种控制程序转移到攻 击代码的方法。论文简介这两种攻击的方式。
•
•
缓冲区溢出国内外研究现状
• 缓冲区溢出攻击作为一种主流的攻击手法,早在20世纪80年代,国外就有人开始 讨论溢出攻击,例如1988年的Morris蠕虫,利用的攻击方法之一就是Fingerd的缓冲区 溢出,这次蠕虫攻击导致全球6000多台机器被感染,损失巨大,由此,缓冲区溢出问 题逐渐得到人们的重视。1989年,Spafford提交了一份分析报告,描述了VAX机上的 BSD版unix的Fingerd的缓冲区溢出程序的技术细节,从而引起了一部分安全人士对这 个研究领域的重视。1996年AlephOne详细的描述了Linux系统中栈的结构和如何利用 基于栈的缓冲区溢出。1997年,Smith综合以前的文章,提供了如何在各种Unix家庭中 写缓冲区溢出Exploit更详细的指导原则。1998年来自“Cult of the Dead cow”的Dildog 详细地介绍了如何利用Windows的溢出,他提出了利用栈指针的方法来完成跳转,返 回固定的指向地址,不论是在出问题的程序中还是在动态链接库中,该固定地址都包 含了用来利用栈指针完成跳转的汇编指令,这是缓冲区溢出利用一个重大的进步。 在国内,这方面技术的研究起步较晚,2000年左右,才有部分安全人士和黑客开始 研究这个领域,最早中联绿盟的袁仁广做过一些工作,他使用暴力探索的办法来获取 kernel32.dll的基址,代码量太多,也不够准确,2003年安全焦点峰会上Flashsky做了 关于堆溢出的演讲[3],总结了堆溢出漏洞利用的方法。2005年San写了关于如何溢出 Windows CE的文章[4],Windows CE是PDA和手机上使用非常广泛的嵌入式操作系统, 该文介绍了Windows CE内存管理,进程等基础知识,初步讨论了Windows CE的缓冲 区溢出问题,只是对Shellcode的解码效率不高。
3、缓冲区溢出的防御方法
3.1、写正确的代码的方法 3.2、通过操作系统使得缓冲区不可执行,从而阻止攻击者植入攻击代码 3.3、利用编译器的数组边界检查来实现缓冲区的保护 3.4、在程序指针失效前进行完整性检查
4、总结与展望
4.1全文总结
4.2 展望
5、参考文献
本课题的研究意义
随着信息与网络技术的发展,以及这些技术在军事领域 的不断渗透,计算机网络已成为连接未来信息化战场的枢纽。 对计算机的攻击,能够获得大量宝贵的情报以及达到其它武 器系统所不能及的效果。因此对以计算机为基础的网络攻击 与防护就自然成为军事领域密切关注的问题。近年来,缓冲 区溢出漏洞的广泛性和破坏性受到国内外信息安全研究领域 的极切关注。从1988年CERT(计算机紧急响应小组)成立以来, 统计到的安全威胁事件每年以指数增长。缓冲区溢出攻击作 为网络攻击一种主要形式占所有系统攻击总数的80%以上[1]。 这种缓冲区溢出漏洞可以发生在不同的操作系统以及不同的 应用程序上。 缓冲区溢出攻击是黑客攻击的主要手段,给网络信息安全 带来了越来越大的危害。已有的防御手段研究相对滞后,目 前国内外的研究大多集中在某个具体漏洞的利用与防范上, 缺乏全面的研究。并且现有的缓冲区溢出防御手段也存在诸 多不足之处。论文主要是对缓冲区溢出攻击的原理分析与防 范进行深入研究。 论文首先介绍了缓冲区和堆栈的基本概念,研究并总结了 缓冲区溢出的原理和过程,并介绍了一些常用的攻击方法。 在此基础上,论文研究并总结了目前防御缓冲区溢出攻击的 一些常用方法,主要从主客观两方面来讨论。主观方面,主 要是要提高程序员编写代码的质量,形成良好的编程风格; 客观方面,主要是从系统和软件做一些相关的检查和优化。
主要目录 1、前言
1.1本课题的研究意义 1.2缓冲区溢出国内外研究现状
2、缓冲区溢出原理概述
2.1、缓冲区溢出的概念 2.2、堆栈的定义 2.3 缓冲区溢出攻击原理 2.4 缓冲区溢出攻击方式 2.4.1在程序的地址空间里安排适当的代码的方法 2.4.2控制程序转移到攻击代码的方法 2.5缓冲区溢出影响及危害
•
缓冲区溢出的防御方法
• • • • 缓冲区溢出攻击占了远程网络攻击的绝大多数,这种攻击可以使得一个 匿名的Internet用户有机会获得一台主机的部分或全部的控制权。如果能有 效地消除缓冲区溢出的漏洞,则很大一部分的安全威胁可以得到缓解。 目前有4种基本的方法保护缓冲区免受缓冲区溢出的攻击和影响。 3.1、写正确的代码的方法 编写正确的代码是一件非常有意义的工作,特别象编写C语言那种风格 自由而容易出错的程序,这种风格是由于追求性能而忽视正确性的传统引起 的。尽管花了很长的时间使得人们知道了如何编写安全的程序,具有安全漏 洞的程序依旧出现。因此人们开发了一些工具和技术来帮助经验不足的程序 员编写安全正确的程序。 最简单的方法就是用grep来搜索源代码中容易产生漏洞的库的调用,比 如对strcpy和sprintf的调用,这两个函数都没有检查输入参数的长度。事实 上,各个版本C的标准库均有这样的问题存在。 此外,人们还开发了一些高级的查错工具,如fault injection等。这些工 具的目的在于通过人为随机地产生一些缓冲区溢出来寻找代码的安全漏洞。 还有一些静态分析工具用于侦测缓冲区溢出的存在。 虽然这些工具帮助程序员开发更安全的程序,但是由于C语言的特点, 这些工具不可能找出所有的缓冲区溢出漏洞。所以,侦错技术只能用来减少 缓冲区溢出的可能,并不能完全地消除它的存在。
•
缓冲区溢出原理概述
• 缓冲区溢出的概念 • 缓冲区是内存中存放数据的地方,一般来说,它是“包 含相同数据类型的实例的一个连续计算机内存块”[5],它 保存了给定类型的数据。在C和C++中,缓冲区通常是使 用数组和诸如malloc()和new这样的内存分配例程来实现 的。最常见的缓冲区种类是简单的字符数组。 • 缓冲区溢出是指当计算机向缓冲区内填充数据位数时超 过了缓冲区本身的容量,使得溢出的数据覆盖在合法数据 上,理想的情况是程序检查数据长度并不允许输入超过缓 冲区长度的字符,但是绝大多数程序都会假设数据长度总 是与所分配的储存空间相匹配,这就为缓冲区溢出埋下隐 患。操作系统所使用的缓冲区又被称为“堆栈”.。在各个操 作进程之间,指令会被临时储存在“堆栈”当中,“堆栈”也 会出现缓冲区溢出。
缓冲区溢出影响及危害
• 在几乎所有计算机语言中,不管是新的语言还是旧的 语言,使缓冲区溢出的任何尝试通常都会被该语言本身自 动检测并阻止(比如通过引发一个异常或根据需要给缓冲 区添加更多空间),但是有两种语言不是这样:C和C++ 语言。C\C++语言由于其针灵活应用的特性,通常允许让 额外的数据乱写到其余内存的任何位置,而这种情况可能 被利用从而导致意想不到的结果。而且,用C\C++编写正 确的代码来始终如一地处理缓冲区溢出则更为困难;很容 易就会意外地导致缓冲区溢出。更重要的一点就是C\C++ 的应用非常广泛,例如,Red Hat Linux 7.1中86%的代码 行都是用C或C++编写的。因此,大量的代码对这个问题 都是脆弱的,出现缓冲区溢出也就是常见的事情。 缓冲区溢出漏洞很容易被蠕虫病毒利用造成了很大的 危害,如2001年7月19日,CodeRed蠕虫爆发,造成的损 失估计超过20亿美元[2],2001年9月18日,Nimda蠕虫被 发现,造成的损失更大,超过26亿美元,2002年Slapper 蠕虫出现,2003年1月25日Slammer蠕虫爆发,2004年5 月1日,“震荡波”被发现,这几个病毒对网络安全造成 的破坏之大是前所未有的。而以上病毒都利用了缓冲区溢 出漏洞。
缓冲区溢出攻击原理
• 缓冲区攻击指的是一种常见且危害很大的系统攻击手段,通过向程序的 缓冲区写入超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈, 使程序转而执行其他的指令,以达到攻击的目的。当正常的使用者操作程序 的时候,所进行的操作一般不会超出程序的运行范围,数据被添加到分配给 该缓冲区的内存块之外,会发生缓冲区溢出,这时候就会出现数据泄漏或侵 占了其它的数据空间。 缓冲区溢出的攻击原理就是越过缓冲区长度界限向程序中输入超出其 常规长度的内容,造成缓冲区的溢出从而破坏程序的堆栈,使程序运行出现 特殊的问题转而执行其它指令。 一般来说,单单的缓冲区溢出,并不会产生安全问题,如果将溢出送到能 够以root权限或其它超级权限运行命令的区域去执行某些代码或者运行一个 shell的时候,该程序就是以超级用户的权限控制了计算机。
在程序的地址空间里安排适当的代 码的方法
• 有两种在被攻击程序地址空间里安排攻击代码的方法: • (1)、植入法: • 攻击者向被攻击的程序输入一个字符串,程序会把这个 字符串放到缓冲区里。这个字符串包含的资料是可以在这 个被攻击的硬件平台上运行的指令序列。在这里,攻击者 用被攻击程序的缓冲区来存放攻击代码。缓冲区可以设在 任何地方:堆栈(stack,自动变量)、堆(heap,动态分配 的内存区)和静态资料区。 • (2)、利用已经存在的代码: • 有时,攻击者想要的代码已经在被攻击的程序中了,攻 击者所要做的只是对代码传递一些参数。比如,攻击代码 要求执行“exec (“/bin/sh”)”,而在libc库中的代码执行 “exec (arg)”,其中arg使一个指向一个字符串的指针参 数,那么攻击者只要把传入的参数指针改向指 向”/bin/sh”。
攻击方式图示
控制程序转移到攻击代码的方法
• 分类的基准是攻击者所寻求的缓冲区溢出的程序空间类型。原则上是可以任 意的空间,实际上,许多的缓冲区溢出都是用暴力的方法来寻求改变程序指针 的。这类程序的不同之处就是程序空间的突破和内存空间的定位不同。主要 有以下三种: 1、活动纪录(Activation Records): 每当一个函数调用发生时,调用者会在堆栈中留下一个活动纪录,它包含 了函数结束时返回的地址。攻击者通过溢出堆栈中的自动变量,使返回地址 指向攻击代码。通过改变程序的返回地址,当函数调用结束时,程序就跳转 到攻击者设定的地址,而不是原先的地址。这类的缓冲区溢出被称为堆栈溢 出攻击(Stack Smashing Attack),是目前最常用的缓冲区溢出攻击方式。 2、函数指针(Function Pointers): 函数指针可以用来定位任何地址空间。例如:“void (* foo)()”声明了一个 返回值为void的函数指针变量foo。所以攻击者只需在任何空间内的函数指针 附近找到一个能够溢出的缓冲区,然后溢出这个缓冲区来改变函数指针。在 某一时刻,当程序通过函数指针调用函数时,程序的流程就按攻击者的意图 实现了。它的一个攻击范例就是在Linux系统下的superprobe程序。