APP下载

浅谈缓冲区溢出

2009-09-29于棣维刘永隆

新媒体研究 2009年14期
关键词:缓冲区安全性

于棣维 刘永隆

[摘要]详细阐述常见的缓冲区溢出。针对这些缓冲区溢出提出相应的防范策略,以此来增强系统的安全性。

[关键词]缓冲区 溢出 安全性

中图分类号:TP3文献标识码:A 文章编号:1671-7597(2009)0720067-01

一、缓冲区溢出概述

(一)缓冲区溢出的概念。缓冲区是内存中存放数据的地方,一般来说,它是“包含相同数据类型的实例的一个连续计算机内存块”,它保存了给定类型的数据。在C和C++中,缓冲区通常是使用数组和诸如malloc()和new()这样的内存分配例程来实现的。最常见的缓冲区种类是简单的字符数组。

缓冲区溢出指的是一种常见且危害很大的系统攻击手段,通过向程序的缓冲区写入超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其他的指令,以达到攻击的目的。

(二)缓冲区溢出攻击原理。当正常的使用者操作程序的时候,所进行的操作一般不会超出程序的运行范围,数据被添加到分配给该缓冲区的内存块之外,会发生缓冲区溢出,这时候就会出现数据泄漏或侵占了其它的数据空间。

缓冲区溢出的攻击原理就是越过缓冲区长度界限向程序中输入超出其常规长度的内容,造成缓冲区的溢出从而破坏程序的堆栈,使程序运行出现特殊的问题转而执行其它指令。

一般来说,单单的缓冲区溢出,并不会产生安全问题,如果将溢出送到能够以root权限或其它超级权限运行命令的区域去执行某些代码或者运行一个shell的时候,该程序就是以超级用户的权限控制了计算机。

(三)缓冲区溢出分类。缓冲区溢出,主要是由于不良的编程习惯引起的。CC++语言之所以长盛不衰,而且应用范围非常广,主要原因在于它给编程人员编程提供了更大的灵活性,具有高效、快速的特点。而与此同时它也提供了很多容易使人出现编程漏洞的方法,比如gets()、scanf()、sprintf()等等,缺乏安全有效、简单易行的字符串处理后果,还忽略了错误的后果。常见危险的CC++语言的API及其说明。一般来说,可以将缓冲区溢出分为以下几类:栈溢出、堆溢出、数组索引错误、格式化字符串bug、以及Unicode(统一字符串编码标准)和ANSI(美国国家标准协会)之间缓冲区大小不匹配等。1.栈溢出。如果向一个在栈上声明的缓冲区中复制数据,但是复制的数据量比缓冲区大的时候,就会发生静态缓冲区溢出(详例见程序3.2)。在栈上声明的各种变量的位置就紧靠着函数调用程序的返回地址,通常出现的错误就是用户输入的数据没有经过验证,就传递给类似strcpy()这样的函数,产生的后果就是调用函数的返回地址将被攻击者选择的某个地址覆盖。在一个常规攻击下,攻击者可以通过一个缓冲区溢出的应用程序执行对他们有益的操作,比如用户输入的内容并不是没有经过验证,或者仅仅几个有限的字符才在缓冲区中适用的情况。栈溢出相对来说非常简单,一个简单的程序员就可以实现,在真正的攻击中,只要将一组取得shell权限的代码转化为机器码,然后放在相应的位置,就可以对被攻击者造成巨大的破坏。2.堆溢出。堆(HEAP)是指通过malloc()或new动态分配的内存。在很多的操作系统里,大部分内存区是由内核一级分配的,而heap段是由应用程序分配的,在编译的时候被初始化。BSS是包含未被初始化的数据,在程序运行的时候才被分配,在被写入数据前,它可以被看作保持全零。堆溢出的思路很简单,覆盖重要的变量以达到自己的目的。而在实际操作的时候,这显得比较困难,尤其是源代码不可见的时候。第一,你必须确定哪个变量是重要的变量;第二,你必须找到一个内存地址比目标变量低的溢出点;第三,在特定目的下,你还必须让在为了覆盖目标变量而在中途覆盖了其他变量之后,程序依然能运行下去。3.数据索引错误。数组索引比起缓冲区溢出来说,出现的比较少一些,其实,字符串也是一个字符数组,既然字符串能写入任意的位置,数组也是一样。对于32位操作系统来说,0x100000000和0x00000000其实是同样一个值,所以,这就使得数据索引的值可能低于数组的基址。某著名的的漏洞就与截断误差有关,在一个UNIX操作系统上,root(超级用户)账户的用户ID为0。网络文件系统中的deamon(一种后台服务)将接受一个带符号整数的用户ID,并且检查这个数值是否为0,然后将这个值截取为一个无符号短整形(unsigned short)。这个缺陷允许用户输入0x10000的非0值,但是截断以后,就变成了0x0000,那么操作系统就会给它超级用户的权限。4.格式化字符串漏洞。这个漏洞相对来说不算大,而且在windows系统中很难发现这类漏洞,在早期的UNIX或类UNIX系统的应用程序中,发现了大量的格式化字符串bug。如果关注安全性较差的邮件列表,就会发现格式化字符串的bug了。比如说printf(input);就存在漏洞,该方法也许不知道如果格式化字符串。当然,使用printf(“%s”,input)就不存在漏洞了。这种漏洞很容易避免,只要制定相应的格式化就可以了。

