杜绝缓冲区溢出?──CPU的硬件防毒功能
硬件周刊
近年来大范围的缓冲区溢出病毒攻击的流行,使CPU硬件防毒在今年大受重视。Intel公布了它的Execute Disable Bit硬件防毒技术;AMD则宣称早已在AMD Opteron系列中使用了Enhanced Virus Protection硬件防毒技术;Transmeta也不甘落后,推出了自己的AntiVirusNX硬件防毒技术,威盛也计划在下一代CPU C5J(Esther)中支持硬件防毒。
不过,要想真正发挥CPU硬件防毒功能,必需操作系统的配合。而这次微软表现相当积极,在已经推出的Windows XP SP2中就集成了数据执行预防(Data Execution Prevention)功能,对各个CPU厂商的CPU硬件防毒提供了操作系统支持。这次众多CPU厂商和微软难得的行动一致,可以说完全是缓冲区溢出攻击的推动。而这里的CPU硬件防毒也完全是针对缓冲区溢出攻击而设计的,所以要想真正了解CPU硬件防毒,必须从缓冲区溢出攻击开始说起。
一、病毒与木马的最爱──缓冲区溢出
早在1988年,美国康奈尔大学的计算机科学系研究生,23岁的莫里斯利用Unix fingered程序不限制输入长度的漏洞,输入512个字符后使缓冲器溢出。莫里斯又写了一段特别大的程序使他的恶意程序能以root(根)身份执行,并传播到其他机器上。2000年7月,微软Outlook以及Outlook Express被发现存在漏洞,让攻击者仅通过发送邮件就能危及目标主机的安全,只要邮件头部程序被运行,就会产生缓冲区溢出,并且触发恶意代码。
2001年8月,“红色代码”利用微软IIS漏洞产生缓冲区存溢出,成为攻击企业网络的“罪魁祸首”。2003年1月,Slammer蠕虫利用微软SQL漏洞产生缓冲区溢出对全球互联网产生冲击。2003年夏“冲击波”蠕虫病毒又利用微软RPC远程调用存在的缓冲区漏洞对Windows 2000/XP、Windows Server 2003进行攻击,波及全球网络系统。而以上所举仅仅是著名个例,据统计目前大范围流行的病毒攻击有近80%与缓冲区溢出漏洞有关,操作系统中超过50%的安全漏洞都是由内存溢出引起的,其中大多数与微软有关(这也是微软这次对硬件防毒技术极积配合的原因之一)。 除了病毒,木马的编写者也对缓冲区溢出漏洞青睐有加,该漏洞已成为木马感染电脑的主要手段之一。无论是病毒还是木马,它们都是利用缓冲区溢出,运行恶意程序,获得优先级,指示计算机破坏文件,改变数据,盗取敏感信息,设置后门访问点,感染或者攻击其他计算机。缓冲区溢出是目前导致攻击性的蠕虫病毒横行的主要原因。
二、系统隐形炸弹──忽视缓冲区检查语句
溢出,这是一个相当形象化的名词,我们向一个杯子中倒入超出它容积的水,水自然就会溢出来。同样,在计算机内部,程序使用的存储空间也都是事先规划好容量的,如果程序向一个容量有限的存储空间里写入过量数据,这些数据就会溢出存储空间。在计算机程序中用来暂时存放输入数据的临时空间被称为缓冲区,缓冲区的长度事先已经被程序或者操作系统定义好了,而当计算机程序向缓冲区内填充的数据位数超过了缓冲区本身的容量时,溢出的数据就会覆盖在合法数据上,这就是缓冲区溢出。
缓冲区溢出并不是不可避免的。在目前,绝大多数程序都会假设数据长度总是与所分配的存储空间相匹配,根本没有考虑如果写入数据过多的情形。并且只要编写程序时,提供了程序检查数据长度的功能,不允许输入超过缓冲区长度的字符串,那么缓冲区溢出就可以避免。但问题是在很早以前,计算机的功能并没有现在这么强大,计算机资源不够或者内存不足是编程者不编写缓冲区边界检查语句的理由。不要以为我们现在所用的程序的代码有多新,每个软件版本升级一次就重写一次代码那是不可能的,再加上代码的可重用性和借鉴性,很多五年、十年甚至更早的程序代码仍然工作在我们所使用的程序中,也就是说那时为了节省资源而省去缓冲区边界检查的程序,现在成了我们电脑中的隐形炸弹。
另一方面,缓冲区溢出与C语言和C++语言的先天缺陷也有关系。一些编程语言对于缓冲区溢出是具有免疫力的。例如Perl能够自动调节字节排列的大小,Ada95能够检查和阻止缓冲区溢出。但是被最广泛使用的C语言却没有建立检测机制。标准C语言具有许多复制和添加字符串的函数,这使得标准C语言很难进行边界检查。C++略微好一些,但是仍然存在缓冲区溢出。而大多数Windows、Linux、Unix系列的开发都依赖于C语言,所以缓冲区溢出成为操作系统、数据库等应用程序最普遍的漏洞之一。
三、覆盖、执行、控制──溢出攻击三部曲
我们再回过头来看看具体的缓冲区溢出。当过量的数据进入到缓冲区时,超出部分就会被写入其他缓冲区,而其他缓冲区存放的可能是数据、下一条指令的指针,或者是其他的输出内容,这些内容都被覆盖或者破坏掉。本来这种情形最多造成一个程序或者系统的崩溃。但问题是编译器通常将缓冲区放在“令人感兴趣的”数据结构旁边。例如,当某个函数的缓冲区紧邻堆栈,则在内存中该函数的返回地址紧靠在缓冲区之后。这时,如果攻击者可以使该缓冲区发生溢出,就可以覆盖函数的返回地址,从而在返回函数时,返回到攻击者定义的地址。也就是说当溢出的数据被“黑客”或者病毒制造者精心设计后,覆盖缓冲区的数据恰恰是“黑客”或者病毒的入侵程序代码,一旦多余字节被编译执行,“黑客”或者病毒就有可能为所欲为,获取系统的控制权。下面我们用一组图片说明这个问题。
四、对溢出说不──CPU硬件防毒基本原理
缓冲区溢出成为目前影响最大、范围最广的漏洞,而且可以预见随着更多程序和系统的缓冲区溢出漏洞被发现,很有可能像“冲击波”、“振荡波”那样利用缓冲区溢出造成全世界范围内的网络瘫痪的恶性蠕虫病毒还会出现。预防缓冲区溢出病毒攻击十分麻烦,对新的程序可以要求程序开发者在开发程序时仔细检查溢出情况,不允许数据溢出缓冲区,这个相对还好说。但对以往的程序和系统就只能发现一个漏洞补一个漏洞,被动之极。杀毒软件和防火墙又不可能对未发现的缓冲区溢出进行提前封堵,所以对付缓冲区溢出完全是被动的,是哪里失火扑灭哪里。正是如此,如何能有效地主动预防缓冲区溢出成为大家关心的议题。在这种背景下CPU硬件防毒终于出台了,并且得到了微软的大力支持。虽然各个CPU厂商给自己的硬件防毒技术起的名字各不相同,而它们实际采取的技术和原理却几乎是一模一样的。
缓冲区受溢出攻击后,溢出所占用的空间一般都是存储空间,而绝大多数程序在这类空间内是不会有代码进行执行的(采用实时执行代码方式的程序则会,这就牵涉到CPU硬件防毒的兼容性问题了)。所以各个CPU厂商在这些存储空间的数据区中都加上了标志(Non-Executable或Execute Disable),当缓冲区溢出发生后,溢出的恶性代码试图运行时,CPU读取到这些数据区中的禁止执行标志,会直接停止恶性代码的运行。表现在Windows XP中就是,会弹出对话框提示数据执行保护:“Windows 安全功能检测到一个问题,并关闭了此程序。”后面跟着程序名和发行商名称。
比如在Intel的Execute Disable Bit技术中,在开启PAE(物理寻址扩展)模式后,它会在所有用于地址译码的分页结构(这里的页指的就是内存页,一种内存单元)中定义一个新的属性位为Execute Disable Bit服务,假设某一个内存页的EDB属性位的值为1,那么这个内存页就只能用来存储数据,而不能用来执行指令。所有的执行企图都会被计算机禁止,并向操作系统报告。AMD、Transmeta也都同样是在分页结构中增加新的属性位来标志存储空间,并禁止在其内执行指令。
CPU硬件防毒是需要操作系统支持的,在Windows XP SP2系统中,只要系统平台所使用的CPU是支持CPU硬件防毒的,数据执行预防(Data Execution Prevention)功能默认就会开启。虽然它不能阻止计算机上被安装有害程序,但配合CPU它可以阻止缓冲区溢出攻击的实现。目前支持数据执行预防功能的操作系统有:Windows XP SP2、Windows Server 2003 SP1、Windows XP 64bit Edition和Windows Server 2003 64bit Edition。已上市支持CPU硬件防毒的CPU有:AMD的Athlon64系列与Opteron系列,这也是目前在国内最容易买到的支持CPU硬件防毒的处理器。Intel的Itanium、Itanium2、E0制程的Xeon处理器、以及LGA775封装的Intel Pentium 4 560J (3.60 GHz)、Intel Pentium 4 550J (3.40 GHz)、Intel Pentium 4 540J (3.20 GHz)、Intel Pentium 4 530J (3.00 GHz)、Intel Pentium 4 520J (2.80 GHz)、Intel Celeron D 340J (2.93 GHz)、Intel Celeron D 335J (2.80 GHz)、Intel Celeron D 330J (2.66 GHz)、Intel Celeron D 325J (2.53 GHz)。这些处理器则估计要等到LGA775接口主板普及开来后,才有可能真正使用户受惠。
五、路仍然很长──硬件防毒须进一步完善
虽然目前看来CPU硬件防毒已经有了处理器和操作系统的全面支持,但它要想真的完全普及开来还要解决一系列问题。首先就是兼容性问题,我们前面已经说过,采用实时执行代码方式的程序会在存储空间中执行操作,在目前的情况下,它肯定就会被CPU和系统所禁止。而微软为此采用的是“单独排除的办法”,即将这个程序设定为不受数据执行预防保护。具体办法是:
1.单击“开始”,然后单击“控制面板”。
2.在经典视图中,双击“系统”。
3.单击“高级”选项卡,单击“性能”,然后单击“设置”。
4.在“性能选项”对话框中,单击“数据执行保护”选项卡。
5.选择“为所有程序和服务启用 DEP,但我选择的程序和服务除外:”,然后单击“添加”。
6.在“打开”对话框中,找到并选择该应用程序,然后单击“打开”。
7.单击“应用”,然后单击“确定”。将出现一个提示,通知你必须重新启动系统后设置才能生效。
此外我们前面说过在32位操作系统中必须打开PAE(物理寻址扩展)模式后才能启用CPU防毒功能,而这又会导致系统的不稳定和部分驱动与EDB的冲突。而且和64位操作系统相比,32位操作系统的EDB的保护范围也没有前者全面(32位Windows版本上,DEP仅适用于堆栈。在64位Windows版本上,DEP适用于堆栈、页面缓冲池和会话池)。这些都是进一步需要解决的问题。
更重要的是这种全新的CPU硬件防毒技术还没有经过真正的大规模考验,到底实际效能如何我们只能等Athlon 64与LGA775封装的J系列Pentium 4与Celeron D普及后才能看出来。不过既然大家已经在正确的道路上迈出了第一步,那么以后用户必定能用上更为安全的硬件与系统。



