缓冲区溢出攻击的分析及防范策略概要

上传人:m**** 文档编号:173499265 上传时间:2022-12-11 格式:DOCX 页数:10 大小:28.79KB
收藏 版权申诉 举报 下载
缓冲区溢出攻击的分析及防范策略概要_第1页
第1页 / 共10页
缓冲区溢出攻击的分析及防范策略概要_第2页
第2页 / 共10页
缓冲区溢出攻击的分析及防范策略概要_第3页
第3页 / 共10页
资源描述:

《缓冲区溢出攻击的分析及防范策略概要》由会员分享,可在线阅读,更多相关《缓冲区溢出攻击的分析及防范策略概要(10页珍藏版)》请在装配图网上搜索。

1、缓冲区溢出攻击的分析及防范策略摘 要 随着Internet及相关信息技术的迅速发展,网上的电子商务 呈现出极大的增长势头,但是投入的增多意味着风险也随之而来,网络安全问 题成为各种网上活动需要考虑的头等大事。本文重点探讨一下缓冲区溢出对计 算机系统造成的危害。因为几十年来,缓冲区溢出一直引起许多严重的安全性 问题。近年由 CERT/CC(Computer Emergency Response Term/Coodination Center)发布的忠告中关于缓冲区溢出漏洞占56.76%以上。本文首先解释了缓 冲区溢出的概念,从程序语言本身存在缺陷,不够健壮的角度出发,对缓冲区 溢出的原理进行了详

2、细的阐述;再次,通过一个会导致缓冲区溢出的程序代码 对缓冲区溢出攻击的产生进行了实例分析,同时还对Unix操作系统下的缓冲区 溢出攻击进行了有针对性的分析,并总结出缓冲区溢出攻击的类型;最后,结 合缓冲区溢出攻击的类型,从系统管理和软件开发两个角度提出了缓冲区溢出 攻击的防范策略。关键字:缓冲区溢出 攻击AbstractWith the development of Internet and information technology, the great growth has appeared out in E-Commerce. But this trend lead to more v

3、enture, network security issue has become the cardinal task that various kinds of online activity need to consider.At present, the biggest problem on network is that computer software is usually not stalwart enough, sometimes such barrier will cause catastrophic result, especially when being utilize

4、d maliciously by the lawless person, the harm will hard to estimate.Buffer overflow attacking is a seriously problem in network security and cause serious security problems in recently years. Some program language have pestilent bug, for example, C program language doesnt check the border of the arr

5、ay of number is apt to cause the buffer overflow, and therefore possibly cause the failure of program processing and paralysis of computer.This paper analysis deeply the principle and possible of buffer overflow attacking, and point out buffer overflows potential dangers. At last, according to the k

6、inds of buffer overflow attacking, I put forward my own opinion of precautionary measures on buffer overflow attacking. Key Words: buffer overflowattacking一 缓冲区与出的概念及原理11何谓缓冲区溢出 缓冲区是用户为程序运行时在计算机中申请得的一段连 续的内存,它保存了给定类型的数据。缓冲区溢出指的是一种常见且危害很大 的系统攻击手段,通过向程序的缓冲区写入超出其长度的内容,造成缓冲区的 溢出,从而破坏程序的堆栈,使程序转而执行其他的指令,以

7、达到攻击的目 的。 12缓冲区溢出的原理 从上面的缓冲区溢出概念可以看出,缓冲区 溢出就是将一个超过缓冲区长度的字符串置入缓冲区的结果,这是由于程序设 计语言的一些漏洞,如C/C+语言中,不对缓冲区、数组及指针进行边界检 查,(strcpy()、strcat()、sprintf()、gets()等语句),在程序员也忽略对 边界进行检查而向一个有限空间的缓冲区中置入过长的字符串可能会带来两种 结果:一是过长的字符串覆盖了相邻的存储单元,引起程序运行失败,严重的 可导致系统崩溃;另一种后果是利用这种漏洞可以执行任意指令,甚至可以取得系统特权,由此而引发多种攻击方法。 缓冲区溢出对系统的安全性带来很

8、大 的威胁,比如向程序的有限空间的缓冲区中置入过长的字符串,造成缓冲区溢 出,从而破坏程序的堆栈,使程序转去执行其他的指令,如果这些指令是放在 有Root权限的内存里,那么一旦这些指令得到了运行,入侵者就以Root的权 限控制了系统,这也是我们所说的U2R(User to Root Attacks)攻击。例如在 Unix系统中,使用一些精心编写的程序,利用SUID程序(如FDFORMAT)中存 在的缓冲区溢出错误就可以取得系统超级用户权限,在Unix取得超级用户权限 就意味着黑客可以随意控制系统。为了避免这种利用程序设计语言漏洞而对系 统的恶意攻击,我们必须要仔细分析缓冲区溢出攻击的产生及类型

