发明内容
本发明的目的在于对传统的web程序静态污点分析过程中存在的误报漏报问题,提出一种基于细粒度污点分析与符号执行的web漏洞检测方法,通过对程序执行路径的判断、对污点状态的细粒度分析以及使用符号执行工具对漏洞可达性的判断可大大降低分析的漏报误报率。
为了实现上述目的,本发明采用的技术方案为:
一种基于细粒度污点分析与符号执行的web漏洞检测方法,包括如下步骤:
步骤(1)、初始化配置:针对Web应用配置污点源列表、对不同的漏洞配置污点汇聚点和净化函数列表;
步骤(2)、方法调用图和控制流图构建:利用字节码分析技术得到程序的方法调用图,并为每个方法构建控制流图;
步骤(3)、过程内和过程间污点分析:使用多级表示记录污点状态,遍历方法调用图,对每个方法进行过程内和过程间污点分析,保存过程间污点传播情况与过程内分析得到的可疑漏洞触发位置;
步骤(4)、符号执行验证:在步骤(3)得到的可疑漏洞触发位置前插入自定义变量,使用符号执行工具检验路径的可达性,在约束求解阶段跳过不包含标记变量的路径。
进一步的,所述步骤(1)中使用文件记录Web漏洞的污点源,即程序获取外部输入的函数,污点汇聚点函数为可以触发安全问题的函数,净化函数为可以过滤特殊字符与加密解密函数。
进一步的,所述控制流图由基本块构成,基本块内是连续无分支的字节码指令,基本块之间可能存在分支;基本块之间互相连接,基本块之间存在跳转、合并操作。
进一步的,所述步骤(3)中的过程内分析和过程间污点分析是一个迭代的过程,先对函数进行过程内分析,过程内污点分析得到方法内变量的状态,分析至污点汇聚点函数触发处会进行记录,过程内污点分析跟踪变量状态并记录sink触发点,也即是可疑漏洞触发位置,过程间分析结束后得到该方法的过程间污点传播情况;在过程内分析遇到方法调用时,需要用到被调用方法的过程间污点传播情况。
进一步的,过程内污点分析依赖控制流图,控制流图由基本块构成,过程内污点分析被分解为基本块内分析与基本块间分析,污点分析的过程记录变量的状态信息时使用污点表示进行处理。
进一步的,所述污点表示具体为:污点分析分析变量的状态变化时使用多级记录,分析过程中记录变量本身的信息。
进一步的,所述变量本身的信息包括变量的污染状态、常量数值、以及变量的内部信息。
进一步的,所述基本块内分析是分析具体的字节码指令对变量状态的影响,得到这个基本块的出口状态,包括变量状态、是否执行标记、跳转地址。
进一步的,所述基本块间分析是分析污点变量的分支、合并情况,判断部分基本块是否会被执行,排除无效块;具体的,基本块内函数调用指令如果调用的是sink函数,判断sink的可感染位置参数状态是否为safe,如果不是,此处sink可能被触发,将所在函数加入待确认漏洞集合,并记录下可被感染的参数位置,也即是可疑漏洞触发位置。
进一步的,所述步骤(4)符号执行验证具体包括:
4.1)自定义变量插入:在可疑漏洞触发位置前定义变量boolean Tlocation=true,并在sink前加入判断if(Tlocation)sink();
4.2)可达性判定:符号执行工具将执行路径上所有条件连接得到约束表达式,在对约束表达式求解过程中,判断约束表达式是否存在Tlocation,如果不存在Tlocation,表明该路径上不存在可疑漏洞,跳过该表达式的求解步骤;如果表达式中存在Tlocation并且有解,将表达式中所有Tlocation对应的漏洞信息加入到确认的漏洞列表中,并将漏洞报告给用户,如果表达式中存在Tlocation但无解,表明此漏洞不可达。
通过本发明所构思的以上技术方案与现有技术相比,主要具备以下的技术优点:
1、在污点分析记录中,使用多级记录,对集合、map等数据结构的内部以及对象的字段状态进行了记录,对String与基本数据类型的值和状态进行了记录,这使得静态分析的准确性有了一定的提高;
2、结合基本数据类型的值跟踪,对基本块之间的跳转进行了判断,减少了部分无效路径的干扰,同时提高了分析效率与准确度;
3、使用符号执行工具对可疑漏洞的执行路径进行验证,符号执行过程的约束求解步骤跳过了不包含可疑漏洞的路径,大大提高了符号执行的效率,根据符号执行求解的结果可以排除不可到达的疑似漏洞。
具体实施方式
本发明基于静态污点分析和符号执行技术,在分析的过程中对基本数据类型进行了值跟踪,并基于此对程序的分支进行了一定程度上的判断,对集合、map等数据结构的内部状态进行了跟踪,最后使用符号执行工具对可疑漏洞的污点传播路径进行了检验,将符号执行作为验证可疑漏洞是否可达的手段,排除了部分很大概率不会执行的漏洞,有效地降低了静态污点分析的误报率。下面结合附图,对本发明做进一步详细的说明。
参照图1,本发明基于细粒度静态污点分析与符号执行的web漏洞检测方法其中一个实施例的实施步骤如下:
步骤1、初始化配置:针对Web应用配置污点源列表、对不同的漏洞配置污点汇聚点和净化函数列表,即配置source(污点源)函数、sink(污点汇聚点)函数和净化函数。
1.1)初始阶段,source、sink和净化函数均存以文本文件形式记录,source函数为程序从外界获取输入的函数,soure函数由包名、类名、返回值、函数名、参数标识构成,sink函数为可能触发安全问题(例如漏洞)的函数,sink函数由包名、类名、返回值、函数名、参数、可被感染位置以及漏洞类型构成,净化函数为可以过滤特殊字符与加密解密函数,由包名、类名、返回值、函数名、参数构成。
1.2)初始化阶段,构造两个map,一个用于保存source和净化函数,另一个保存sink。对于source和净化函数,只需记录方法和返回值状态,但对于sink,需记录其可感染参数位置,参数的位置为其在操作数栈中的偏移量。
步骤2、方法调用图和控制流图构建:利用字节码分析技术得到程序的方法调用图,并为每个方法构建控制流图,控制流图由基本块构成。
调用bcel字节码分析框架对传入的待分析程序进行解析,得到方法间的调用关系。对每个方法进行分析得到方法的控制流图,控制流图由基本块构成,基本块内是连续无分支的字节码指令,即基本块内不存在分支,一个基本块只有一个入口和一个出口,一个方法只存在一个入口块。基本块之间可能存在分支,一个基本块可能存在多个前驱块,也可能存在多个后继块。
步骤3、过程内和过程间污点分析:使用多级表示记录污点状态,遍历方法调用图,对每个方法进行过程内和过程间污点分析,保存过程间污点传播情况与过程内分析得到的可疑漏洞触发位置。
过程内分析和过程间污点分析是一个迭代的过程,先对函数进行过程内分析,过程内污点分析得到方法内变量的状态,分析至污点汇聚点函数触发处会进行记录,过程内污点分析跟踪变量状态并记录sink触发点,也即是可疑漏洞触发位置;过程间分析结束后得到该方法的过程间污点传播情况,以及得到该方法调用导致的实例对象、方法参数、返回值三者之间的状态感染情况;在过程内分析遇到方法调用时,需要用到被调用方法的过程间污点传播情况。
过程内污点分析依赖控制流图,控制流图由基本块构成,过程内污点分析被分解为基本块内分析与基本块间分析,污点分析的过程中需要记录变量的状态信息,涉及到污点表示问题。其中污点表示问题具体为:污点分析主要分析变量的状态变化,使用多级记录,分析过程中记录变量本身的信息,包括变量的污染状态、常量的值、以及变量的内部信息,例如集合的内部状态、对象的字段状态、map的key-value对等信息等这些更细粒度状态。
过程内的污点分析结果直接关系到漏洞报告是否准确,在分析过程中,程序模拟java栈的进出栈操作,维护每个变量的状态,程序的分析过程即为操作数栈和本地变量表之间的操作,每个字节码操作都有对应的栈变化。使用可变的ArrayList模拟本地变量表和操作数栈,list容量大小等于局部变量表大小加上操作数栈大小。过程内污点分析涉及到三个问题:污点表示问题,基本块内分析,基本块间分析。
3.1)污点表示问题。变量状态分为三种:safe、unknow、tainted。常量初始化值与净化函数返回值为safe状态,source函数的返回值为tainted状态,方法参数初始化为unknow状态。所有对象都会维持一个source列表,每次生成非safe状态的变量时,该对象的source列表中都会加入依赖的非safe对象的source,并加入当前字节码操作的信息,分析过程中,程序会维持一个不断更新的待确认漏洞集合。每个对象在维持自身状态的同时,还维持了更细粒度的状态。数组对象维持了数组内部状态序列,map维持了不同key对应的变量状态,list维持了内部变量状态序列,如果对象的字段参与了污点传播过程,对象内部也需要维护字段的状态,图3为细粒度多级状态记录示意图。污点表示中还记录了变量的常量数值与字符串值。
3.2)基本块内分析。基本块内分析是连续的字节码指令,不同的字节码指令对应不同的操作。对于常量入栈操作字节码,记录下对应变量的值,对于各种运算操作,先判断操作对象的值是否合法,在合法的情况下根据指令对栈顶值进行运算,如果值不合法,将返回值置为不合法;对数组、list指定项进行操作时,需要对指定的下标值进行判断,从而确定指定下标对应的变量状态,在使用数组中指定位置处变量时,对该位置处变量状态进行判断,如果位置下标无法确定或者对数组的操作无法识别,数组、list内部会被清空,使用自身的状态进行操作;字段相关的操作为putfield、getfield、putstatic、getstatic等指令,指令操作的对象均为栈顶元素,当字段发生了状态变化时,对象内部维护的字段状态也需要发生变化,初始化情况下,字段状态与对象状态一致;对map中指定key对应的对象进行操作时,记录下对应key的value状态,如果无法确定状态,使用map自身状态代替。基本块内函数调用指令如果调用的是sink函数,判断sink的可感染位置参数状态是否为safe,如果不是,此处sink可能被触发,将所在函数加入待确认漏洞集合,并记录下可被感染的参数位置,也即是可疑漏洞触发位置。如果被调用函数不为sink,判断该函数是否存在于待检测漏洞列表中,如果存在,判断可被感染参数位置处变量状态是否为safe,如果不是,将当前函数更新至待确认漏洞列表,并记录下可被感染参数位置,所有的unknow参数都会被追溯至来源处。基本块内分析是分析具体的字节码指令对变量状态的影响,得到这个基本块的出口状态,包括变量状态,是否执行标记,跳转地址等。
3.3)基本块间分析。步骤3.2)获取基本块中存在变量状态,是否执行标记,跳转地址等信息。基本块合并如图2,入口块默认为执行块,如果当前块不是入口块,对其前驱块进行分析,如果存在跳转目的为当前块的前驱块且前驱块为执行块,当前块也为执行块。如果当前块的所有前驱块均为不执行块,或者存在执行前驱块但跳转目的地址不为当前地址,则当前块也为不执行块;对于不执行块,污点分析会跳过该块,提高执行效率并降低无效路径带来的干扰。基本块在跳转之前存在判断,污点表示中存在基本数据类型的值记录。如果跳转判断的依据是基本数据类型的值,例如,int类型数据大小的判断,boolean类型真假的判断,char值的判断,可以读取污点表示中的常量记录,进行对应判断,并选择判断结果对应的路径;如果判断的条件过于复杂,或者无法得到准确的判断结果,对所有块进行分析。基本块间分析是分析污点变量的分支、合并情况,代码层面的分支结构会显示为块的分支跳转,需要根据跳转条件判断。基本块中存在跳转地址、分支记录等信息,通过这些信息可以判断部分基本块是否会被执行,排除无效块。
3.4)过程间污点分析。分析过程中,系统维护了参数、字段、返回值之间的状态传递关系map。如果方法的参数对字段状态产生了影响,需要将此传递关系保存至参数-字段map中。在分析return指令时,如果栈顶元素的来源中有参数或者对象字段,分别将状态传递关系保存至参数-返回值、字段-返回值map中。过程间分析结束向这三个map中更新该方法污点传播情况。在分析调用某个方法指令时,可以从这几个状态传递map中寻找该函数,并对参数、字段、返回值的状态进行相应的调整。对于未知的函数,返回值的状态由所有参数的状态共同决定,即返回参数当中最危险的状态。方法调用可能产生返回值,返回值状态取决于调用方法的实例对象、方法参数;方法参数状态可能受到实例对象状态影响;实例对象状态可能受到方法参数影响,这三者之间的影响关系通过过程间污点分析得到、
步骤4,符号执行验证:在步骤3得到的可疑漏洞触发位置前插入自定义变量,使用符号执行工具检验路径的可达性,在约束求解阶段跳过不包含标记变量的路径。
静态污点分析考虑了程序中的所有的调用与路径,但是有些路径是不会被执行的,因此会有误报产生。符号执行技术可以用来检测路径可达性,并排除一些不大可能执行的路径。在符号执行之前,向源代码中插入自定义标记变量。
待验证漏洞列表中的记录都包含了位置信息和路径信息,但这些位置不一定可达,使用符号执行工具对源码的可达性进行检测,在代码的可疑漏洞前加上恒为真的分支,不影响程序的执行,符号执行工具会将分支判断加入到约束表达式中求解,可以得到漏洞位置的可达性信息。这么做的好处是可以利用加入的分支筛选出包含可疑漏洞的路径,排除大量不包含可疑漏洞的无效路径,另一个方面来说具有可拓展性,可以与不同的符号执行工具结合(如EXE、KLEE)。
所述步骤4具体包括:
4.1)自定义变量插入。在可疑漏洞触发位置前定义变量boolean Tlocation=true;并在sink前加入判断if(Tlocation)sink();该代码不会对程序的执行产生影响,但是在可疑漏洞的执行路径上增加了变量Tlocation。
4.2)可达性判定。符号执行工具会将执行路径上所有条件连接得到约束表达式,在对约束表达式求解过程中,判断约束表达式是否存在Tlocation。如果不存在Tlocation,表明该路径上不存在可疑漏洞,跳过该表达式的求解步骤;如果表达式中存在Tlocation并且有解,将表达式中所有Tlocation对应的漏洞信息加入到确认的漏洞列表中,并将漏洞报告给用户,如果表达式中存在Tlocation但无解,表明此漏洞不可达。
本发明使用多级的污点记录结构,分析了程序内部代码块的分支跳转情况,提高污点分析的准确性,将污点分析和符号执行技术结合,保证了静态分析的全面,并且用符号执行技术排除静态分析带来的大量误报,在符号执行过程中跳过了大量无关路径的约束求解步骤,提高了执行效率。
以上所述,仅为本发明的具体实施方式,但本发明的保护范围并不局限于此,任何属于本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到的变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应该以权利要求的保护范围为准。