首页> 中国专利> 基于数据流特征的比较函数识别系统及识别方法

基于数据流特征的比较函数识别系统及识别方法

摘要

本发明属于比较函数识别技术领域,具体涉及一种基于数据流特征的比较函数识别系统及识别方法。本发明通过分析函数的控制流,从中提取循环路径和分支路径,构建数据流并检测数据流特征是否匹配,通过将路径中的指令转为中间语言VEX IR指令,支持ARM、MIPS、PPC和x86指令集,不依赖源码等信息,并且受编译器选项、编译器版本以及优化等级的影响较小,对glibc库和自定义实现的比较类函数都有很好的识别效果。经实验评估表明,当缺少源码、函数名等信息时,相比于FLIRT和SaTC,CMPSeek有着更高的精准率和召回率。

著录项

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2022-09-16

    实质审查的生效 IPC(主分类):G06F 8/70 专利申请号:2022103986394 申请日:20220415

    实质审查的生效

说明书

技术领域

本发明属于比较函数识别技术领域,具体涉及一种基于数据流特征的比较函数识别系统及识别方法。

背景技术

随着物联网的快速发展,越来越多的嵌入式设备走进我们的生活,它们往往出现于安全领域的关键位置和靠近终端的隐私场所,如路由器、交换机和打印机等设备。然而,最近的研究表明市场上有很多嵌入式设备存在后门,后门是指一种用于秘密绕过软件、计算机系统、密码机制等正常认证流程,获取计算机系统的访问权限或经密码系统加密后的明文的程序方法。其中披露最多的为硬编码后门(即口令后门)。如2013年在D-Link路由器中发现的口令后门:浏览器 User-Agent设置为"xmlset_roodkcableoj28840ybtide"后就可以远程控制路由器;2016年在Fortinet的防火墙中发现的SSH后门,硬编码的密码口令为"FGTAbc11*xy+Qqz27";2021年在合勤科技公司Zyxel 的防火墙、VPN等设备中发现的管理员级别账户{username:"zyfwp", password:"PrOw!aN_fXp"},使用该账户就可以通过Web管理面板对设备进行访问。

口令后门为最常见的后门之一,其危害严重,影响深远,造成的损失不可估量。在口令后门触发过程中,比较类函数不可或缺,因此有不少方法借助比较类函数检测口令后门。

在嵌入式设备中基于比较类函数的漏洞挖掘技术研究颇多。2015 年Yan等提出的二进制分析框架Firmalice就需要借助于strcmp和 strncmp等函数来定位关键路径,对关键路径进行切片,通过静态符号执行来判断是否存在确定性约束,若存在则有后门。2017年Thomas 等提出的基于静态数据权重比较的后门识别方法Stringer,原理为定位strcmp、memcmp和strstr等函数来查找定位参与比较的字符串,然后按提出的算法计算字符串的权重,根据权重比较识别出二进制程序的口令后门。2020年Redini等提出的静态污点分析框架Karonte 通过建模和跟踪多二进制文件交互来分析固件,在二进制文件之间传播污点信息以识别不安全的交互并识别漏洞,但其仍需要借助strcmp 和strncmp等函数的信息静态跟踪和传播污点数据。2021年,Chen 等人提出的定向模糊测试工具SaTC匹配前端的关键字和后端的输入项,对敏感输入进行污点分析来识别漏洞,但SaTC同样需要strcmp 和strncmp等函数来定位敏感输入。

当前对剥除函数名等信息的二进制文件函数识别技术以静态分析方法为主。如IDA Pro中的库文件快速识别与鉴定技术(Fast Library Identification andRecognition Technology,FLIRT),首先分析二进制程序,找到程序使用的库函数名称和版本信息,然后在GitHub或其他开源平台下载源码,编译库函数为目标程序架构,选取函数的二进制代码的前若干位字节制作函数签名,最后根据签名匹配的方式识别程序中的函数;然而FLIRT方法需要源码,函数识别效果会受到编译器类型、编译器版本、优化等级、优化选项等影响。在Karonte和SaTC 中都提出了基于特征匹配的静态函数识别方法,但所采取的特征较为简单:1)有循环结构;2)循环中有比较指令。然而满足上述条件的函数不一定具有比较字符串的功能,具有较高的误报率和漏报率。

