傅 涛
基于源码与二进制文件的漏洞挖掘技术
傅 涛
(江苏博智软件科技股份有限公司,江苏 南京 210044)
基于源码的漏洞挖掘分析技术是源代码审核技术,它通过对程序的源码阅读分析,检测程序中可能存在的安全漏洞。而基于二进制文件的漏洞挖掘分析技术,则是着眼目标文件中的函数、库函数以及各种间接跳转,获得程序的控制流图,分析反汇编出来的代码或者脚本语言,从而识别出可疑的汇编代码序列,进而发现漏洞信息,为科学实现漏洞挖掘提供有效思路。
漏洞挖掘;源码;二进制文件;虚拟堆栈;动静态结合
漏洞挖掘分析技术是指对未知漏洞的探索,综合应用各种技术和工具,尽可能地找出软件中的潜在漏洞,然后对已发现漏洞的细节进行深入分析,为漏洞利用、补救等处理措施作铺垫。根据漏洞挖掘分析的自动化程度,可分为手工分析、半自动或自动化分析;根据软件源代码的开放性,可分为白盒分析、黑盒分析和灰盒分析三类;根据目标软件的运行状态,又可分为静态分析和动态分析。本文主要研究基于源码的漏洞挖掘分析技术虚拟堆栈分析漏洞挖掘技术。
基于源码的漏洞挖掘分析技术是源代码审核技术,该技术是指对程序的源码通过人工或者运用半自动化、自动化工具进行阅读分析,检测程序中可能存在的安全漏洞的关键点。目前使用最为广泛的是词法分析、控制流分析和数据流分析等。
词法分析的核心是特征数据库,特征数据库中包含了从词法、语法、语义等方面进行分析得出的可能产生安全问题的函数,如strcpy、gets、malloc等。再在特征数据库的基础上对程序进行分析,尤其对那些囊括函数的地方进行重点分析[1]。
控制流分析主要是用来发现程序的执行流与数据操作相关的特征。它的基本方法是对程序的基本块进行标识,标识出程序最基本的模块,以及模块之间的调用关系。它包含了基本模块和控制流程两个部分。通过对基本模块的分析,得出函数、变量、缓冲区等重要的信息,再结合对控制流程分析而得到的程序控制结构的信息,进行宏观和微观的分析。这种分析方法能够得到比较全面的分析结果。
而数据流分析是建立在控制流分析的基础上的,在控制流分析得到程序的基本模块和控制流程后,利用这些信息对程序的函数和进程的数据信息进行全局性的分析。其具体的实现方法是在通过建立程序各个节点的数据流方程,然后通过求解来收集系统的数据流信息。
基于源码的漏洞挖掘分析可以检测出很多漏洞,但同时也存在很多漏报以及误报。现在市面上比较常见的检测工具有很多,比如免费开源的ITS4,FlawFinder,Splint以及一些商业软件如Fortify等。
ITS4[2]是第一款用于检测软件源码中安全问题的代码审计工具,它以命令行方式工作在Linux和 Unix 环境中的一种静态扫描 C/C++语言源代码中安全漏洞的简单工具,可以集成到软件开发环境中。ITS4构造了一种对安全具有威胁的模型结构的数据库,然后使用词法分析技术对源码进行对应模式的搜索匹配。这类检测技术的特点是实现简单、算法效率高,但是由于没有考虑到语法和语义层面的信息,容易出现漏报和误报的情形。
Flawfinder[3]主要用以审查C/C++源代码然后以风险等级来报告可能存在的脆弱点(错误)。它基于Unix/ Linux系统,内嵌了一个C/C++有问题的函数数据库,包括缓冲区溢出危险(strcpy(), strcat()函数等),格式化字符串问题(printf()函数等),竞争条件(access(),chown()函数等),shell元字符危险(exec()函数家族,system()等),以及低劣随机数值获取(random()函数)。然后扫描源代码文件,通过比对数据库函数,得得到潜在的安全漏洞,最后以HTML格式生成报告。
Splint[4]是用来静态检查 C 语言程序安全弱点和编写错误的工具,能进行多种常规的检查,其中包括未使用的变量、使用未定义变量、无法执行的代码、忽略返回值、类型不一致、执行路径未返回、无限循环等错误等。同时它还会通过在源码中添加注记给出的附加信息,使其可以进行功能更加强大的检查。同一般的程序分析工具相比,Splint 可以检查抽象边界问题,全局变量非法使用问题等,因而可以作为检测源代码中缓冲区溢出漏洞的基础之一。但是,由于条件约束分析的要求比较严格,所以检测范围不广。
Fortify是一款在编译阶段扫描C++/JAVA语言的若干种安全风险的源代码审计工具,它是集合了Fortify开发工具包和拥有超过了500个漏洞比较代码的Fortify源代码分析服务的一套产品,其列举所有可以采取行动或执行的计算机代码的路径,并且迅速发现计算机代码的敏感区,然后确定精确的漏洞限制。Fortify开发工具包会产生一个类似于编译器生成的输出,它会停在明显会产生安全危险的软件开发函数前,会提示代码使用了危险函数,将会发生什么以及为什么不要使用这些函数。此外,Fortify源代码分析服务可以在整合构造时生成软件代码存在的漏洞和安全错误分析,也可以分析发现由软件函数接受的外部输入引起的漏洞,同时让产品发现在离散的分段代码中不存在但是结合其他脆弱的内容便会产生的漏洞。
由于不是所有的程序都公开源代码,很多商业的软件只能得到已经编译好的二进制文件,所以就需要逆向工程的处理,在二进制级上进行审核或者比对。
基于二进制文件的漏洞挖掘分析技术,第一步是识别出目标文件中的函数、库函数以及各种间接跳转,获得程序的控制流图;然后再跟踪分析反 汇编出来的代码或者脚本语言,从而识别出一些可疑的汇编代码序列,进而发现一些存在漏洞的关键信息。
目前基于二进制文件的漏洞挖掘分析技术包括二进制补丁比对、有向图分析、污点数据传播分析、IDC脚本分析技术等。
目前常用的二进制补丁比对方法主要分为基于文本的比对,基于汇编指令的比对以及基于结构化的比对。前种方法只适用于若干字节变化的比较,不适合文件修改较多的情况。而第二种方法可以图形化的显示比对结果,同时可以发现一些非结构化的变化(如缓冲区大小改变等),但是仍然存在输出结果范围大,误报情况多和漏洞定位不精确的缺点。结构化比对从逻辑结构的层次上对补丁文件进行分析,但是当比对的两个二进制文件较大时程序的执行效率会非常低。
有向图分析技术利用反汇编软件IDA得到反汇编文件,然后直接通过广度或者深度优先搜索算法,搜索汇编代码中的Ret,Call指令。根据软件逻辑流程得出函数调用有向图,用每个调用函数点作为有向图的节点,其中包含了函数的入口地址,局部变量使用情况,分配的堆栈空间大小,调用者传递的参数以及返回地址等信息。然后在有向图中判断每个调用函数是否进行了参数边界检测,特别是那些容易引发漏洞的函数调用。图1显示了一个简单的有向图。
需要指出的是,由于编译器的不同,不同函数被编译后采用的寻址方式又不尽相同,致使程序在反汇编后,提取相关函数的匹配搜索变得比较困难,而如何对编译器进行优化又是一个难以解决的问题。
图1 简单有向图示例
污点数据传播分析技术可以分为静态分析和动态分析两类,这里只对其静态分析技术进行介绍。
静态的污点数据传播分析涉及数据流和控制流等多个方面,首先通过反汇编软件得到反汇编文本,然后抽取其中的语法、语义特征,记录数据流向,监控污染数据的产生、传播轨迹。
对于没有源码的二进制文件,污点数据传播分析通过双向数据流分析,从污点数据输入开始,自上而下形成一棵传播树;再从反汇编文本中搜索可疑函数的调用,然后从这些函数调用的地方开始向上回溯,找到两者相交的位置(可能不存在交点),从而产生污染流路径。将污染数据标记为“tainted”,通过程序语句传播“tainted”数据,凡是对“tainted”数据进行添加、插入、合并等操作,那么它的结果值也肯定是“tainted”。最后再分析交点处指令,判断是否进行了污点数据的长度检查,进而判断漏洞是否存在。
污点数据传播分析技术在搜索字符串操作函数时受到编译器优化的影响,同时构造完整的污染点数据也是一个难点。
IDC 脚本分析技术主要是基于IDA Pro 的静态分析技术,在漏洞挖掘分析时对于缓冲区溢出漏洞方面的检测要比前两种技术更有效[5]。IDC脚本分析技术的关键是在汇编代码中搜索诸如ReadFile,recv等数据输入函数的调用,在这些函数后面如果能够搜索到容易产生漏洞的关键函数,比如strcpy(),sprintf()等函数的调用,则记录相应的内存地址,并且检查在调用函数前是否进行了数据长度的检查,如果没有就有可能存在潜在的安全漏洞。
虚拟堆栈分析是挖掘缓冲区溢出漏洞常用的动态分析技术[6]。它首先进行格式化分析,然后在这基础上通过动态拦截软件运行时的可疑函数调用,创建记录所有函数缓冲区使用情况的虚拟堆栈表;其次判断缓冲区是否在堆中,如果缓冲区在堆中则定位堆指针,而如果缓冲区在栈中则通过查询虚拟栈表,来获得缓冲区位置、大小以及函数的返回地址等信息;最后将得到的信息与限定条件进行比较,得到分析的结果,进而判断是否存在安全问题,图2显示了虚拟堆栈分析的流程。
虽然虚拟堆栈分析的方法比较简单,但是在虚拟堆栈分析中,如果没有后期人工分析的有效介入,还是很难实现漏洞的挖掘,因此,漏洞挖掘的成功率在很大程度上依靠人的经验,要实现系统化困难很多。
图2 虚拟堆栈分析流程
单纯地通过静态或者动态地分析挖掘漏洞,总是不可避免的存在一些缺陷和问题。动态分析和静态分析又有着各自的优势,可以通过将静态与动态分析方法相结合进行漏洞挖掘分析,以求更好的弥补各自的缺陷,发挥各自的优势,达到更好地漏洞挖掘分析效果。
下面以缓冲区溢出漏洞的挖掘分析为例,详细阐述这种方法的处理流程,具体方法为:
(1)首先,对于有源代码的软件程序,将 目标程序通过源代码扫描软件进行分析,查找目 标程序中存在的容易发生缓冲区溢出的函数,比如strcpy()、sprintf()等,如果发现直接进行修改直至没有。然后将目标程序进行编译,编译成为可以执行的二进制文件,进而转为执行第二步的漏洞挖掘分析。
(2)对于没有源代码的二进制文件,通过反汇编软件获得反汇编代码,然后根据strcpy()、sprintf()等函数的特征代码在目标软件的反汇编代码中搜索strcpy()、sprintf()等容易发生缓冲区溢出的函数。再结合IDA或者Ollydbg 动态加载目标软件,接着在所有搜索到的关键函数处设置断点,通过改变输入数据不断观察调试器异常行为,最后确认脆弱点。
本文讨论了基于源码、基于二进制文件和基于静以及动态结合的漏洞挖掘分析技术。不同的漏洞挖掘技术在漏洞挖掘分析中存在不同的特点,将静态分析与动态分析相结合的漏洞挖掘分析方法相可以更好地发挥各自的优势,达到更好地漏洞挖掘分析效果。
[1] 周英. 基于词法分析的源代码自动分析技术[J]. 计算机与信息技术, 2010(4): 61–62.
[2] Cigital. ITS4. [EB/OL]. http://www.cigital.com/its4.
[3] Cigital. FlawFinder. [EB/OL]. http://www.dwheeler.com/ flawfinder.
[4] Splint. [EB/OL]. http://splint.org/.
[5] 唐正军. 网络入侵检测系统的设计与实现[M]. 北京: 电子工业出版社, 2002: 103-251.
[6] 吴晨, 张量, 张静. ASP. NET+SQLSERVER 数据库开发与实例[M]. 北京: 清华大学出版社, 2004: 351–422.
[7] 徐欣明. 一种缓冲区溢出漏洞自动挖掘及漏洞定位技术[D]. 华中科技大学硕士论文, 2008.
[8] 曹军. Wnidows危急级漏洞挖掘及分析技术研究[D]. 四川大学硕士学位论文, 2006.
[9] 罗鸿彦. 基于逆向分析的缓冲区溢出漏洞挖掘技术[D]. 上海交通大学工学硕士学位论文, 2008.
[10] 史尤昭. 数据挖掘技术研究与应用[J]. 软件, 2015, 36(11): 38-42.
[11] 印杰, 李千目. 软件代码漏洞的电子取证技术综述[J]. 软件, 2015, 36(12): 49-59.
Vulnerability Mining based on Source Code and Binary Files
FU Tao
(Jiangsu Elex Software Technology Co., LTD, Nanjing 210044)
The vulnerability mining analysis technology that based on source code is the source code review technical,which attempts to detect possible security vulnerability by reading and analyzing the source code. Moreover, vulnerability mining that based on binary files, which is aimed at the functions, library functions, and various indirect jumps of the object file, obtaining the control flow diagram of the program and analyzing the disassembled code or script language. Accordingly, this vulnerability mining can identify the suspicious assembly code sequence, and then discover the vulnerability information, which provide effective ideas for the scientific implementation of vulnerability mining.
Vulnerability mining; Source code; Binary files; Virtual stack; Dynamic and static combination.
TP311
A
10.3969/j.issn.1003-6970.2018.07.019
傅涛(1980-),男,博士,副研究员,高级工程师,曾获中国人民解放军和江苏省政府科技进步奖。主要研究方向:计算机网络,信息安全。
本文著录格式:傅涛. 基于源码与二进制文件的漏洞挖掘技术[J]. 软件,2018,39(7):95-97