APP下载

缓冲区溢出检测技术综述

2023-12-05邵思豪李国良朱宸锋李典恩

信息安全研究 2023年12期
关键词:缓冲区漏洞静态

邵思豪 李国良 朱宸锋 李典恩

1(辽宁工程技术大学工商管理学院 辽宁葫芦岛 125105) 2(辽宁省大数据管理中心(辽宁省信息中心) 沈阳 110002) 3(悉尼大学商学院 悉尼 NSW2006) 4(东北育才学校 沈阳 110179)

1988年Morris蠕虫病毒利用缓冲区溢出漏洞造成全世界6000多台网络服务器瘫痪,随后出现的Code Red,Blaster等蠕虫也是利用缓冲区漏洞进行传播,造成损失巨大[1].这使得缓冲区溢出漏洞成为国内外信息安全研究领域的关注焦点.

在2021年CWE/SANS机构总结的25大危害性最强的软件缺陷中,缓冲区溢出漏洞排名第一[2].2001—2021年的CERT报告显示,与缓冲区溢出有关的漏洞一直占最大的比例[3].2017年,全球爆发的比特币病毒正是利用缓冲区溢出漏洞,造成至少150个国家、30万用户中招,经济损失达80亿美元,体现了其危害的广泛存在与严重破坏性.

为防御缓冲区溢出漏洞,相应的漏洞静态检测技术、漏洞动态测试技术、漏洞运行时防护技术、漏洞自动利用技术、漏洞自动修复技术不断更新创新.然而,当今信息社会软件规模不断扩大[4],软件数量不断增多,缓冲区溢出漏洞的数目不减反增[5].中国国家信息安全漏洞库(CNNVD)报告显示:2022年2月国内信息技术产品新增漏洞1859个,其中缓冲区溢出漏洞240个,占比最高为12.91%[6].

本文针对上述问题对缓冲区溢出漏洞检测技术进行分类讨论,对各类检测技术进行脉络梳理,对具体技术进行对比分析,辅助科研人员了解溢出漏洞技术发展历程和已有技术方案特点及不足,更有利于相关行业人员进行技术创新.

1 缓冲区溢出简介

缓冲区是一段连续的内存空间.当向缓冲区读或写一段数据的长度(length)超出缓冲区本身大小(size)时,便会触发缓冲区溢出漏洞[2].其中,读溢出可能会导致数据读入异常,引发程序宕机和拒绝服务攻击.写溢出则可能导致程序被黑客劫持,获得系统控制权限,危害更为严重.

用新闻5要素刻画缓冲区溢出,如图1所示,1)When:读或者写;2)Who:数据;3)Why:超出边界;4)Where:缓冲区;5)What:读取了相邻内存或覆写了相邻内存,违反了内存安全.缓冲区溢出漏洞使攻击者能够执行恶意代码或者使程序崩溃[7].如图2所示,本文对CWE[2]中安全漏洞进行梳理,共有11项是缓冲区溢出漏洞,将其分为3大类:1)不安全的开辟缓冲区;2)不安全的读缓冲区;3)不安全的写缓冲区.

图1 新闻5要素刻画缓冲区溢出

图2 缓冲区溢出分类和CWE对应关系

缓冲区溢出漏洞检测技术旨在防止软件内部的缓冲区溢出漏洞被外部攻击者利用[8].因此,检测技术可分为漏洞静态检测技术、漏洞动态检测技术、漏洞运行时防护技术、漏洞自动利用技术和漏洞自动修复技术.

2 静态检测技术

静态检测是不运行软件,针对程序源代码或目标码进行分析的技术[9].静态检测常用的基础模型有抽象语法树、控制流图、函数调用图、系统依赖图、值流图、值依赖图等.

抽象语法树(abstract syntax tree, AST)是编程语言源代码的树状表现形式[10];控制流图(control flow graph)是一种反映程序逻辑控制流程的有向图[11];函数调用图(call graph)描述了函数或之间潜在的控制流[11];系统依赖图(system dependence graph)是一种同时描述程序数据依赖关系和控制依赖关系的模型[12];值流图(value flow graph)是一种反映程序中变量值流向关系的有向图;值依赖图(value dependence graph)是一种构造程序值依赖关系的有向图[13],可以理解为是对值流图的一种扩展.静态分析的分析敏感度有3个衡量维度:流敏感、路径敏感、上下文敏感[14].