而实际上,在嵌入式设备中,出于商业竞争或者软件安全的需要,厂商往往不公布开发文档或源码,而是以二进制的形式发行软件,甚至会剥除程序中的函数名、符号表等信息。在此情况下,比较类函数识别对口令后门的发现和修复具有重大意义和价值。但是当前函数识别方法存在以下问题:FLIRT方法需要源码制作函数签名,识别效果依赖编译环境,而二进制程序往往不公开源码,因此FLIRT难以识别程序中的比较类函数,尤其是自定义实现的比较类函数;Karonte 和SaTC方法采用的函数特征较为简单,具有较高的误报率和漏报率。

发明内容

针对目前的比较类函数识别方法存在误报率和漏报率高的缺陷和问题,本发明提供一种基于数据流特征的比较函数识别方法。

本发明解决其技术问题所采用的方案是:一种基于数据流特征的比较函数识别系统,该系统包括CFG提取和循环检测模块、循环指令提取模块、比较操作分支模块、VEX IR指令生成模块、数据流构建模块、数据流分析模块和比较类函数识别模块;所述CFG提取和循环检测模块分析函数中是否包含循环路径;所述循环指令提取模块和比较操作分支模块分别用于提取循环块内和循环内比较操作分支到函数返回的指令;所述VEX IR指令生成模块借助于开源库pyvex 将二进制代码转换为中间语言VEX IR指令,方便系统支持多种指令集架构;所述数据流构建和数据流分析模块从VEX IR指令中提取数据流中变量关系,生成数据流DFG并进行分析;所述比较类函数识别模块根据数据流特征检测循环路径和分支路径是否匹配,从而判断函数是否为比较类函数。

本发明还一种基于数据流特征的比较函数识别方法,包括以下步骤:

步骤一、提取函数的控制流CFG,将基本块视为顶点v,基本块之间的跳转关系视为有向边e,将函数CFG转为有向拓扑图G,

G={V,E}

其中:V={v

e

步骤二、识别有向图G中是否存在循环;

(1)若有向图G中不存在循环路径,直接认为其为非比较类函数;

(2)若有向图G中包含循环路径,提取循环路径和从循环跳出到函数返回的分支路径,将循环路径和分支路径转换为中间语言 VEX IR指令,构建数据流DFG;然后根据数据流DFG特征是否匹配,若匹配则认为是比较类函数识别,否则认定为非比较类函数。

上述的基于数据流特征的比较函数识别方法,步骤一中调用IDA Pro内置IDAPython插件的FlowChart()类和self.succs()函数获取V和 E。

上述的基于数据流特征的比较函数识别方法,步骤二中使用开源库NetworkX的DiGraph()函数快速构建有向图G,并调用 simple_circles()识别图G中是否存在循环。

上述的一种基于数据流特征的比较函数识别方法,步骤二中若数据流DFG同时满足以下特征则识别为比较类函数,

(1)数据流上存在环结构,并且环上存在比较运算和算术运算;

(2)数据流上存在Cz点和Cmp对;

(3)存在Cz点到Cmp对的路径,并且Cz点先于Cmp对出现;

(4)环上Cmp对跳出循环后,都能到达函数Rt点。

本发明的有益效果:本发明分析比较类函数源码,将其编译成不同指令集架构,分析控制流和数据流的特征,构建基于数据流特征匹配的比较类函数识别模型,提出并实现了比较类函数识别方法 CMPSeek,该方法不依赖源码、函数名、符号表等信息,识别效果几乎不受编译环境影响,能够识别任何方式实现的比较类函数,支持 ARM、MIPS、PowerPC(PPC)和x86指令集,具有良好的适用性。

从GitHub、Stack Overflow等平台上收集比较类函数,构建开源库函数数据集A和自定义实现函数数据集B进行测试。实验结果表明,当缺少源码、函数名等信息时,相比于FLIRT和SaTC,CMPSeek 在精准率和召回率上都有着更好的结果。

附图说明

图1为本发明识别系统CMPSeek流程图。

图2为Karonte中识别比较类函数。

图3为SaTC中识别比较类函数。

图4为glibc库中strcmp函数源码。

图5为ARM架构下strcmp函数。

图6为strcmp函数DFG中的循环路径。

具体实施方式

在嵌入式设备中基于比较类函数的漏洞挖掘技术研究颇多。2015 年Yan等提出的二进制分析框架Firmalice就需要借助于strcmp和 strncmp等函数来定位关键路径,对关键路径进行切片,通过静态符号执行来判断是否存在确定性约束,若存在则有后门。

2017年Thomas等提出的基于静态数据权重比较的后门识别方法 Stringer,原理为定位strcmp、memcmp和strstr等函数来查找定位参与比较的字符串,然后按提出的算法计算字符串的权重,根据权重比较识别出二进制程序的口令后门。

2020年Redini等提出的静态污点分析框架Karonte(见图2)通过建模和跟踪多二进制文件交互来分析固件,在二进制文件之间传播污点信息以识别不安全的交互并识别漏洞,可见,仍需要借助strcmp 和strncmp等函数的信息静态跟踪和传播污点数据。

2021年,Chen等人提出的定向模糊测试工具SaTC(见图3)匹配前端的关键字和后端的输入项,对敏感输入进行污点分析来识别漏洞,但是SaTC同样需要strcmp和strncmp等函数来定位敏感输入。

当前对剥除函数名等信息的二进制文件函数识别技术以静态分析方法为主。如IDA Pro中的库文件快速识别与鉴定技术(Fast Library Identification andRecognition Technology,FLIRT),首先分析二进制程序,找到程序使用的库函数名称和版本信息,然后在GitHub或其他开源平台下载源码,编译库函数为目标程序架构,选取函数的二进制代码的前若干位字节制作函数签名,最后根据签名匹配的方式识别程序中的函数。然而FLIRT方法需要源码,函数识别效果会受到编译器类型、编译器版本、优化等级、优化选项等影响。在Karonte和SaTC 中都提出了基于特征匹配的静态函数识别方法,但所采取的特征较为简单:1)有循环结构;2)循环中有比较指令。然而满足上述条件的函数不一定具有比较字符串的功能,具有较高的误报率和漏报率。

