1.引言
网络安全已成为人们日益关注的重要问题。据CNCERT/CC2007年网络安全工做报告的统计,近年来漏洞数量呈现明显上升趋势,不只如此,新漏洞从公布到被利用的时间愈来愈短,黑客对发布的漏洞信息进行分析研究,每每在极短期内就能成功利用这些漏洞。除了利用已知漏洞,黑客们也善于挖掘并利用一些还没有公布的漏洞,发起病毒攻击,或出售漏洞资料,知足经济目的。相对于黑客,安全研究者们在漏洞研究方面显得相对被动和滞后。所以,应该加大对漏洞挖掘的研究力度,以便对各种漏洞采起更为主动合理的处理方式。
2.漏洞挖掘概述
漏洞(vulnerability)是指系统中存在的一些功能性或安全性的逻辑缺陷,包括一切致使威胁、损坏计算机系统安全性的全部因素,是计算机系统在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷和不足。因为种种缘由,漏洞的存在不可避免,一旦某些较严重的漏洞被攻击者发现,就有可能被其利用,在未受权的状况下访问或破坏计算机系统。先于攻击者发现并及时修补漏洞可有效减小来自网络的威胁。所以主动发掘并分析系统安全漏洞,对网络攻防战具备重要的意义。
漏洞的研究主要分为漏洞挖掘与漏洞分析两部分。漏洞挖掘技术是指对未知漏洞的探索,综合应用各类技术和工具,尽量地找出软件中的潜在漏洞;漏洞分析技术是指对已发现漏洞的细节进行深刻分析,为漏洞利用、补救等处理措施做铺垫。
国内外多个安全组织及我的都从事漏洞的研究。其中比较权威的两个漏洞发布机构是CVE(Common Vulnerabilities and Exposures)和CERT(Computer Emergency Response Team)。此外,国外eEye、LSD等组织也对最新的漏洞进行及时跟踪分析,并给出相应的漏洞解决方案。绿盟科技、启明星辰等单位是国内安全研究组织的表明。其中绿盟科技是发布自主研究安全漏洞最多的国内安全公司,已经完成对RPC、SMB、IIS等多类漏洞的研究,并取得了不错的成绩。
3.现有漏洞挖掘技术分类
根据分析对象的不一样,漏洞挖掘技术能够分为基于源码的漏洞挖掘技术和基于目标代码的漏洞挖掘技术两大类。
基于源码的漏洞挖掘的前提是必须能获取源代码,对于一些开源项目,经过分析其公布的源代码,就可能找到存在的漏洞。例如对Linux系统的漏洞挖掘就可采用这种方法。但大多数的商业软件其源码很难得到,不能从源码的角度进行漏洞挖掘,只能采用基于目标代码的漏洞挖掘技术。对目标码进行分析涉及编译器、指令系统、可执行文件格式等多方面的知识,难度较大。
基于目标代码的漏洞挖掘首先将要分析的二进制目标代码反汇编,获得汇编代码;而后对汇编代码进行切片,即对某些上下文关联密切、有意义的代码进行汇聚,下降其复杂性;最后经过分析功能模块,来判断是否存在漏洞。
漏洞挖掘技术从逆向分析的软件测试角度,又可分为白箱分析、黑箱分析和灰箱分析三类,这三种方法在文献中有较详细介绍。
4.常见的漏洞挖掘分析技术
漏洞挖掘是一个多种漏洞挖掘分析技术相互结合、共同使用和优点互补的过程。目前漏洞挖掘分析技术有多种,主要包括手工测试技术(manual testing)、Fuzzing技术、比对和二进制比对技术(Diff and BinDiff)、静态分析技术(static analysis)、动态分析技术(runtime analysis)等。
4.1.手工测试
手工测试是经过客户端或服务器访问目标服务,手工向目标程序发送特殊的数据,包括有效的和无效的输入,观察目标的状态、对各类输入的反应,根据结果来发现问题的漏洞检测技术。手工测试不须要额外的辅助工具,可由测试者独立完成,实现起来比较简单。但这种方法高度依赖于测试者,须要测试者对目标比较了解。手工测试可用于Web应用程序、浏览器及其余须要用户交互的程序。
4.2.Fuzzing技术
Fuzzing是一种基于缺陷注入的自动软件测试技术,它利用黑盒测试的思想,使用大量半有效的数据做为应用程序的输入,以程序是否出现异常为标志,来发现应用程序中可能存在的安全漏洞。所谓半有效的数据是指对应用程序来讲,文件的必要标识部分和大部分数据是有效的,这样应用程序就会认为这是一个有效的数据,但同时该数据的其余部分是无效的,这样应用程序在处理该数据时就有可能发生错误,这种错误可以致使应用程序的崩溃或者触发相应的安全漏洞。Fuzzing技术是利用Fuzzer工具经过彻底随机的或精心构造必定的输入来实现的。下图显示了Fuzzing技术的通用测试过程。git