如图3所示,静态检测技术有2大类:一类是特征分类,从最原始的字符串匹配,到后来Unix grep采用的词法分析,再到后来的基于语法进行分析.2014年以后,机器学习领域的飞速发展,使得关注多特征的缓冲区溢出静态检测特征分类方法重新回归学术领域.另一类是基于软件分析的方法.程序静态检测技术通常非常关注流敏感,另外缓冲区溢出漏洞的本质是访问缓冲区的大小大于缓冲区分配的长度,所以,一开始也有部分研究侧重于值域分析.后来流敏感和值域分析逐渐结合起来.除此之外,流敏感和其他敏感相关也逐渐相结合,例如流敏感和指针分析、流敏感和上下文敏感、流敏感和路径敏感.又因为缓冲区大时都是通过指针解引用进行访问的,因此有必要通过指针分析来确定究竟在访问哪个数组.

值域分析一般采用抽象解释的方法,通常是多个调用点的区间值取并,所以在上下文敏感方面较弱.通过符号执行技术可以把每个函数调用点分别考虑,实现上下文敏感,再通过指针的别名分析使得函数上下文敏感的信息更充足.2010年以后通常采用符号执行实现流敏感、路径敏感、上下文敏感以及与指向分析结合的技术;通常采用抽象解释实现流敏感、路径敏感、上下文不敏感、但分析值域信息的技术.最理想的方法是在保证效率的基础上构造出流敏感、路径敏感、上下文敏感以及值域分析与指向分析相结合的技术.

2.1 特征分类技术

特征分类:特征分类是指根据程序的某些特征的符合条件对缺陷进行判断的方法.早期的方法基于词法匹配,若匹配到调用函数strcpy则将其判定为缓冲区溢出缺陷.后来的方法基于语法匹配,在匹配到函数strcpy后还要对其涉及的参数特征进行分析,再作进一步判断.发展到现在,该技术借助机器学习算法考虑的特征值更多,判别方法更为智能准确.

最初始的基于特征分类的缓冲区溢出漏洞静态检测技术是利用字符串文本模式匹配技术.后来通过过滤掉空格等无效字符,过渡到基于词法的缓冲区溢出漏洞静态检测技术[15].词法分析技术[15-17]快捷且简单,但是其能力有限,因为没有考虑程序的语法与语义信息.

后来出现了基于语法层次的方法扫描可执行程序代码,如Tevis等人[18]通过分析可执行文件及检查符号表,判断是否存在脆弱性库函数名字,跟踪被0填满的超过50B或者更多的区域(这些区域可能会被放置恶毒代码).

随着近年来机器学习技术的崛起,Bindu等人[19-20]将缓冲区溢出漏洞检测问题抽象为基于sink结点、输入类型、输入验证结点等代码属性的二元分类问题,借助支持向量机、决策树等分类器进行学习.因为只涉及到属性的收集和分类,未涉及符号执行、约束生成、约束求解等复杂的数学逻辑运算,因此算法相对高效.

2.2 抽象解释技术

抽象解释理论是由Cousot等人[21]提出的关于程序静态分析的基于格论的一种近似理论.抽象解释的典型算法有多面体分析、八面体分析和区间分析.

Wagner等人[22]将缓冲区溢出抽象为分配空间(size)与读写空间(length)的值域求解和大小关系约束判定问题,对后续研究具有较大启发作用.但其具有流不敏感和上下文不敏感的不足.

针对Wagner方法的不足,Weber等人[23]在借鉴Wagner的方法基础上,通过对流敏感的分析,分析全局变量使用、函数调用等改善了Wagner的方法.其分析的基础模型是SDG.

Ganapathy等人[14]基于Codesurfer[24]工具生成的SDG图的结点去检测BOF,使用4个约束变量(使用和分配的最大、最小值)去模型化指针到字符缓冲区上.流不敏感使其产生了大量误报.

Sotirov等人[25]假设大多数BOF出现的原因是调用脆弱性库函数时使用了未经验证的参数,使用污染数据传播分析去检测可疑的函数调用,该方法基于漏洞检测方法的污点分析和编译器优化技术中的值范围传播技术的组合,提供了一个C程序中的缓冲区溢出漏洞检测静态源代码分析技术.

Gong等人[26]对strcpy等字符串操作函数进行函数摘要运算,对缓冲区访问涉及的变量进行区间分析,但由于上下文敏感易导致状态爆炸的问题,该方法不是上下文敏感的分析,此外只考虑部分函数,因此会导致部分误报和漏报.