二、缓冲区溢出防御

根据缓冲区溢出的原理,针对攻击者的攻击目标可作相应的保护,从而防御可能的缓冲区溢出攻击。目前针对缓冲区溢出主要有四种防御措施。

(一)编写正确安全的程序代码。针对实施攻击的对象常常是某个系统中的程序,可采用安全编程的方法,编写正确安全的代码从而防止缓冲区溢出。主要有尽可能限制拥有系统特权的程序尽可能采用安全的函数和用相应的工具和技术对原码中易产生漏洞的库调用进行检查等。

(二)对数组边界实施检查。缓冲区溢出攻击的各种方法都是利用了C语言中的无边界检查的漏洞,因此对于C中的数组边界实施检查以防止数组的边界溢出,即可杜绝缓冲区溢出的问题。

(三)对程序指针的完整性实施检查。程序指针的完整性检查是指对程序的引用指针在引用时实施检查,以检测其是否改变。即使攻击者成功地改变了程序指针,但由于系统检测到程序指针的改变,这一程序指针也不会被引用。

(四)对操作系统内核实行分段限制采用非执行缓冲区。这种方法通过修改操作系统的内核分段限制,使其不覆盖实际的栈空间,除去堆栈执行的特权,从而使攻击代码无法执行。

三、总结

缓冲区溢出的攻击与防御的技术正在日新月异的发展,各种网络渗透技术不断出现,而随着人们安全意识的加强,漏洞的利用越来越困难,要求的技术越来越高级,本文在这方面做了一些工作,但还有很多其他相关技术需要研究,现在Windows的内核溢出已经被发现,本文在这方面也没有谈及,希望在以后的工作中,在这些方面都有进一步的研究。缓冲区的防御现在是一个大的难题,希望在以后的工作中能有所突破。

参考文献:

[1](美)JAMES C.FOSTER,《缓冲区溢出攻击——检测、剖析与预防》,清华大学出版社,2006.12.

[2]王清,《0 day安全:软件漏洞分析技术》,电子工业出版社,2008.4.

猜你喜欢

缓冲区安全性
长效胰岛素联合口服降糖药治疗2型糖尿病的疗效与安全性
民航空中交通管制进近程序间隔安全性评估模型
西药临床应用中合理用药对其安全性的影响
鼻内镜手术治疗老年慢性鼻窦炎鼻息肉的疗效及安全性探讨
关于桥梁设计中的安全性与耐久性问题的几点思考
基于关键链的核电站大修项目缓冲区的设定方法
基于GIS的凤阳县初级中学布局分析研究
基于关键链技术的项目进度管理方法研究
初涉缓冲区
全氢罩式炉的安全性