而当前函数识别方法存在以下问题:FLIRT方法需要源码制作函数签名,识别效果依赖编译环境,而二进制程序往往不公开源码,因此FLIRT难以识别程序中的比较类函数,尤其是自定义实现的比较类函数;Karonte和SaTC方法采用的函数特征较为简单,具有较高的误报率和漏报率。为解决比较类函数识别问题,提出一种基于特征匹配的函数识别系统CMPSeek及识别方法。下面结合附图和实施例对本发明进一步说明。

实施例1:本实施例提供一种基于数据流特征的比较函数识别系统CMPSeek,如图1所示,该系统包括CFG提取和循环检测模块、循环指令提取模块、比较操作分支模块、VEX IR指令生成模块、数据流构建模块、数据流分析模块和比较类函数识别模块;其中CFG 提取和循环检测模块分析函数中是否包含循环路径;循环指令提取模块和比较操作分支模块分别用于提取循环块内和循环内比较操作分支到函数返回的指令;VEX IR指令生成模块借助于开源库pyvex将二进制代码转换为中间语言VEX IR指令,方便系统支持多种指令集架构;数据流构建和数据流分析模块从VEX IR指令中提取数据流中变量关系,生成数据流DFG并进行分析;比较类函数识别模块根据数据流特征检测循环路径和分支路径是否匹配,从而判断函数是否为比较类函数。

实施例2:本实施例提供一种基于数据流特征的比较函数识别方法,该方法通过提取函数的控制流CFG,将基本块视为顶点v,基本块之间的跳转关系视为有向边e,将函数CFG转为有向拓扑图G,

G={V,E}

