一种二进制程序漏洞自动化定位方法

文档序号:6401133阅读:367来源:国知局
专利名称:一种二进制程序漏洞自动化定位方法
技术领域
本发明主要涉及漏洞定位方法,更确切地是涉及一种二进制程序漏洞自动化定位方法,属于网络信息安全领域。
背景技术
漏洞已经给Internet带来很大威胁:一方面,攻击者可以利用漏洞入侵系统 ’另一方面,蠕虫利用漏洞进行传播,并产生破坏。近些年,软件漏洞数量持续上涨,但是其补丁的生成需要很长时间,据分析微软当前的21个漏洞(MS11-087 MS12-007)公布和补丁发布平均需要115天。补丁的生成需要较长时间的主要原因:首先,软件越来越复杂,分析人员需要针对数以万计的指令进行分析,因此,在软件中快速定位漏洞代码是困难的;其次,漏洞种类繁多,分析人员需要熟悉各种类型,也增加了查找漏洞的难度;最后,由于大部分程序并不开源,只有开发人员可以对漏洞分析并打补丁,降低了第三方专业人员的参与度,减少了发布补丁的有效通道。由此可见,需要很长时间来发布漏洞补丁,给用户带来了很大安全威胁。为了解决上述问题,现有方法主要分为三类:1) 一类方法主要针对单一类型的漏洞进行分析(如缓冲区溢出)定位并产生补丁,但是只能解决一种类型的漏洞且大多数方法需要源代码的支持;2) —类方法从正常执行流中研究不变量来定位漏洞,但是这类方法无法寻找出漏洞的真正成因;3)差分切片可以在两个相似的路径中发现不同,帮助分析人员识别执行中的异常,但是需要一个正常执行流作比对,而不同程序输入会使得执行流差异不可控,因此难以找到合适的用于比对的执行流。因此,如何对漏洞进行快速定位是当前补丁生成面临的重要难题,也是当前研究的热点。