Fuzzing测试一般以大小相关的部分、字符串、标志字符串开始或结束的二进制块等为重点,使用边界值附近的值对目标进行测试。Fuzzing技术能够用于检测多种安全漏洞,包括[4]:缓冲区溢出漏洞、整型溢出漏洞、格式化串漏洞、竞争条件漏洞、SQL注入、跨站点脚本、远程命令执行、文件系统攻击、信息泄露等。目前公布的安全漏洞中有许多都是使用Fuzzing技术检测发现的,而且有许多Fuzzing工具能够用于测试应用程序的安全性。 与其它技术相比,Fuzzing技术具备思想简单,容易理解、从发现漏洞到漏洞重现容易、不存在误报的优势,固然它也具备黑盒测试的所有缺点,并且它有不通用,构造测试周期长等问题。 4.3.二进制比对技术 二进制比对技术又可称为补丁比对技术,它主要是被用以挖掘“已知”的漏洞,所以在必定意义上也可被认为是一种漏洞分析技术。因为安全公告中通常都不指明漏洞的确切位置和成因,使得漏洞的有效利用比较困难。但漏洞通常都有相应的补丁,因此能够经过比较补丁先后的二进制文件,肯定漏洞的位置和成因。 补丁比对技术对于安全人员及黑客都是很是有用的技术,经过补丁比对分析,定位漏洞代码,再加以数据流分析,最后能够获得漏洞利用的攻击代码。有经验的安全专家或黑客甚至能在很短的时间内就完成这个漏洞挖掘与利用的过程。 补丁比对技术有不少,简单的比较方法有二进制字节比较和二进制文件反汇编后的文本比较,前者只适用于若干字节变化的比较;然后者缺少对程序逻辑的理解,没有语义分析,适用于小文件和少许的变化。这两种方法都不适合文件修改较多的状况。较复杂的方法[4]还有Tobb Sabin提出的基于指令类似性的图形化比较和Halvar Flake提出的结构化二进制比较,前者能够发现文件中一些非结构化的变化,如缓冲区大小的改变等,而且图形化显示比较直观。其不足是受编译器优化的影响较大,且不能在两个文件中自动发现大量比较的起始点。后者注重二进制可执行文件在结构上的变化,从而在必定程度上消除了编译器优化对分析二进制文件所带来的影响,但这种方法不能发现非结构的变化。 经常使用的补丁比对工具备IDefense公司发布的IDACompare、The eEye Digital Security发布的Binary Diffing Suite(EBDS)以及Sabre Security的BinDiff。它们都是基于结构化二进制比较技术的补丁比对工具。此外,NCNIPC还于2007年12月发布了NIPC Binary Differ(NBD)补丁比对工具,大大的扩充了经典算法中简易签名,可参见文献[8]。 4.4.静态分析 静态分析是经过词法、语法、语义分析检测程序中潜在的安全问题,发现安全漏洞的,其基本思想方法也是对程序源程序的静态扫描分析,故也归类为静态检测分析。静态分析重点检查函数调用及返回状态,特别是未进行边界检查或边界检查不正确的函数调用(如strcpy,strcat等可能形成缓冲区溢出的函数)、由用户提供输入的函数、在用户缓冲区进行指针运算的程序等。 目前流行的软件漏洞静态分析技术[9]主要包括源代码扫描和反汇编扫描,它们都是一种不须要运行软件程序就能够分析程序中可能存在的漏洞的分析技术。 源代码扫描:主要针对开放源代码的程序,经过检测程序中不符合安全规则的文件结构、命名规则、函数、堆栈指针等,从而发现程序中可能隐含的安全缺陷。这种漏洞分析技术须要熟练掌握编程语言,并预先定义出不安全代码的审查规则,经过表达式匹配的方法检查源代码。因为程序运行时是动态变化的,若是不考虑函数调用的参数和调用环境,不对源代码进行词法分析和语法分析就没有办法准确的把握程序的语义,所以这种方法不能发现程序动态运行过程当中的安全漏洞。 反汇编扫描:对于不公开源代码的程序来讲每每是最有效的发现安全漏洞的办法。分析反汇编代码须要有丰富的经验,也可使用辅助工具来帮助简化这个过程。但不可能有一种彻底自动的工具来完成这个过程。例如,利用一种优秀的反汇编程序IDA就能够获得目标程序的汇编脚本语言,再对汇编出来的脚本语言使用扫描的方法,从而进一步识别一些可疑的汇编代码序列。经过反汇编来寻找系统漏洞的好处是从理论上讲,无论多么复杂的问题老是能够经过反汇编来解决的。它的缺点也是显然的,这种方法费时费力,对人员的技术水平要求很高,一样不能检测到程序动态运行过程当中产生的安全漏洞。 静态分析方法高效快速,可以很快完成对源代码的检查,而且检查者不须要了解程序的实现方式,故很是适合自动化的程序源程序缓冲区溢出检查。此外,它还可以较全面的覆盖系统代码,减小了漏报。 但这种方法也存在很大的局限性,不断扩充的特征库或词典,形成了检测的结果集大、误报率高;静态分析方法,重点是分析代码的“特征”,而不关心程序的功能,不会有针对功能及程序结构的分析检查。 4.5.动态分析技术 动态分析技术是一种动态的检测技术,在调试器中运行目标程序,经过观察执行过程当中程序的运行状态、内存使用情况以及寄存器的值等以发现潜在问题,寻找漏洞。它从代码流和数据流两方面入手:经过设置断点动态跟踪目标程序代码流,以检测有缺陷的函数调用及其参数;对数据流进行双向分析,经过构造特殊数据触发潜在错误并对结果进行分析。动态分析须要借助调试器工具,SoftIce、OllyDbg、WinDbg等是比较强大的动态跟踪调试器。 常见动态分析方法有:输入追踪测试法、堆栈比较法、故障注入分析法。 动态分析是在程序运行时进行分析,找到的漏洞即表现为程序错误,所以具备较高的准确率;它可以有针对性的对目标系统进行检查,从而可以准确的肯定目标系统相应功能或模块的系统表现。此外,动态分析技术与黑盒测试很是类似,无须源代码,能够经过观察程序的输入和输出来分析,并对其进行各类检查,以验证目标程序是否有错误。如由输入引起的缓冲区溢出漏洞,可使用此方法。动态分析能够知足某些安全检测的须要,可是仍是有较大的局限性,它效率不高,不容易找到分析点,须要熟悉目标系统且有丰富经验,技术复杂,对分析人员要求高,难以实现自动化发现。在大规模项目的检查中,动态分析技术都受到较大的制约。5 结束语 软件漏洞挖掘是网络攻防技术的重要组成部分。本文重点研究了几种常见的漏洞挖掘技术,各类方法都有其优缺点,为了准确挖掘软件漏洞,在实际测试时能够综合使用。好比,将手工测试和Fuzzing技术相结合,同时借助于Debugger(IDA Pro、Ollydbg等)进行分析调试就是一种很好的漏洞挖掘思路。经过手工测试,可以了解目标的一些基本信息,找出该程序可能出现脆弱点的线索,从而有针对性的利用Fuzzing技术设计并实现具体的fuzzer工具。在使用fuzzer对目标的某些脆弱点进行测试的同时,用一个Debugger工具将目标挂起,从而当有错误发生时,将会被Debugger捕捉到,这样就能够借助于Debugger具体调试目标程序。