其中:V={v

e

由于IDA Pro内置的IDAPython插件提供了FlowChart()类和 self.succs()函数来可以获取函数基本块和基本块间的关系,因此本实施例直接调用FlowChart()和self.succs()获取V和E(下方算法1中第 3-8行)。

然后使用开源库NetworkX的DiGraph()函数快速构建有向图G (算法1中第9行),并调用simple_circles()识别图G中是否存在循环(算法1中第10行)。

(1)若有向图G中不存在循环路径,直接认为其为非比较类函数;

(2)若有向图G中包含循环路径,提取分支路径,将循环路径和分支路径转换为中间语言VEX IR指令,构建数据流DFG;然后根据数据流DFG特征是否匹配,若匹配则认为是比较类函数识别,否则认定为非比较类函数。考虑到函数CFG中可能有多条循环路径,因此只要有其中一条路径满足条件,就识别为比较类函数。

具体的识别算法示例如算法1所示。

算法1:

输入:(ea)/*函数起始地址*/

输出:(0/1)/*是否为比较类函数*/

1 func←get_func(ea)

2 V←[],E←[]

3 for block in FlowChart(func)do

4 V←V∪block/*获取顶点*/

5 for succor in block.succs()do

6 E←E∪(block,succor)/*获取有向边*/

7 end for

8 end for

9 cfg←generate_cfg(V,E)/*生成控制流图*/

10 loops←simple_cycles(cfg)/*提取循环路径*/

11

12 branchs←get_branch(cfg)/*提取分支路径*/

13 dfg←generate_dfg(loops,branchs)/*生成数据流图*/

14 if is_cmp_func(dfg)/*数据流特征是否匹配*/

15 return 1

16 end if

17 end if

18 return 0

通过CFG提取循环路径和分支路径后,分析路径中的数据流向,将寄存器或者内存地址视为顶点v,数据的传递方向转为有向边e,按相同的方式构建DFG(算法1中第13行)。为更好地说明数据流中的特征,下表1列出相关释义和例子。

表1数据流中的特殊值

*注:在不同架构中函数返回值存放的寄存器不同,如ARM中为r0,MIPS中为ra,表1为 ARM架构。

若函数满足以下4个特征,即识别为比较类函数,否则不是比较类函数。

(1)数据流上存在环结构,并且环上存在比较运算和算术运算;

(2)数据流上存在Cz点和Cmp对;

(3)存在Cz点到Cmp对的路径,并且Cz点先于Cmp对出现;

(4)环上Cmp对跳出循环后,都能到达函数Rt点。

具体的,glibc库中strcmp函数源码见图4,ARM架构下strcmp 函数见图5。

提取图5中的循环路径和分支路径,转为VEX IR指令后构建DFG,循环路径DFG如图6所示(分支路径较为简单,分别为(r2→ r1,r3→r1)和(r2→r1),限于篇幅不给出分支路径的DFG)。在图中Cz={t11},Add={t10,t14},Cmp={(r3,r2)},Cr={t33}。循环中存在比较运算Cmp对{(r3,r2)}和算术运算Add点{t10,t14}(特征a),并且还有Cz点t11以及t11到r3的路径(特征b和c),最后分支路径中都有从Cmp对{(r3,r2)}到Rt点r0的路径(特征d),因此CMPSeek识别strcmp为比较类函数。

试验例:本实施例从不同的角度评估本发明的方法(CMPSeek) 的比较类函数识别效果,并与现有方法FLIRT、Karonte、SaTC进行对比,分别对glibc库函数和自定义比较类函数进行实验,对比三种函数识别方法受编译器选项、编译器版本、优化等级和不同指令集架构的影响。

数据集:分为数据集A和数据集B,A为C语言glibc库中的比较类函数,如表2所示,共计有25个。B为自定义实现的比较类函数,从Github(openwrt和Mirai源码)和StackOverflow等平台上收集比较类函数,整合到一个C程序中进行编译测试。

表2glibc库中的比较类函数

对比方法:FLIRT,Karonte和SaTC(如图2和图3所示,Karonte 和SaTC对比较类函数识别方法完全相同,因此两者中选择SaTC即可)。考虑到FLIRT制作函数签名时需要源码,而且识别效果受编译环境的影响,因此FLIRT中使用的签名来自于glibc库函数,编译器类型及版本为GCC 5.5.0,优化等级为-O0,选择ARM架构为目标程序。

工具实现:CMPSeek是基于IDAPython和pyvex进行实现,并借助于NetworkX对CFG和DFG进行处理。表3展示了各个方法实现主要依赖的工具和支持的指令集架构。

表3三种方法对比

*注:实验中FLIRT使用的函数签名对应ARM架构,因此后续实验中将数据集编译为ARM架构。

评价指标:使用精准率P和召回率R来评估所提方法的效果,精准率和召回率越高,效果越好。

P=TP/(TP+FP)

R=TP/(TP+FN)

式中:TP为真正例,即比较类函数被识别为比较类函数;FP为假正例,即非比较类函数被识别为比较类函数;FN为假反例,即比较类函数被识别为非比较类函数。

编译器以及优化等级:如表4所示为实验评估中使用的编译器类型,编译器版本和优化等级,使用GCC和Clang两个编译器进行测试,并使用buildroot构建了不同指令集的交叉工具链,用于生成不同指令架构的程序。

表4实验评估中使用的编译环境选项

编译器选项对函数识别效果的影响

为比较编译器选项对函数识别效果的影响,使用GCC和Clang 编译器,优化等级为-O0,将数据集A和B编译成ARM指令集架构的二进制程序,函数识别效果如表5和6所示。

表5不同编译器下对数据集A识别效果对比

表6不同编译器下对数据集B识别效果对比

从表5和6可以看出,对于数据集A(glibc库中的比较类函数), FLIRT函数识别效果最好,在GCC和Clang编译器下P分别为1.00 和0.71,但受编译器选项影响较大,CMPSeek和SaTC的P相差不大,但CMPSeek的R能达到0.80,而SaTC只有0.16;对于数据集 B(自定义实现的比较类函数),FLIRT的P和R都为0.00,完全识别不出比较类函数,CMPSeek的P在0.56以上,R在0.67以上,P 和R都优于SaTC,整体表现较为稳定。当有函数源码时,FLIRT函数识别效果最佳,但受编译器选择影响较大,在GCC-5.1.0中有着最好的识别效果,P和R分别为1.00和0.88,CMPSeek也有着较为不错的识别效果,在GCC-4.5.4中表现最好,P和R分别为0.62和0.80;当没有源码时,CMPSeek函数的识别效果好于SaTC和FLIRT,且在GCC和Clang编译器下识别效果基本一致。

编译器版本对函数识别效果的影响

为进一步比较编译器版本对函数识别效果的影响,选择GCC编译器,版本如上表4所示,优化等级为-O0,将数据集A和B编译为 ARM架构的二进制文件,函数识别效果如表7和8所示。

表7不同版本下对数据集A识别效果对比

表8不同版本下对数据集B识别效果对比

从表7和表8中可以看出,对于数据集A,FLIRT识别效果最好, P为1.00,R在0.80以上,CMPSeek次之,P和R分别在0.52和0.72 以上,SaTC最差,召回率R最高只有0.20。对于数据集B,CMPSeek 识别效果最好,P和R分别在0.58和0.68以上,FLIRT的P和R依然为0.00。

三种方法受编译器版本影响不大,对于数据集A,FLIRT在 GCC-5.5.0中表现最佳,P和R达到1.00,因为FLIRT中函数签名的编译环境也是GCC-5.5.0-O0;SaTC和CMPSeek在GCC-4.5.4下表现最好;对于数据集B,三种方法在GCC-5.3.0及以上版本表现最好。

优化等级对函数识别效果的影响

为比较不同优化等级对函数识别效果的影响,选择GCC-5.5.0编译器,优化等级为-O0~O3,将数据集A和B编译为ARM架构的二进制文件,函数识别效果如表9和10所示。

表9不同优化等级下对数据集A识别效果对比

表10不同优化等级下对数据集B识别效果对比

从表9和10可以看出,FLIRT受优化等级影响较大,P和R随优化程度的上升而不断下降,相对而言,CMPSeek和SaTC基本不受优化等级的影响。对数据集A来说,即使在-O3优化等级,综合P 和R来看,依旧是FLIRT效果最好,P和R分别为0.73和0.76;对数据集B而言,则是CMPSeek识别效果最优,P和R都在0.70以上。无论是数据集A还是数据集B,CMPSeek的P和R都高于SaTC。

指令集对函数识别效果的影响

本实验只测试CMPSeek对于四种指令集的识别效果,因此不再分别对数据集A和B进行测试,将A和B的源码整合成一个文件,使用GCC 5.5.0编译器,优化等级选择-O0~O3,分别编译成4种不同架构的二进制文件,实验结果如表11所示。

表11不同指令集对函数识别效果的影响

从表11中可以看出,CMPSeek支持对多指令集架构的函数识别,对不同架构中比较类函数识别效果相差不大,在MIPS架构优化等级为-O0中表现最好,P和R分别为0.67和0.80。

以上所述仅为本发明的较佳实施例,并不限制本发明,凡在本发明的精神和原则范围内所做的任何修改、等同替换和改进,均应包含在本发明的保护范围之内。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号