发明内容
针对上述问题, 本发明的目的在于面向无需源码的二进制程序提供一种二进制程序漏洞自动化定位方法,它支持多种类型的漏洞,包括堆/栈/整数型/缓冲区溢出,内存泄漏,格式字符串等。通过对程序执行路径进行记录,进而对异常位置进行分析,产生的相应漏洞依赖树(以下简称“依赖树”),有效减少需要分析指令的数量,实现对漏洞位置的快速定位。在此基础上,提出一种简单有效的样例补丁生成方法,有效保证系统不被恶意利用。根据以上目的,实现本发明的技术方案是:一种二进制程序漏洞自动化定位方法,其步骤为:I)运行待检测二进制程序,记录从该程序开始运行到出错过程中所有指令;2)根据所记录的指令构建漏洞依赖树,并根据所构建漏洞依赖树从所记录指令中检测指令中的漏洞指令;其中,构建所述漏洞依赖树的过程中,每增加若干个节点检查是否出现漏洞候选节点,如果出现,则产生该漏洞候选节点的临时补丁;3)观察该临时补丁是否有效,如果有效则停止构建漏洞依赖树,并作为定位到漏洞位置的依据;否则继续构建漏洞依赖树。进一步的,所述漏洞依赖树中的节点表示该程序中的指令,指令之间通过边连接。进一步的,所述漏洞依赖树的构建方法为:I)初始化一工作集Wl为空集;对所记录指令中每一执行路径,从该执行路径的最后一条指令开始,顺次取出一指令i ;2)将指令i对应的指令地址加入漏洞依赖树V,将由指令i使用的变量加入工作集wl ;3)初始化一变量 branchNum = O ;4)如果指令i不为空且工作集wl不为空,则进行以下循环:如果指令i是依赖输入数据的分支指令,则branchNum = branchNum+1,即对依赖于外部输入的分支进行计数,i指向前一条指令,继续循环过程;如果当前指令i定义的变量var和wl有交集,贝Ij从wl中移除这个变量var,并在wl中加入当前指令i使用的变量;计算边长度edgeLen =branchNum-j为指令j到树根的长度,指令j为漏洞依赖树中使用var的节点;然后在漏洞依赖树V中增加节点i,在漏洞依赖树V中增加边(j,i),其长度为edgeLen。进一步的,所述每增加若干个节点检查是否出现漏洞候选节点的方法为:a)每增加若干个节点后,检测所述漏洞依赖树中连接每一新增加节点的入边和出边,如果其长度的比值大于设定阈值则将此节点作为漏洞候选节点山)选择所增加若干个节点中改变变量范围值超过设定比例的节点,将此节点作为漏洞候选节点。进一步的,所述记录从该程序开始运行到出错过程中所有指令的方法为:首先设定一阈值;然后从该程序开始运行到出错过程中,对每条指令进行记录,包括每个分支指令和选用的分支进行记录,当记录指令超过设定阈值时则新记录的指令将覆盖最先记录的指令,进行循环记录。进一步的,如果该程序的指令指针依赖于外部输入,或者内存引用依赖于外部输入,或者指定的异常函数被触发,则判定该程序出错。进一步的,所述临时补丁的生成方法为:利用指令的执行条件,实现不执行这条指令即可得到程序运行不出错结果的临时补丁。进一步的,如果函数A调用函数B出现问题,但该函数B也被其他函数调用且没出现问题,则对函数A打补丁。本发明的主要内容为:I)在攻击检测阶段:在攻击输入,即输入待检测二进制程序,程序运行过程中记录导致程序错误的执行路径。通过污点分析或程序是否崩溃来检测攻击,如程序指针(EIP)依赖于外部输入或者某些异常被触发,异常触发包括UNHANDLED_EXCEPTION_FILTER函数被调用等。2)当检测到攻击后:找到执行路径中相关指令中的漏洞,并产生依赖树。与传统切片方法不同,我们在树中增加边的长度来显示指令和漏洞之间的相关度,依赖树中节点表示程序中某个指令,边是连接这些指令的。当节点之间存在数据依赖关系时,例如指令a中使用了在指令b中定义的变量,则有一条从a到b的边。相关度即“边的长度”,指两个指令之间的“依赖于外部输入的条件指令”数目。利用当前执行路径即可产生依赖树。3)依赖树的构建:并不是路径上所有指令都需要分析。实际上在构建依赖树的过程中,当发现可能是漏洞的代码,就停止构建依赖树,并产生一个临时补丁。临时补丁可以验证漏洞位置的正确性,同时也是对攻击的一种临时防御措施(有可能产生程序的非正常运行),为真实漏洞分析提供参考;验证方法为:如果变化程序输入,漏洞不再出现,程序也能正常运行,则判断这个补丁有效。如果验证失败,则继续构建依赖树,找其他指令;如果成功,则停止依赖树的构建过程。临时补丁的生成方法,即利用指令的执行条件(控制这条指令执行的条件指令),从而不执行这条指令,也就避免了漏洞的发生。(如执行条件是判断某个标志位不为1,则把这个标志位设置为1,这样这条指令就不执行了。)这个是临时的方法,本文的目的不在于找到正确的补丁,而是提供一个定位漏洞的方法,为今后正确补丁提供支持。与现有技术相比,本发明的积极效果为:本发明的优点在于,在无源码情况下定位多种类型的未知漏洞位置,通过构建依赖树,并在依赖树边上进行赋值,有效描述指令和漏洞之间的相关度,在减少了需要分析的指令数量的同时,极大地提高了分析效率;此外,提出一种临时漏洞补丁生成方法,可以临时防御漏洞被恶意利用。