9、,从而做出 相应的防范策略。 “xebx2ax5ex89x76x08xc6x46x07x00xc7x46x0cx00x00x00” “x00xb8x0bx00x00x00x89xf3x8dx4ex08x8dx56x0cxcdx80” “xb8x01x00x00x00xbbx00x00x00x00xcdx80xe8xdlxffxff” “xffx2fx62x69x6ex2fx73x68x00x89xecx5dxc3” 事例程序如下: /test/ char shellcode=“xebx2ax5ex89x76x08xc6x46x07x00xc7x46x0cx00x00x00” “x00xb8x0

10、bx0 0x00x00x89xf3x8dx4ex08x8dx56x0cxcdx80” “xb8x01x00x00x00xbbx00x00x00x00xcdx80xe8xdlxffxff” “xffx2fx62x69x6ex2fx73x68x00x89xecx5dxc3”; void f(char *src) char dest4; memcpy(dest,src,12); void main() int shellentry3; shellentry0=(int)shellcode; shellentry1=(int)shellcode; shellentry2=(int)shellcode;

11、 f(shellen try); 由以上程序可以看出缓冲区溢出攻击的关键:因为memcpy 并不检验边界,所以dest溢出时,使shellcode的地址覆盖了子程序的返回地 址,当子程序执行ret指令时,CPU的指令指针寄存器EIP指向shellcode,从 而执行shellcode。这里讨论一个现实中的Unix环境下,利用缓冲区溢出的 到一个Shell的行攻击方法的实现。其中,S代表Shellcode,A代表填写的返 回地址,由于Shellcode在虚地址的高端,所以这个返回地址(32bit) 一般不 会含有零字节:(1)启动一个一个Shell的代码Shellcode的获得 通常的获得方法是

12、先用高级语言编写同样功能的程序,然后用调试工具抽取 必须的二进制代码。高级语言程序如下: shellcode.c #include void main() char *name2; name0=”bin/sh”; name1=NULL; execve(nameO,name,NULL); exit(0); 把上述程序编译之后,可以用 gdb 得到上面程序的汇编代码及二进制代码,适当优化后即可得到二进制的 Shellcode。这里要解决的一个问题是,无论Shellcode被装置到内存的什么 位置,字符串“/bin/sh”的地址都可以得到。解决方法是在“/bin/sh”之前 加一条CALL指令,这样

13、当CALL被执行时,“/bin/sh”的地址将被自动压入堆 栈,紧接着用一条popl指令即可获得这个地址。Shellcode的结构如下:(J 代表JMP指令,C代表CALL指令,S代表启动Shell的代码,s代表串“/bin/sh”,A 指向 Shellcode 的起始地址)。SCO Unix 下的 Shellcode 的 汇编代码如下:Jmp 0x2a# 3 bytes#跳到CALL指令处Popl %esi# 1 byte#把由CALL指令压入堆栈的串#地址送到 esi movl %esi, 0x8(%esi)# 3 bytes movb $0x0,0x7(%esi)# 4 bytes mo

14、vl $0x0, 0xc(%esi)# 7bytes movl $0xb, %eax# 5 bytesmovl %esi, %ebx execve(name0,name,NULL); bytes leal 0xc(%esi) , %edx $0x80$0x1,%eax$0x0,%ebx$0x800x2f处 .string ”/bin/sh”# 2 bytes # 执行leal 0x8(%esi) , %ecx # 3# 3 bytes int# 2 bytes movl# 5 bytes#执行 exit(0) movl# 5 bytes int# 2 bytes call -# 5 bytes

15、#跳到 popl %esi 指令# 8 bytes利用gdb的x命令可以得到上述汇编代码的二进制代码。 (2)猜测被溢出的缓冲区的位置有了 shellcode还不够,在溢出一个缓冲区时,还必须使被溢出的返回地址正 确指向shellcode。在Unix环境下,当我们去溢出另外一个程序的没有边界检 查的buffer时,通常只会得到一个Segmentation fault (段错误),程序退 出,再没有其他信息。这就是由于返回地址不正确引起的。 为了正确获得溢出 的缓冲区在堆栈的位置,所以需要推测shellcode的起始位置,即被溢出的缓 冲区buffer的位置。Unix环境下,每个进程启动时的初始

