2
Journal of Software 软件学报
1 引言
计算机的迅速发展极大地便利了人们的生活,计算机软件渗透进生活的方方面面.以移动端软件为例,工
信部发布的数据
[1]
显示,2018 年我国市场监测到的移动应用程序净增 42 万款,总量达到 449 万款,涵盖生活服
务、日常工具及互联网金融等诸多类别.随着计算机软件的目标客户越来越广泛,需求也越来越庞杂,使软件的
复杂性大幅增加.如 Linux 内核
[2]
2018 年共有 74 974 次提交,增加了 3 385 121 行代码,移除了 2 512 040 行代码,
内核树的总代码行数为 26 132 637 行.与此同时,被披露的安全漏洞数量也呈现逐年增长的趋势.据安全数据库
网站 CVE Details
[3]
发布的报告显示,2016 年共发布 6 447 个安全漏洞,2017 年共发布了 14 714 个安全漏洞,2018
年共发布了 16 556 个安全漏洞,而 2019 年截止到十月已发布了 12 174 个安全漏洞,其中 8.7%的漏洞 CVSS 得
分超过 9.0.除了数量的增长,安全漏洞的形态也呈现复杂性和多样性,给计算机系统的正常安全运行造成极大
的威胁.
目前对于软件漏洞的定义尚未形成广泛的共识,本文参照吴世忠等人
[4,5]
对软件漏洞的定义,即软件漏洞
是指在软件系统或产品的软件生命周期中,由于操作实体有意或无意的疏忽而产生的设计错误、编码缺陷、运
行故障,它们以不同形式存在于软件系统的各个层次与环节之中.一旦被恶意主体利用,比如获得更高级别权
限、泄露软件中用户隐私数据等,将危害软件系统安全,并可能影响构建于软件系统之上的服务的正常运行.由
于安全漏洞具有隐蔽性和可利用性,因此软件提供方通常需要在软件生命周期的各个阶段,利用各种技术手段
尽早发现软件漏洞,降低漏洞的可利用性,从而降低软件系统被恶意损害的风险.
软件漏洞挖掘是检查并发现软件系统中存在安全漏洞的主要手段之一,通过利用各种工具对软件的代码
进行审计,或者分析软件的执行过程来查找软件的设计错误、编码缺陷、运行故障.早期漏洞挖掘技术依据是
否依赖程序运行划分为静态分析方法与动态分析方法,其中静态分析方法一般应用于软件的开发编码阶段,无
需运行软件,通过扫描源代码分析词法、语法、控制流和数据流等信息来发现漏洞.动态分析方法则一般应用
于软件的测试运行阶段,在软件程序运行过程中,通过分析动态调试器中程序的状态、执行路径等信息来发现
漏洞.典型漏洞挖掘工具如 Coverity
[6]
、Klocwork
[7]
以及 Cobot
[8]
等通过对程序源代码进行静态分析来检测系统
漏洞;KLEE
[9]
、S2E
[10]
、Mayhem
[11]
等采用符号执行这种动态分析方法进行漏洞挖掘;libFuzzer
[12]
、Radamsa
[13]
以及 AFL
[14]
等采用模糊测试这种动态分析方法排查错误.同时也有相关研究尝试通过动静态相结合的分析方
法来 提高 检测 效率 和准确率 ,如 angr
[15]
集成 了静 态分析 和动 态符 号执 行,能 够实 现 自动 化分 析二进制 文
件;SAGE
[16]
结合使用了模糊测试和符号执行,并将动态符号执行应用在 x86 架构的程序分析中.近年来,为了提
高漏洞挖掘的效率,也出现了一些自动化或半自动化的漏洞挖掘工具,比较有代表性的如 Bochspwn
[17]
对内核层
采用污点追踪,从而检测用户层泄露数据的行为;Digtool
[18]
针对 Windows 系统,可以自动化捕获程序执行过程
中 触 发 的 漏 洞 ;Syzkaller
[19]
是 谷 歌 团 队 推 出 的 一 款 针 对 Linux 内核 的 无监 督 、 覆 盖 引 导 的 模 糊 测 试 工
具;RapidScan
[20]
漏洞扫描器则通过自动化执行 nmap、dnsrecon 和 wafw00f 等多个安全扫描工具,尝试通过相互
关联扫描结果来发现漏洞.
上述漏洞挖掘方法一般适用于小型规模软件,已经在各类小型规模软件的漏洞挖掘中取得了许多成果,但
是在应对大型复杂软件系统以及变化多样的新型漏洞时,通常无法满足需求.如传统的静态分析方法往往依赖
于人工专家构造漏洞模式,随着软件复杂性增加,人工构造成本过高,且人的主观性会影响误报率和漏报率.动
态分析方法中,监测目标程序的崩溃是模糊测试发现漏洞的重要依据之一,因此测试效果依赖于输入种子的质
量,存在测试冗余、测试攻击面模糊、难以发现访问控制漏洞和设计逻辑错误等问题
[21]
.动态分析方法中的符
号执行方法虽然能以较少的测试用例覆盖更多的程序路径,从而挖掘复杂软件更深层次的漏洞,但仍存在路径
爆炸、约束求解难、内存建模与并行处理复杂等问题
[22]
,单独处理大型软件系统时仍存在较大困难
[23]
.
针对复杂软件系统的漏洞挖掘问题,学术界一方面尝试通过优化和改造现有方法来突破传统漏洞挖掘方
法的瓶颈,另一方面尝试探索新的智能化软件漏洞挖掘方法.由于漏洞是代码缺陷被利用形成的,直观上认为分
析代码可以获取最多的漏洞相关信息,即挖掘软件漏洞的能力与分析代码数据的能力紧密相关,而机器学习方
法非常适合于从海量数据中发现和学习规律.理论研究中 Hindle 等人
[24]
利用统计学的方法将编程语言和自然
评论