缓冲区溢出的安全隐患

2010-09-17 09:43孙文豪
网络安全技术与应用 2010年5期
关键词:堆栈程序员缓冲区

孙文豪

大连市委党校信息中心 辽宁 116013

0 引言

很久以来,恶意的黑客和病毒开发者广泛使用漏洞和缓冲区溢出技术。Codered(红色代码)病毒就是最典型的例子,其传播所使用的技术可以充分体现网络时代网络安全与病毒的巧妙结合,将网络蠕虫、计算机病毒、木马程序合为一体,开创了网络病毒传播的新路,可称之为划时代的病毒。它可以完全取得所攻破计算机的所有权限为所欲为,可以盗走机密数据,严重威胁网络安全。Codered病毒采用了“缓存区溢出”的黑客技术,是通过微软公司IIS系统漏洞进行感染,它使IIS服务程序处理请求数据包时溢出,导致把此“数据包”当作代码运行,病毒驻留后再次通过此漏洞感染其它服务器。Codered不同于以往的文件型病毒和引导型病毒,并不将病毒信息写入被攻击服务器的硬盘。它只存在于内存,传染时不通过文件这一常规载体,而是借助这个服务器的网络连接攻击其它的服务器,直接从一台电脑内存传到另一台电脑内存。当本地 IIS服务程序收到某个来自“红色代码”发送的请求数据包时,由于存在漏洞,导致处理函数的堆栈溢出。当函数返回时,原返回地址已被病毒数据包覆盖,程序运行线跑到病毒数据包中,此时病毒被激活,并运行在 IIS服务程序的堆栈中。所以很多专门的反病毒公司对 Codered束手无策。之后又出现了Nimda(尼母达)和Badtrans(坏透了)病毒,破坏也非常大。

本文就是针对缓冲区溢出的安全隐患进行分析。

1 缓冲区溢出的定义

缓冲区通常是用来存储数量事先确定的、有限数据的存储区域。当一个程序试图将比缓冲区容量大的数据存储进缓冲区的时候,就会发生缓冲区溢出。

为了便于理解,打个比方。缓冲区溢出好比是将十磅的糖放进一个只能装五磅的容器里。一旦该容器放满了,余下的部分就溢出在柜台和地板上,弄得一团糟。由于计算机程序的编写者写了一些编码,但是这些编码没有对目的区域或缓冲区——五磅的容器——做适当的检查,看它们是否够大,能否完全装入新的内容——十磅的糖,结果可能造成缓冲区溢出的产生。如果打算被放进新地方的数据不适合,溢得到处都是,该数据也会制造很多麻烦。但是,如果缓冲区仅仅溢出,这只是一个问题。到此时为止,它还没有破坏性。当糖溢出时,柜台被盖住。可以把糖擦掉或用吸尘器吸走,还柜台本来面貌。与之相对的是,当缓冲区溢出时,过剩的信息覆盖的是计算机内存中以前的内容。除非这些被覆盖的内容被保存或能够恢复,否则就会永远丢失。也就是说数据超出缓冲区的大小,多余的数据就会溢出到相邻的内存地址,破坏该位置原有的有效数据,并且有可能改变执行路径和指令。可以将任意的数据注入到执行路径中,允许远程计算机的系统级访问,不仅使恶意的黑客,也会使自我复制的恶意代码获得未经授权的访问。

2 缓冲区溢出的种类

2.1 第一种堆栈缓冲区溢出

一个有漏洞的函数

一个大小为256字节的缓冲区,程序试图用512字节的字符A填满这个缓冲区。由于程序溢出了这个小的256字节的缓冲区,EIP(指令指针)是如何改变的。

当数据超出缓冲区大小的时候,剩下的数据就会覆盖堆栈的邻近区域原有的数据,包括一些重要的值,比如用来定义执行路径的指令指针(EIP)。通过覆盖返回的EIP地址,攻击者可以任意修改程序下一步将要执行的内容。

攻击者使用自己的恶意代码填充缓冲区,而不是A,使用填满了恶意代码的缓冲区地址来覆盖EIP(指向程序下一步将要执行的代码),而不是随机的数据来重写它。这改变了程序的执行路径,转而执行被注入的恶意代码。