文献[26-28]都是流敏感、路径敏感、上下文不敏感、同时结合值域分析的静态检测算法.不同点是:Gong等人[26]侧重检测字符串操作函数或内存操作函数导致的溢出漏洞;Brat等人[27]更侧重大型工程需求吞吐量大;高凤娟等人[28]侧重数组访问越界这类漏洞,并且在结合污染数据传播分析的基础上,又采用了区间分析和指针分析,是目前抽象解释流派最有代表性的检测算法.

2.3 符号执行技术

符号执行是通过将程序中的变量抽象化表示,再模拟程序的执行,从而得到含有变量间关系的表达式的推理方法[29].符号执行往往应用在控制流模型中.虽然符号执行能实现路径全覆盖,但可能带来的状态爆炸问题一直困扰着科研人员.

符号执行常常结合污染传播分析技术.在污染传播技术中,包含不信赖输入的程序位置被标记为污染的,由污染位置开始,传播到的位置都被认为是污染的.通过计算不动点计算来分析污染信息的传播(类似常量传播算法).如果被污染的信息在敏感操作使用(如作为不安全函数调用的参数),那么相关的语句被标记为相应的缺陷.

Xie等人[30]使用符号执行的手段进行检测,分析不合法的缓冲区下标、指针解引用和不合法的函数参数.在每个访问缓冲区的点求解约束.如果无法求解则没有警告生成.

Cova等人[31]通过遍历可达程序执行路径,采用提取的信息来执行上下文敏感的污染传播分析,进行检测二进制代码的BOF.该方法标记不安全的函数,并将其分类为污染源或者敏感的槽结点,这样进行符号执行的剪枝.

Le等人[32]提出的Marple是较为典型的基于控制流图的利用符号执行和约束求解的缓冲区溢出漏洞检测模型.该方法路径敏感、流敏感、且一定程度上下文敏感.但性能开销较大,不适用于大型工程.Le等人[33]虽然后来对算法进行优化,在检测精度和吞吐量方面有提升,但仍不适用于大型工程.Ding等人[34]在循环处理上将循环抽象成基本块,优于Le等人[32-33]的固定循环次数方法,提高了分析精度.同时用语法分析过滤掉某一类结点,与Marple相比吞吐量较大.不足是某一类结点被暴力过滤会导致检测结果漏报.

3 动态检测技术

动态检测技术是通过选择测试用例来运行程序,检验漏洞是否存在[35].其测试用例输入变量的生成策略可分为3大类:1)传统模糊测试.旨在输入变量畸形值.2)智能灰盒测试.结合静态分析,将程序内部约束信息加入去生成测试用例.3)输入变量覆盖率转换.选择有代表性输入变量集合,对被选择变量集合进行路径全覆盖测试.

3.1 传统模糊测试

传统模糊测试一开始是通用的测试,只是简单地随机产生数据,以1989年Miller等人[36]用其测试Unix系统完备性为起源;后来发展成基于领域知识的传统模糊测试[37],其具备一定格式信息,能够绕过软件的初始判断,提高触发漏洞的成功率.

3.2 智能灰盒测试

模糊测试与静态分析技术结合,发展成智能灰盒测试[38-46].从一开始的利用符号执行来遍历路径生成约束,基于约束生成用例[40];到后来的符号执行与具体执行相结合,用具体执行指导符号执行[39];从开始生成约束时指针不敏感[40],到后来的部分指针敏感(考虑指针通过常值偏移的情况)[38],再到进一步指针敏感(考虑指针通过变量偏移的情况)[41];从最开始的利用静态分析分析源代码生成相关约束[38-41],到后来的利用动态插桩、反汇编等技术分析二进制代码生成相关约束[42-46];从开始的生成约束时只考虑路径可达条件[43,45],到后来的将路径可达条件和漏洞触发条件取交作为约束,进行测试用例生成[46].智能灰盒测试技术在逐渐地逼近但不会达到绝对的溢出漏洞全覆盖.

3.3 输入变量覆盖率转换

对于输入变量是n维的程序,若能覆盖n维变量则覆盖率最高,但测试用例呈指数增长,实际应用中不可行,因此,科研人员将思路转为追求另外的输入变量覆盖率:例如从n维变量选出t维攻击控制相关的变量,将n维变量覆盖转化为输入变量任意t路覆盖,也能取得一定的检测效果.Wang等人[47]对外部输入变量的攻击控制参数集合进行t路覆盖,极大地降低了测试用例数量,但对大型工程测试效果不尽如人意.

4 运行时防护技术