16、堆栈的虚存位置时 一样的。利用下面的程序可以近似的得到这个位置(在环境变量不同、传入的 命令行参数不同时,这个值略有变动): unsigned long get_esp(void)asm_(“movl %esp,%eax”); void main(void) printf(“0x%x ”,get_esp(); 通常,进程运行时向堆栈中写入的数据不 会超过数百个字节或数千个字节,有了这个起始地址,用简单的一个个尝试的 方法也是可以攻击的。但显然这不是一种效率高的方法。解决的办法是在缓冲 区前端填充几百字节NOP指令,只要猜测的地址落在NOP指令序列中,仍可以 执行shellcode,从而成倍地增

17、加猜中的机会。(3)攻击代码中字节代码为零的消除Unix的程序中大量使用了 strcpy函数,shellcode中含有 0x00,由于通常是攻击一个字符缓冲区,如果攻击代码中含有0,则它会被当 成字符串的结尾处理,于是攻击代码被截断。消除的方法是对代码做适当的变 换,因此在这里需要使用一些汇编程序设计技巧,把shellcode转换成不含 0x00的等价代码。(4)被攻击的缓冲区很小的情况当缓冲区太小,可能使 NOP部分或shellcode部分覆盖返回地址ret,导致缓冲区起址到返回地址的距 离不足以容纳shellcode,这样设定的跳转地址就没有用上,攻击代码不能被 正确执行。 一个方法就是利

18、用环境变量。当一个进程启动时,环境变量被映射 到进程堆栈空间的顶端。这样就可以把攻击代码(NOP串+Shellcode)放到一 个环境变两中,而在被溢出的缓冲区中填上攻击代码的地址。比如,可以把 shellcode放在环境变量中,并把环境变量传入到要攻击的程序中,就可以对 有缓冲区溢出漏洞的程序进行攻击。利用这样方法,还可以设计很大的攻击代 码。 22缓冲区溢出攻击的类型 缓冲区溢出的目的在于扰乱具有某些特 权运行程序的功能,这样就可以让攻击者取得程序的控制权,如果该程序具有 足够的权限,那么整个主机甚至服务器就被控制了。一般而言,攻击者攻击 root程序,然后执行类似“exec(sh)的执行

19、代码来获得root的shell。但并 不总是这样,为了达到这个目的,攻击者必须达到如下两个目标:l在程序的地址空间里安排适当的代码 l通过适当地初始化寄存器和存储器,让程序跳转到安排好的地址空间执行。 我们可 以根据这两个目标来对缓冲区溢出攻击进行分类。 1在程序的地址空间里安 排适当的代码有两种在被攻击程序地址空间里安排攻击代码的方法:(1) 植入法: 攻击者向被攻击的程序输入一个字符串,程序会把这个 字符串放到缓冲区里。这个字符串所包含的数据是可以在这个被攻击的硬件平 台运行的指令流。在这里攻击者用被攻击程序的缓冲区来存放攻击代码,具体 方式有以下两种差别:a.攻击者不必为达到此目的而溢出

20、任何缓冲区,可以 找到足够的空间来放置攻击代码;b缓冲区可设在任何地方:堆栈(存放自 动变量)、堆(动态分配区)和静态数据区(初始化或未初始化的数据)。(2)利用已经存在的代码 有时候攻击者所要的代码已经存在于被攻击的程序中了,攻击者所要做的只是对代码传递一些参数,然后使程序跳转到想 要执行的代码那里。比如,共及代码要求执行“exec(bin/sh) ”,而在 libc库中的代码执行“exec(arg) ”,其中arg是一个指向字符串的指针参 数,那么攻击者只要把传入的参数指针改向指向“/bin/sh”,然后调转到 libc库中相应的指令序列即可。2.控制程序转移到攻击代码的方法所有这 些方法

21、都是在试图改变程序的执行流程,使之跳转到攻击代码。其基本特点就 是给没有边界检查或有其他弱点的程序送出一个超长的缓冲区,以达到扰乱程 序正常执行顺序的目的。通过溢出一个缓冲区,攻击者可以用几乎暴力的方法(穷尽法)改写相邻的程序空间面直接跳过系统的检查。 这里的分类基准是攻 击者所寻求的缓冲区溢出的程序空间类型。原则上可以是任意的空间。比如起 初的Morris Worm (莫尔斯蠕虫)就是使用了 fingerd程序的缓冲区溢出,扰 乱fingerd要执行的文件的名字。实际上许多的缓冲区溢出是用暴力的方法来 寻求改变程序指针的。这类程序不同的地方就是程序空间的突破和内存空间的 定位不同。一般来说,

22、控制程序转移到攻击代码的方法有以下几种:(1)函数返回地址 每当一个函数调用发生时,调用者会在堆栈中留下函数返回地址,它包含了函数结束时返回的地址。攻击者通过溢出这些自动变 量,使这个返回地址指向攻击代码,这样就通过改变程序的返回地址,当函数 调用结束时,程序跳转到攻击者设定的地址,而不是原先的地址。这类的缓冲 区进出被称为“stack smashing attack”,是目前常用的缓冲区溢出攻击方 式。(2)函数指针“Void(*foo)() ”中声明了一个返回值为Void函数指针的变量foo。函数指针定位任何地址空间,所以攻击者只需在任何空间 内的函数指针附近找到一个能够溢出的缓冲区,然后

23、溢出来改变函数指针,当 程序通过函数指针调用函数时,程序的流程就会发生改变而实现攻击者的目 的。(3)长跳转缓冲区在C语言中包含了一个简单的检验/恢复系统,称为“setjmp/longjmp”,意思是在检验点设定“setjmp(buffer)”,用 longjmp(buffer)来恢复检验点。然而,如果攻击时能够进入缓冲区的空间, 那么“longjmp(buffer) ”实际上是跳转到攻击者的代码。像函数指针一样, longjmp缓冲区能够指向任何地方,所以攻击者所要做的就是找到一个可供溢 出的缓冲区。一个典型的例子就是Perl 5.003,攻击者首先进入用来恢复缓冲 区溢出的longjmp缓

24、冲区,然后诱导进入恢复模式,这样就使Perl的解释器跳 转到攻击代码上了。 3.综合代码植入和流程控制技术 最简单和常见的溢出缓 冲区攻击类型就是在一个字符串里综合了代码植入和激活记录。攻击者定位一 个可供溢出的自动变量,然后向程序传递一个很大的字符串,在引发缓冲区溢 出改变激活记录的同时植入了代码(因为C语言程序员通常在习惯上只为用户 和参数开辟很小的缓冲区)。 代码植入和缓冲区溢出不一定要在一次动作内完 成,攻击者可以在一个缓冲区内放置代码(这个时候并不能溢出缓冲区),然 后攻击者通过溢出另一个缓冲区来转移程序的指针。这样的方法一般用来解决 可供溢出的缓冲区不够大(不能放下全部的代码)。如

25、果攻击者试图使用已经 常驻的代码而不是从外部植入代码,他们通常必须把代码做为参数。举例说 明,在libc (几乎所有的C程序都用它来连接)中的一部分代码段会执行“exec(some thing),其中的some thing就是参数,攻击者使用缓冲区溢出改 变程序的参数,然后利用另一个缓冲区溢出,使程序指针指向libc中的特定的 代码段。三 缓冲区溢出攻击的防范策略 缓冲区溢出攻击的防范是和整个系统的安全性分不开的。如果整个网络系统的安全设计很差,则遭受 缓冲区溢出攻击的机会也大大增加。针对缓冲区溢出,我们可以采取多种防范 策略。 1系统管理上的防范策略 (1)关闭不需要的特权程序 由于缓冲区溢

26、出只有在获得更高的特权时才有意义,所以带有特权的Unix下的 suid程序和Windows下由系统管理员启动的服务进程都经常是缓冲区溢出攻击 的目标。这时候,关闭一些不必要的特权程序就可以降低被攻击的风险。如 Solaris下的fdformat是个有缓冲区溢出漏洞的suid程序,因为这个格式化 软盘的命令用的较少,最直接的措施是去掉这个程序或者去掉suid位。当有缓 冲区溢出漏洞的程序还没有补丁时,就可以用这种方法。 (2)及时给程序漏洞打补丁 这是漏洞出现后最迅速有效的补救措施。大部分的入侵是利用 一些已被公布的漏洞达成的,如能及时补上这些漏洞,无疑极大的增强了系统 抵抗攻击的能力。 这两种

27、措施对管理员来说,代价都不是很高,但能很有效地 防止住大部分的攻击企图。 2软件开发过程中的防范策略 发生缓冲区溢出的 主要及各要素是:数组没有边界检查而导致的缓冲区溢出;函数返回地址或函 数指针被改变,使程序流程的改变成为可能;植入代码被成功的执行等等。 所 以针对这些要素,从技术上我们就可以采取一定的措施。 (1)编写正确的代 码 只要我们在所有拷贝数据的地方进行数据长度和有效性的检查,确保目标缓 冲区中数据不越界并有效,则就可以避免缓冲区溢出,更不可能使程序跳转到 恶意代码上。但是诸如C/C+自身是一种不进行强类型和长度检查的一种程序 设计语言,而程序员在编写代码时由于开发速度和代码的简

28、洁性,往往忽视了 程序的健壮性,从而导致缓冲区溢出,因此我们必须从程序语言和系统结构方 面加强防范。 很多不安全程序的出现是由于调用了一些不安全的库函数,这些 库函数往往没有对数组边界进行检查。这些函数有strcpy()、sprintf()、 strcat()等,所以一种简单的方法是利用grep搜索源程序,找出对这些函数的 调用,然后代以更安全的函数,如strncpy()替换strcpy ()。进一步的查找可 以是检查更广范围的不安全操作,如在一个不定循环中对数组的赋值等。 可用 的另一种措施是漏洞探测。利用一些工具,人为随机地产生一些缓冲区溢出来 寻找代码的安全漏洞。已有这方面的一些高级的查

29、错工具,如fault injection等。(2)缓冲区不可执行通过使被攻击程序的数据段地址空间不 可执行,从而使得攻击者不可能执行被植入被攻击程序输入缓冲区的代码,这 种技术被称为缓冲区不可执行技术。事实上,很多老的Unix系统都是这样设计 的,但是近来的Unix和MS Windows系统为实现更好的性能和功能,往往在数 据段中动态地放入可执行的代码。所以为了保持程序的兼容性不可能使得所有 程序的数据段不可执行。但是我们可以设定堆栈数据段不可执行,这样就可以 最大限度地保证了程序的兼容性。Linux和Solaris都发布了有关这方面的内 核补丁。因为几乎没有任何合法的程序会在堆栈中存放代码,

30、这种做法几乎不 产生任何兼容性问题。 通过使被攻击程序的数据段地址空间不可执行,从而使 得攻击者不可能执行被殖入被攻击程序输入缓冲区的代码,这种技术被称为非 执行的缓冲区技术。事实上,很多老的Unix系统都是这样设计的,但是近来的 Unix和MS Windows系统由于实现更好的性能和功能,往往在在数据段中动态 地放入可执行的代码。所以为了保持程序的兼容性不可能使得所有程序的数据 段不可执行。Linux和Solaris也发布了有关这方面的内核补丁。因为几乎没 有任何合法的程序会在堆栈中存放代码,这种做法几乎不产生任何兼容性问 题,除了在Linux中的两个特例,这时可执行的代码必须被放入堆栈中:

31、a.信 号传递:Linux通过向进程堆栈释放代码然后引发中断来执行在堆栈中的代码 来实现向进程发送Unix信号。非执行缓冲区的补丁在发送信号的时候是允许缓 冲区可执行的。b.GCC的在线重用:研究发现gcc在堆栈区里放置了可执行 的代码作为在线重用之用。然而,关闭这个功能并不产生任何问题,只有部分 功能似乎不能使用。非执行堆栈的保护可以有效地对付把代码植入自动变量的 缓冲区溢出攻击,而对于其他形式的攻击则没有效果。通过引用一个驻留的程 序的指针,就可以跳过这种保护措施。其他的攻击可以采用把代码殖入堆或者 静态数据段中来跳过保护。(3)改进C语言函数库C语言中存在缓冲区溢出 攻击隐患的系统函数有

32、很多。例如gets(), sprintf(),strcpy(),strcat(),fscanf(),scanf(), vsprintf()等。可以开发出更安全的封装了若 干已知易受堆栈溢出攻击的库函数。修改后的库函数实现了原有功能,但在某 种程度上可以确保任一缓冲区溢出都被控制在现有堆栈帧之内。(4)数组边 界检查可以说缓冲区溢出的根本原因是没有数组边界检查,当数组被溢出的时 候,一些关键的数据就有可能被修改,比如函数返回地址、过程帧指针、函数 指针等。同时,攻击代码也可以被植入。因此,对数组进行边界检查,使超长 代码不可能植入,这样就完全没有了缓冲区溢出攻击产生的条件。只要数组不 能被溢出,

33、溢出攻击就无从谈起。为了实现数组边界检查,则所有的对数组的 读写操作都应当被检查,以确保对数组的操作在正确的范围内。最直接的方法 是检查所有的数组操作,但是会使性能下降很多,通常可以采用一些优化的技 术来减少检查的次数。(5)使堆栈向高地址方向增长缓冲区溢出的一个重要 要素是植入的代码成功地被执行。最常见的是被植入的代码放在堆栈区中。通 过修改操作系统核心,在核心层引入保护机制,限制代码在堆栈区的执行,这 样,缓冲区溢出攻击就不可能成功。到目前为止,我们讨论利用函数返回地址 控制程序转移到攻击代码的攻击方法时,有一个基本的前提,那就是当堆栈被 压入数据时,栈顶向低地址方向增长,只有这样,缓冲区

34、溢出时才可能覆盖低 地址处的函数返回地址指针,从而控制程序转移到攻击代码。如果我们使用的 机器堆栈压入数据时向高地址方向前进,那么无论缓冲区如何溢出,都不可能 覆盖低地址处的函数返回地址指针,也就避免了缓冲区溢出攻击。但是这种方 法仍然无法防范利用堆和静态数据段的缓冲区进行溢出的攻击。(6)程序指 针完整性检查程序指针完整性检查是针对上述缓冲区溢出的另一个要素阻 止由于函数返回地址或函数指针的改变而导致的程序执行流程的改变。它的原 理是在每次在程序指针被引用之前先检测该指针是否已被恶意改动过,如果发 现被改动,程序就拒绝执行。因此,即使一个攻击者成功地改变程序的指针, 由于系统事先检测到了指针

35、的改变,因此这个指针不会被使用。与数组边界检 查相比,这种方法不能解决所有的缓冲区溢出问题。但这种方法在性能上有很 大的优势,而且兼容性也很好。程序指针完整性检查大体上有三个研究方向: 第一,手写的堆栈检测;第二,堆栈保护;第三,保护指针。在手写的堆栈检 测中会介绍Snarskii为FreeBSD开发了一套定制的能通过监测cpu堆栈来确定 缓冲区溢出的libc。在堆栈保护中会介绍我们自己的堆栈保护方法所开发的一 个编译器,它能够在函数调用的时候自动生成完整性检测代码。最后在保护指 针中介绍正在开发中的指针保护方法,这种方法类似于堆栈保护,它提供对所 有程序指针的完整性的保护。1)手写的堆栈监测