图1为程序执行中漏洞定位处理流程图;图2为跟踪路径。图3为根据图2样例代码生成的依赖树。
具体实施例方式I)在待检测二进制程序运行中记录错误运行的执行路径,即记录从程序开始运行到出错过程中所有指令(已知某个输入会导致程序出错,如崩溃现象,然后从头就开始记录)。为了避免再次对程序进行分析,记录过程中包括对每个分支指令和选用的分支也进行记录。在实际分析中,由于漏洞位置与指令较为接近,而且考虑到程序和硬盘空间的限制,我们设定阈值进行指令跟踪与记录,目前选用100000个,如果超过此阈值,新记录的指令将覆盖最先记录的指令,进行循环记录。如果在记录的指令中无法找到漏洞代码,我们将重新设定阈值并运行程序。对指令进行记录后,将检测利用漏洞的位置。当满足如下条件时,判定漏洞被利用,即导致程序出错: 指令指针EIP依赖于外部输入数据,此时程序指针能够被外部输入改写,易出现任意代码执行的危险。 内存引用依赖于外部输入,此时内存引用被外部输入任意指定,易产生任意读/
写错误。 系统默认异常处理函数被触发,此时表示系统出现异常,也属于错误类型一种。2)因为执行路径中有数以百万计的指令,很难直接找到漏洞代码。我们将选择与漏洞相关的指令,为后续分析漏洞代码位置提供基础。

首先,根据指令构建漏洞依赖树。漏洞依赖树构建算法如下:输入:执行路径t,执行路径由记录的指令组成,即路径是一组指令;即输入上一步记录的指令;输出:依赖树V
1INS i=t.last; "i 指向 t 中指令
2WorkList wl= Φ\
3v.addNote(i); //将指令i加入依赖树
4wl.add(use(i)); //use(i)由 i 使用的变量组成
5int branchNum = O;
6while i^NULL and wl^ Φ do
7if i是依据输入数据的分支指令then
8branchNum++; i=1.prev; continue;
9end 10if def(i)Dvvl then
11wl.remove(def(i)); wl.add(use(i));
12INS j=v.node(def(i)); //v.node(var)返回使用 var 的节点
13int edgeLen = branchNum -v.len(rootj); //v.len(rootj)返丨11I W1: root 和 j 之丨丨丨]的边的
长&
14v.addNode(i);
15v.addEdge(j丄edgeLen);//添加新的边到 v
16if edgeLen>delta then Il delta 是某个阈值
17尝试修复漏洞
18if修复成功then
19break; //退出循环
20end
21end
22end
23i=1.prev;//i指向t中目If一个指针
24end艮P;I指令i=路径中最后一条指令2工作集wl=空集;
3将指令i对应的指令地址加入依赖树V4将由指令i使用的变量加入工作集wl;
5 branchNum - O;
6如果指令i不为空而且工作集wl不为空,则进行以下循环:
7if i是依赖输入数据的分支指令then
8branchNum++,即对依赖于外部输入的分支进行计数;i指向前一条指令;继续循环过程。(一直累加直到算法停止运行,三种情况下会停止运行:I)当前路径所有指令取出;
2)工作集wl为空:3)发现合适的补丁位置并成功修补;)
9end
10ifi中定义的变量和wl有交集(即当前指令i中被定义的变量在后续程序中被使用到)