如图4所示,本文将缓冲区漏洞运行防护技术分为3大类:1)完整性防护.监控栈中的EBP等值或性质是否完整未被修改.2)机密性防护.对内存中某些关键对象进行加密,以提高破解攻击难度.3)可用性防护.保障内存中某些关键对象可用性.

图4 缓冲区溢出运行时防护技术发展脉络

4.1 完整性防护技术

在完整性防护方面,最开始的保护策略是采取值验证的方法,最初的保护目标是retaddr的值,从最开始的随机产生canary值,到后来的canary值中含有字符串终止符,再到后来的canary值存放原canary值和retaddr的异或[48];后来由于通过覆写EBP的值也能实现栈溢出,保护目标从retaddr过渡到EBP和retaddr[49];再后来,保护目标进一步一般化,变成将canary值插入内存区域[50],保护内存区域.性质验证也是完整性防护验证重要的一部分,通过判断isOOB属性[51](访问缓冲区的索引值应小于缓冲区分配大小)进行防护.从一开始的针对所有内存区域的fat-pointer,到后来的针对堆内存的low-fat pointer[52],再到后来的针对堆和栈内存的low-fat pointer[53].未来完整性防护将重点围绕保护性质来研究发展.

4.2 机密性防护技术

在机密性防护方面,从一开始的加密指针[54]以使得攻击者即使成功溢出缓冲区,也无法跳转到理想的攻击部位;到后来的通过加入padding[55]的方式随机化栈帧;加入padding的方式对跨栈帧攻击的防御效果较好,但栈帧内部关系仍然是线性的[56],所以后来研究人员通过置换栈帧内部数据[57]破坏栈内存的线性分布信息.

4.3 可用性防护技术

在可用性防护方面,一开始Linux的创始人Torvalds[58]提出了不让堆栈数据执行的方法,该方法能较好地防御return-to-stack或者return-to-heap攻击,但对较为常见的return-to-libc攻击无能为力;后来,研究人员又提出了更换动态链接库[59]的方法,把动态链接库替换成更安全的动态链接库,该方法能较好地防御通过strcpy等函数溢出缓冲区的攻击,但是,对常规的通过数组访问溢出缓冲区的方式无防御能力;2013年,Chen等人[60]提出了SafeStack的方法,当检测到大于等于3次去覆写栈缓冲区时,就通过二进制插桩、运行时重分配内存对象位置等手段,将该危险缓冲区转移到heap上去执行,该方法与一般的防护方法相比,不终止程序执行,实用性较好,且对栈缓冲区溢出防御能力较强,不足之处是未对堆上缓冲区溢出进行防御.

5 自动利用与修复技术

5.1 自动利用技术

根据Bishop等人[61]的研究,自动利用攻击向量在构造时需同时满足大小长度大于缓冲区,含有攻击载荷,通过溢出缓冲区修改特定变量,使得跳转执行到攻击者希望的位置或者更改数据流.因此自动利用技术可按最终目标分为导致程序崩溃[62]、劫持程序控制流[63]、劫持程序数据流[66]3种.

1) 导致程序崩溃.APEG[62]采用动静结合的方式生成约束,对关键点以上动态分析生成约束以提高效率,对关键点以下符号执行追求路径全覆盖.

2) 劫持程序控制流.AEG[63]首先利用静态检测技术找到缓冲区溢出缺陷,然后利用动态分析提取运行信息分析内存布局,再将攻击的条件转换成约束与路径约束取交,利用约束求解器(如SMT)求解攻击向量,最后验证攻击向量是否有效[63].

3) 劫持程序数据流.FlowStitch[64]利用已有的能触发溢出漏洞的输入作为种子文件,通过对内存运行状态分析,构造出能泄露敏感数据的攻击向量.局限性是需要有能触发溢出漏洞的输入文件[64].

漏洞自动利用领域是最新的研究热点,该技术能够通过自动构造攻击用例的方式来发现和检测缓冲区溢出漏洞.该技术具有下述优点:1)能够帮助科研人员从大量程序漏洞中快速甄别出具有高危险性的漏洞;2)一定程度上帮助软件降低遭受高危漏洞攻击的可能.目前的自动利用技术通常无法绕过ASLR和DEP的防御;另外,随着软件的复杂性增加、控制流完整性检测等防御手段的部署,自动生成难度较大.

5.2 自动修复技术