36、Snarskii为FreeBSD开发 了一套定制的能通过监测cpu堆栈来确定缓冲区溢出的libc。这个应用完全用 手工汇编写的,而且只保护libc中的当前有效纪录函数。这个应用达到了设计 要求,对于基于libc库函数的攻击具有很好的防卫,但是不能防卫其它方式的 攻击。 2)堆栈保护:编译器生成的有效纪录完整性检测 堆栈保护是一种提供 程序指针完整性检查的编译器技术,通过检查函数活动纪录中的返回地址来实 现。堆栈保护作为gcc的一个小的补丁,在每个函数中,加入了函数建立和销 毁的代码。加入的函数建立代码实际上在堆栈中函数返回地址后面加了一些附 加的字节,如图2示。而在函数返回时,首先检查这个附加

37、的字节是否被改动 过。如果发生过缓冲区溢出的攻击,那么这种攻击很容易在函数返回前被检测 到。 但是,如果攻击者预见到这些附加字节的存在,并且能在溢出过程中同样 地制造他们,那么他就能成功地跳过堆栈保护的检测。通常,我们有如下的两 种方案对付这种欺骗:a.终止符号:利用在C语言中的终止符号如 O(null),CR,LF,-1(EOF)等不能在常用的字符串函数中使用,因为这些函数 一旦遇到这些终止符号,就结束函数过程了。b.随机符号:利用一个在函数 调用时产生的一个32位的随机数来实现保密,使得攻击者不可能猜测到附加字 节的内容。而且,每次调用,附加字节的内容都在改变,也无法预测。 通过检 查堆栈