堆栈缓冲区溢出的原因是在复制数据到缓冲区时没有检测数据大小。这经常是由于使用了不限制从一个位置复制到另一个位置的数据的大小的函数造成。如,strcpy是C语言中用来将一个缓冲区中的字符串复制到另一个缓冲区的函数,这个函数不检测接收字符串的缓冲区是否够大,所以可能溢出。

2.2 单字节越界溢出

程序员经常犯计数错误,会出现因为多出一个字节而溢出的现象,即单字节越界溢出。程序员希望使用相对安全的函数,例如strncat函数,但这并不一定使他们的程序更加安全。其实strncat函数经常导致溢出,它的行为相对太直观,在检查缓冲区大小的时候发生错误,经常会导致单字节越界溢出,因为程序员没有注意到数组的下标是从“0”开始。这种溢出只溢出一个字节,程序不能够重写 EIP。系统字节序是little-endian,程序可以覆盖EBP中的低位字节。根据代码的不同,可以用多种方式利用伪造的EBP。紧接着下一条指令是mov esp, ebp, 这使堆栈指针指向缓冲区的位置。伪造堆栈中的本地变量部分是经过处理的,程序返回后继续执行伪造的EIP处的指令,实际上执行的是堆栈中被注入的代码。程序员有一个普遍的误解,通过动态分配内存,避免使用堆栈,减少缓冲区溢出的可能。堆是动态分配的内存,这部分内存与分配给堆栈的是分离的,堆的建立和删除是动态的。事先不知道程序所需的内存大小时,或所需内存比堆栈大时,经常使用堆。堆溢出并不影响 EIP,溢出的堆覆盖数据或者修改指向数据和函数指针,也可导致拒绝服务攻击,使应用程序崩溃。函数指针(function pointer)溢出发生在使用回调函数(callback function)时,缓冲区后面是函数指针,不检查缓冲边界,就有可能覆盖函数指针。

2.3 格式化字符串漏洞

格式化字符串漏洞是因为程序员粗心大意的编码造成的,C语言的函数可以将字符串打印到文件、缓冲区、屏幕上。程序员利用函数的格式化控制输出格式。百分号(%)是转义符,后面字符表示输出的格式,如%d表示用十进制格式显示数值,%X表示用十六进制格式显示,并用大写字母。这就是格式说明符。一个使用错误格式化语法的伪程序:

这段程序想把“hello Beijing”显示在屏幕上,但函数的调用格式不正确,正确的应该是 Printf(“%s”,buffer);这种编程方式容易被攻击者利用,控制堆栈并注入任意的可执行代码。

安全研究人员检测到大多数的应用程序都含有这种漏洞,开发者依然不重视,还继续错误使用格式输出函数,造成现在很多应用程序存在漏洞,易受攻击。

3 结束语

缓冲区溢出的安全隐患经常被忽视,它只是黑客和病毒攻击的一种手段,破坏力可大可小,随着现代技术的不断更新,网络攻击和防御也平衡发展。保护计算机的最好办法就是经常安装安全补丁修补系统,基于主机以及基于网络的漏洞分析工具能够帮助找到内部网络中过期的有漏洞的系统,及时安装补丁。另外,漏洞分析工具还可以识别出该卸载的不需要不安全的服务。企业版及个人版的防火墙软件也有利于防范外来的和内部的攻击,需要在工作站、服务器、网关上安装防范机制,网络安全最重要。

[1]Halvar Flake,personal communication.2004.

[2]Peter szor and Frederic perriot.2003.

猜你喜欢
堆栈程序员缓冲区
基于行为监测的嵌入式操作系统堆栈溢出测试*
为了让妈妈看懂地图,一位“野生程序员”做了个小程序
怎样成为一名优秀程序员
基于网络聚类与自适应概率的数据库缓冲区替换*
程序员之子
基于堆栈自编码降维的武器装备体系效能预测
加班
一类装配支线缓冲区配置的两阶段求解方法研究
关键链技术缓冲区的确定方法研究
初涉缓冲区