近年来,有些学者将深度学习应用于程序缺陷修复上,借鉴生物学中的基因突变、交叉变异[65]等思想修复缓冲区溢出漏洞,这些都对传统分析技术产生深远的影响.同时,漏洞自动修复策略有从单一修复策略[66]到多元修复策略[67]的发展趋势,例如扩充缓冲区size大小、用安全内存操作函数替换原函数、对缓冲区大小size和写范围length进行判断等多策略修复,提高了修复成功率.

6 总结与展望

6.1 本文工作总结

本文对缓冲区溢出漏洞检测技术进行脉络梳理:1)将静态检测技术划分为特征分类和软件分析方法,其中软件分析方法包含抽象解释方法和符号执行方法2个子类.2)将动态测试技术划分为传统模糊测试、智能灰盒测试和输入变量覆盖率转换3类.3)将运行防护技术划分为完整性防护、机密性防护和可用性防护3类.4)将自动利用技术划分为导致程序崩溃、劫持程序控制流、劫持程序数据流3类.5)将自动修复技术划分为单一修复策略和多元修复策略2类.

6.2 未来研究方向

本文认为,未来缓冲区溢出检测有3个可能研究方向.

6.2.1 优化静态检测技术

通过对缓冲区溢出检测技术的调研,可以发现动态测试技术、运行时防护技术、自动修复技术、自动利用技术的优劣都一定程度上依赖于静态检测技术的精确与否.对于动态测试技术,有的需要通过静态检测技术来生成路径可达约束及缺陷触发约束,有的需要静态检测技术先查出一部分缺陷,再用这些缺陷作为“种子”触发更多的缺陷.

对于运行时防护,利用静态检测技术有助于有针对性地对软件或系统进行防护.对于自动修复,部分技术依赖于静态检测去发现漏洞,静态分析的方法也常常在修复中被利用.对于自动利用,无论攻击的目标是导致程序崩溃、还是劫持程序控制流或数据流,在构造攻击载荷时都需要静态检测进行辅助.可以说静态检测技术是缓冲区溢出检测技术中最为基本、必不可少、被其他技术所依赖的技术.

因此,有必要对缓冲区溢出静态算法进行创新改进.一方面,已有静态检测方法关注数组越界类以及外部污染数据输入导致的、不安全函数导致的、指针迭代造成的溢出漏洞中的某一种,缺乏能把各类溢出漏洞涵盖在内的统一漏洞模型和检测方法.另一方面,基于控制流图的溢出漏洞分析,由于缓冲区分配结点和发生结点间可能会有大量无关节点,在分析时若采用符号执行技术会发生状态爆炸;基于值流图的缓冲区溢出分析由于直接关注sink结点和source结点的切片,可以一定程度上避免状态爆炸问题,但流失了控制流信息,导致误漏报.如何采用值流图作为模型进行分析,同时,精确地提取所需控制流信息是未来静态检测的研究方向.

6.2.2 融合机器学习技术进行检测

机器学习技术近年来发展成熟,对信息安全领域产生深远影响.通过使用机器学习算法,可以学习在不同的上下文中出现缓冲区溢出漏洞的模式,进而提高精度.并且机器学习算法相比传统静态分析算法,较为高效,可保证在一定精度的基础上,应用于大型工程的检测,Bindu等人[19-20]对C源程序和二进制程序都采用了机器学习方法进行检测,取得了较好的检测效果.王剑等人[68]借助卷积神经网络(CNN)和全局平均池化(GAP)可解释性模型模型,实现了对CWE-119类漏洞的检测.

6.2.3 多技术协同检测

如能多技术协同检测,有望获得最佳分析与防护效果:通过静态检测技术分析出候选缓冲区溢出程序漏洞、漏洞发生条件和路径条件取交后的约束表达式;再对其生成含有攻击载荷的攻击向量进行自动利用;接下来,用动态测试的方法验证攻击向量是否生效,同时跟踪记录攻击向量攻击的程序点;最后,利用自动修复技术重点修复攻击向量的攻击点,修复程序漏洞;同时,在运行时对完整性、机密性、可用性进行防护.

猜你喜欢

缓冲区漏洞静态
嵌入式系统环形缓冲区快速读写方法的设计与实现
漏洞
静态随机存储器在轨自检算法
三明:“两票制”堵住加价漏洞
漏洞在哪儿
高铁急救应补齐三漏洞
关键链技术缓冲区的确定方法研究
机床静态及动态分析
具7μA静态电流的2A、70V SEPIC/升压型DC/DC转换器
50t转炉静态控制模型开发及生产实践