38、的完整性的堆栈保护法是从Synthetix方法演变来的。Synthetix方法 通过使用准不变量来确保特定变量的正确性。这些特定的变量的改变是程序实 现能预知的,而且只能在满足一定的条件才能可以改变。这种变量我们称为准 不变量。Synthetix开发了一些工具用来保护这些变量。攻击者通过缓冲区溢 出而产生的改变可以被系统当做非法的动作。在某些极端的情况下,这些准不 变量有可能被非法改变,这是就需要堆栈保护来提供更完善的保护了。 实验的 数据表明,堆栈保护对于各种系统的缓冲区溢出攻击都有很好的保护作用,并 能保持较好的兼容性和系统性能。早先我们报告的堆栈保护所能抑制的漏洞都 在表一中列出。随后,

39、我们用堆栈保护的方法重新构造了一个完整的Linux系 统(Red Hat5.1)。然后我们用XFree86-3.3.2-5和lsof的漏洞对此进行了攻 击,结果表明,这个系统有效地抵御了这些攻击。这些分析表明,堆栈保护能 有效抵御现在的和将来的基于堆栈的攻击。堆栈保护版本的Red Hat Linux 5.1已经在各种系统上运行了多年,包括个人的笔记本电脑和工作组文件服务 器。从我们的Web服务器上可以得到这个版本,而且在我们的邮件列表里已经 有了55个成员。出了仅有的一次例外,这个系统和本来的系统工作完全一样, 这表明堆栈保护并不对系统的兼容性构成很大的影响。 我们已经用各种性能测 试来评测堆