then
11wl中移除这个变量var; wl中加入i使用的变量;例如指令“mov eax, ebx”,定义的变量为eax,使用的变量为ebx。
12指令j为依赖树中使用var的节点
13edgeLen = branchNum -j为指令j到树根的长度,
14在依赖树V中增加节点i;
15在依赖树V中增加边(j,i),其长度为edgeLen
16if edgeLen的长度超出某个阈值then
17尝试在此位置修补漏洞
18if修补成功then
19退出循环
20end
21end
22end
23指令i指向路径t中前一个指令
24end在构建好依赖树之后,可以通过对依赖树的分析定位漏洞可能出现的程序位置,进而寻找漏洞解决方法。举例说明:指令如表I所示,设置第9行作为程序的入口点;输入字符为0x78作为终止符。表I中第12行为用户终端输入一个字符,第13行判断是否为0x78,如果不等就继续循环,否则跳到第20行。表I代码样例
权利要求
1.一种二进制程序漏洞自动化定位方法,其步骤为: 1)运行待检测二进制程序,记录从该程序开始运行到出错过程中所有指令; 2)根据所记录的指令构建漏洞依赖树,并根据所构建漏洞依赖树从所记录指令中检测指令中的漏洞指令;其中,构建所述漏洞依赖树的过程中,每增加若干个节点检查是否出现漏洞候选节点,如果出现,则产生该漏洞候选节点的临时补丁; 3)观察该临时补丁是否有效,如果有效则停止构建漏洞依赖树,并作为定位到漏洞位置的依据;否则继续构建漏洞依赖树。
2.如权利要求1所述的方法,其特征在于所述漏洞依赖树中的节点表示该程序中的指令,指令之间通过边连接。
3.如权利要求1或2所述的方法,其特征在于所述漏洞依赖树的构建方法为: 1)初始化一工作集《I为空集;对所记录指令中每一执行路径,从该执行路径的最后一条指令开始,顺次取出一指令i ; 2)将指令i对应的指令地址加入漏洞依赖树V,将由指令i使用的变量加入工作集wl; 3)初始化一变量branchNum= O ; 4)如果指令i不为空且工作集wl不为空,则进行以下循环:如果指令i是依赖输入数据的分支指令,则branchNum = branchNum+1,即对依赖于外部输入的分支进行计数,i指向前一条指令,继续循环过程;如果当前指令i定义的变量var和wl有交集,则从wl中移除这个变量var,并在wl中加入当前指令i使用的变量;计算边长度edgeLen = branchNum-j为指令j到树根的长度,指令j为漏洞依赖树中使用var的节点;然后在漏洞依赖树V中增加节点i,在漏洞依赖树V中增加边(j,i),其长度为edgeLen。
4.如权利要求1或2所述的方法,其特征在于所述每增加若干个节点检查是否出现漏洞候选节点的方法为:a)每增加若干个节点后,检测所述漏洞依赖树中连接每一新增加节点的入边和出边,如果其长度的比值大于设定阈值则将此节点作为漏洞候选节点;b)选择所增加若干个节点中改变变量范围值超过设定比例的节点,将此节点作为漏洞候选节点。
5.如权利要求1或2所述的方法,其特征在于所述记录从该程序开始运行到出错过程中所有指令的方法为:首先设定一阈值;然后从该程序开始运行到出错过程中,对每条指令进行记录,包括每个分支指令和选用的分支进行记录,当记录指令超过设定阈值时则新记录的指令将覆盖最先记录的指令,进行循环记录。
6.如权利要求1或2所述的方法,其特征在于如果该程序的指令指针依赖于外部输入,或者内存引用依赖于外部输入,或者指定的异常函数被触发,则判定该程序出错。
7.如权利要求1所述的方法,其特征在于所述临时补丁的生成方法为:利用指令的执行条件,实现不执行这条指令即可得到程序运行不出错结果的临时补丁。
8.如权利要求7所述的方法,其特征在于如果函数A调用函数B出现问题,但该函数B也被其他函数调用且没出现问题,则对函数A打补丁。
全文摘要
本发明公开了一种二进制程序漏洞自动化定位方法。本方法为1)运行待检测二进制程序,记录从该程序开始运行到出错过程中所有指令;2)根据所记录的指令构建漏洞依赖树,并根据所构建漏洞依赖树从所记录指令中检测指令中的漏洞指令;其中,构建所述漏洞依赖树的过程中,每增加若干个节点检查是否出现漏洞候选节点,如果出现,则产生该漏洞候选节点的临时补丁;3)观察该临时补丁是否有效,如果有效则停止构建漏洞依赖树,并作为定位到漏洞位置的依据;否则继续构建漏洞依赖树。本发明减少了需要分析的指令数量,极大地提高了分析效率。
文档编号G06F17/30GK103198260SQ20131010495
公开日2013年7月10日 申请日期2013年3月28日 优先权日2013年3月28日
发明者陈恺, 张颖君, 赵险峰 申请人:中国科学院信息工程研究所
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1