40、栈保护的性能。Mircobenchmarks的结果表明在函数的调用,堆栈 保护中增加了系统的开销。而在网络的测试中(需要用到堆栈保护的地方), 则表明这种开销不是很大。我们的第一个测试对象是SSH,它提供了极强的加 密和认证,用来替代Berkeley的r系列指令。SSH使用了软件加密,因此系统 的占用的带宽不大,我们用网络间复制一个大的文件来测试带宽: scp bigsource localhost:bigdest测试结果表明:堆栈保护几乎不影响SSH的网 络吞吐性能。第二个测试使用了 Apache Web服务器。如果这种服务器存在基 于堆栈的攻击,那么攻击者就可以轻易地取得Web服务器的控制

41、权,允许攻击 者阅读隐秘的内容和肆意篡改主页的内容。同时,Web服务器也是对性能和带 宽要求较高的一个服务器部件。我们用WebStone对带有和不带堆栈保护的 Apache Web服务器进行了测试,测试的结果在表二中列出。和SSH 样,他 们的性能几乎没有区别。在客户数目较少的情况下,带有保护的服务器性能比 不带保护的略微好些,在客户端数目多的时候,不带保护的性能好些。在最坏 的情况下,带保护的服务器比不带保护的要差8%的连接性能,而在平均延时上 保持优势。象以前一样,我们把这些归结为噪声的影响。因此,我们的结论 是:堆栈保护对Web服务器系统性能没有重大的影响。3)指针保护:编译器 生成程序

42、指针完整性检查 在堆栈保护设计的时候,冲击堆栈构成了缓冲区溢出 攻击的常见的一种形式。有人推测存在一种模板来构成这些攻击(在1996年的 时候)。从此,很多简单的漏洞被发现,实施和补丁了,很多攻击者开始用在 第二部分中描述的更一般的方法实施缓冲区溢出攻击。 指针保护是堆栈保护针 对这种情况的一个推广。通过在所有的代码指针之后放置附加字节来检验指针 在被调用之前的合法性。如果检验失败,会发出报警信号和退出程序的执行, 就如同在堆栈保护中的行为一样。这种方案有三点需要注意:a.附加字节的 定位: 附加字节的空间是在被保护的变量被分配的时候分配的,同时在被保护 字节初始化过程中被初始化。这样就带来了

43、问题;为了保持兼容性,我们不想 改变被保护变量的大小,因此不能简单地在变量的结构定义中加入附加字。还 有,对各种类型也有不同附加字节数目。b.检查附加字节:每次程序指针被 引用的时候都要检查附加字节的完整性。这个也存在问题;因为“从存取器 读”在编译器中没有语义;编译器更关心指针的使用,而各种的优化算法倾向 于从存储器中读入变量。c.还有随着不同类型的变量,读入的方法也各自不 同。已经开发的指针保护的一个原型(还是基于gcc的),通过附加字节来保 护静态分配的函数指针,但不适用于结构和数组类型。这个计划还远没有完 成。一旦这个项目完成了,那么用它和堆栈保护构成的可执行代码将不会受到 缓冲区溢出

44、的攻击了。 目前为止,只有很少一部分使用非指针变量的攻击能逃 脱指针保护的检测。但是,可以通过在编译器上强制对某一变量加入附加字节 来实现检测,这时需要程序员自己手工加入相应的保护了。 (7)利用编译器 将静态数据段中的函数地址指针存放地址和其他数据的存放地址分离 我们知道 缓冲区溢出的一个基本条件是在缓冲区的高地址附近存放着可供溢出覆盖的函 数地址指针,如果我们破坏了这一条件,就会使缓冲区溢出不能覆盖函数地址 指针。比如,我们可以假定编译器在编译程序时会将静态数据段中的函数地址 指针存放地址和其他数据的存放地址隔开相当大的一段距离,例如数10M,数 100M,这样才会迫使攻击者只有送入长的出

45、乎想象数据才能抵达函数地址指针 存放地址并覆盖它,以这样的不可操作性来制止攻击者实现攻击意图。另外, 我们还可以使这两种数据段间的线形地址空间不分配物理地址并设置为不可读 写,这些都可以通过硬件实现,这样每当缓冲区溢出进入这段区域,就会出现 地址保护错误,从而阻止了缓冲区溢出攻击。 另外一种较为简洁的方法是始终 保持使静态数据段中的函数地址指针存放地址低于其他数据的存放地址。但是 这个方法仅仅是防止了静态数据段中的缓冲区溢出攻击,而不能避免堆的缓冲 区溢出攻击,因为编译器和操作系统并不知道用户申请的内存是用来存放函数 地址指针还是其他数据,从而无法为其隔离分配内存。表1是针对静态数据 段、堆栈

46、和堆的缓冲区溢出的防范策略,其中没有把边界检查包括在内,因为 它能有效地防止所有的缓冲区溢出,但其运行开销也是惊人的。表的最上面一 行是攻击代码所植入的内存空间,表的最左面一列是溢出方法,而中间单元就 是相应的防范策略。 表1 缓冲区溢出的防范策略堆栈 (Stack Buffer)堆 (Heap Buffer)静态数据段 (Static Buffer)活动记录堆栈保护 非执行的缓冲区堆栈保护堆栈保护函数指针指针保护 非执行的缓冲区指针保护指针保护长跳转缓冲区指针保护 非执行的缓冲区指针保护指针保护其它变量手工的指针保护 非执行的缓冲区手工的指针保护手工的指针保护 为了防止静态数据段、堆栈和堆这

47、三种数据段中 的一个缓冲区溢出覆盖另一个段中的函数地址指针,我们应该为这三种数据段 隔离分配线形地址空间。 四 总结 缓冲区溢出是当今很流行 的一种网络攻击方法,它易于攻击而且危害严重,给系统的安全带来了极大的 隐患。因此,如何及时有效地检测出计算机网络系统入侵行为,已越来越成为 网络安全管理的一项重要内容。缓冲区溢出的漏洞一般有以下几种情况: (1) 系统漏洞 如操作系统、服务器程序、数据库程序等,这种漏洞可 以通过升级软件、打安全“补丁”等方法来解决。 (2) 应用软件 在 软件开发过程中,如果程序员没有很强的安全意识和良好的编程习惯,也会产 生很多安全漏洞。 本文从上面的系统环境及程序设

48、计语言角度,对目前主要的 网络攻击方式:缓冲区溢出攻击的出现和原理进行了详细的分析,并根据缓冲 区溢出攻击的类型提出了相应的防范策略。 然而,飞速发展的网络技术还需要 我们继续对各种黑客攻击系统的方法做更多的关注和应付措施的探索,为网络 安全做出更大的实践意义的研究。 参考文献 1 张小斌,严望佳, 黑客分析与防范技术M北京清华大学出版社,1999。2陈意云编译原理和技术M,合肥,中国科技大学出版社,1997。3汪立东,方滨兴,Unix缓冲区溢出攻击:技术原理、防范与检测,计算机工程与应用,2000(2)。4 谭毓安,网络攻击防护编码设计,北京希望电子出版社,2002。5 为了防止静态数据段、

49、堆栈和堆这三种数据段中的一个缓冲区溢出覆盖另一个段中的函数地址指针,我们应该为这三种数据段隔离 分配线形地址空间。四 总结 缓冲区溢出是当今很流行的一种网络攻击方法,它易于攻击而且危害严重,给系统的安全带来了极大的隐 患。因此,如何及时有效地检测出计算机网络系统入侵行为,已越来越成为网 络安全管理的一项重要内容。缓冲区溢出的漏洞一般有以下几种情况:(1) 系统漏洞 如操作系统、服务器程序、数据库程序等,这种漏洞可 以通过升级软件、打安全“补丁”等方法来解决。 (2) 应用软件 在 软件开发过程中,如果程序员没有很强的安全意识和良好的编程习惯,也会产 生很多安全漏洞。 本文从上面的系统环境及程序设计语言角度,对目前主要的 网络攻击方式:缓冲区溢出攻击的出现和原理进行了详细的分析,并根据缓冲 区溢出攻击的类型提出了相应的防范策略。 然而,飞速发展的网络技术还需要 我们继续对各种黑客攻击系统的方法做更多的关注和应付措施的探索,为网络 安全做出更大的实践意义的研究。 参考文献 1 张小斌,严望佳, 黑客分析与防范技术M北京清华大学出版社,1999。2陈意云编译原理和技术M,合肥,中国科技大学出版社,1997。3汪立东,方滨兴,Unix缓冲区溢出攻击:技术原理、防范与检测,计算机工程与应用,2000(2)。4 谭毓安,网络攻击防护编码设计,北京希望电子出版社,2002。5

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!