同源分析
Last updated
Last updated
在之前的文章中笔者将固件分为两类,即类 **Linux (有明显文件系统)**和 RTOS (一般单个文件),而在论文[29] (Muench) 中给出更细粒度定义可做参考,分为三类:
基于通用目的操作系统的设备。
改进通用的 Linux 核心,用在嵌入式系统中,通常使用轻量级的用户空间环境,比如 busybox,uClibc 等。这类设备中,与定制硬件的交互大部分是通过特定的设备驱动进行的。
基于嵌入式操作系统的设备。
通常适用于一些计算能力较低的设备,虽然可能不存在内存管理单元等高级处理器特性,但是操作系统内核和应用程序代码之间的逻辑隔离仍然存在。比如 VxWorks、ZephyrOS 这样的操作系统,常用于单用途的用户电子设备,比如 LTE 调制解调器或 DVD 播放器等。
不具备操作系统抽象的设备。
这类设备采用所谓的―monolithic firmware,其操作通常基于一个控制循环和从外设触发的中断以处理外部事件。在这些设备上运行的代码可以完全定制,也可以基于操作系统库,但最终形成的固件是一个独立的软件。
同厂商同价位系列的设备一般采用一套代码编译,如果有基础应用存在漏洞,那么其他设备也可能存在相同的脆弱点。与此同时,有些设备会使用openwrt、zyxelos等开源系统编译修改,使用lighttpd、miniupnpd等开源软件或第三方开源库,如果开源软件出现漏洞,那设备也将受到波及。当然,这也可以归类与开源供应安全范畴,这里不作赘述,下阐释一些常见的同源检测方法。
该方法提取固件中的第三方库,使用关联压缩算法对其与数据中的资源库进行压缩,如果关联压缩显著小于单个文件压缩的总和,则可认为是同源性的证据之一。
具体过程是给定两个二进制文件x和y以及压缩算法C,如果 |C(xy)| 明显小于|C(x)| + |C(y)| ,可使用以下公式来度量第三方库之间的同源程度:
其中0≤ncd(x,y)≤1,ncd(x,y)=1表示文件x和y同源, $ncd(x,y)=0$表示文件x和y不同源。
xy表示文件x和y的关联性;| | 表示以字节为单位的文件大小;ncd 指归一化压缩距离。
该方法利用二进制文件中的字符串常量作为不同架构下三方库同源性的指纹标识,首先提取固件包含的二进制程序及依赖库,搜索内部标识字符串、调试信息以及依赖库的名称、版本号等信息,将提取的标识信息与数据库中保存的字符串进行比较,若与某个数据库中第三方库匹配的字符串达到某个阈值,则认为同源。如Busybox
是嵌入式设备常用的一个工具集'其可以被字符串常量Busybox V
标识。
在字符串常量唯一的情况下,匹配的评分标准为匹配字符串的长度总和;在非唯一性的情况下,提出一种启发式的匹配方法,对每个字符串的匹配分数进行量化'计算公式为:
其中libs(s)表示包含字符串$s$的第三方库的个数;len(s)$表示字符串s的长度;μ为常量;μ>1通常取为5,可根据len(s)的大小进行调整。
模糊哈希算法又称为基于内容分割的分片哈希算法,可用于文件同源性比较(恶意代码检测(开源软件漏洞挖掘等。该算法使用一个弱哈希计算文件局部内容,在某个条件下切割文件,然后使用一个强哈希对每片文件计算哈希值,取这些值的一部分并连接起来,与分片条件一起构成多个模糊哈希结果。最后使用字符串相似性对比算法判断2个模糊哈希值的相似度,从而判断2个文件的相似程度。模糊哈希对文件的部分变化(包括在多处修改、增加、删除、部分内容)均能发现与源文件的相似关系,是目前判断同源性较好的一种方法。
Costin 等人首次提出基于模糊哈希的大规模嵌入式固件安全分析方法,通过固件模块关联的方法,采用模糊哈希算法扫描不同固件镜像之间存在的类似漏洞,最终在 693 个固件中关联出了 38 个漏洞文件,但是这种方案需要对每个文件进行一对一的模糊哈希比较,会产生大量的时间开销,且粒度是文件级别的,精确度也不高。李登等人提出的基于第三方库的同源性分析结果对同类固件的漏洞检测也是基于模糊哈希算法实现的,能够准确地对不同类型、架构、版本的固件进行漏洞检测,但由于模糊哈希本身的问题,这种检测方法仍然存在一定的误差。BinARM提出了一种多阶段的检测引擎,可以有效地识别出IED 固件中的脆弱函数,同时实现高精度,实验结果表明这个检测引擎比现有的模糊匹配方法快 3 个数量级。陈昱等人通过深度学习二进制文件中的可读字符串,然后对编码向量生成局部敏感哈希从而实现快速检索,解决了大规模设备固件同源二进制文件检索方法的时间开销问题,只需不到 1s 的时间即可完成一次针对 22,594 个固件的同源二进制文件检索任务。
Multi-MH是首个跨体系结构的二进制代码相似度检测工作,该方法对心脏滴血漏洞进行关联时取得了较好的效果,但其对不同平台的函数控制流图较为敏感。FirmUp提出使用规一化的片段表示程序以解决跨编译器、跨优化选项、跨体系结构的问题,其主要方法是将函数进行基本块级别的拆分,然后将基本块进一步切片成更小的片段,再将这种片段中的寄存器名和地址偏移归一化,以函数为单位制成一张表,以两个表中相同的代码片段的数量作为相似度比较的依据。为了提升效率,discovRE提取更轻量级的语法级别特征来加速特征提取,并且在图匹配之前通过简单的函数级特征进行预过滤,以提升搜索的效率。然而,根据 Feng,这种预过滤方法并不可靠,可能会产生很多的漏报,导致搜索精确度的严重下降。理论上来说,这种依赖于 pairwise 图匹配来检测相似度的算法,必然是低效的。
相比较于直接匹配两个控制流图,Genius从控制流图中学习更高级别的数值特征描述,然后再基于学习到的特征构建搜索。与原始的 CFG 特征相比,学习到的特征对于跨体系结构的更改更能保持不变性,而且通过局部敏感哈希的方式索引转换后的更高级别的特征,可以使搜索 bug 的速度比现有的基于图的搜索快出好几个数量级。针对 Genius 在训练图嵌入所需的代码库时需要的时间开销大的问题,Xu提出基于神经网络构建图嵌入模型,以执行跨平台的相似度检测,实验结果表明,相比于 Genius,训练时间从 1 周下降到了 30 分钟~10 个小时,而且能识别出更多额外的漏洞代码。针对传统的一对一关联匹配检索方法的时间复杂度不能满足大规模同源检索的需求,IHB设计并实现了一种时间复杂度为 O(lgN)同源二进制文件检索方法,其核心思想是通过深度学习网络编码(双向双层 Bi-GRU)二进制文件中的可读字符串,然后对编码向量生成局部敏感哈希从而实现快速检索,其不足之处在于对包含字符串较少或者做过字符串混淆处理的二进制文件的检索能力较差。
虽然上述方法在漏洞搜索领域获取了一定的效果,但在复杂场景中应用时,存在两个局限性。第一,获取的函数语义信息不充分、不准确,导致了很高的假阳率。第二,大部分的方法需要很高的计算开销,这就使得它们很难应用于复杂的大型二进制文件。Gao 提出了VulSeeker和 VulSeeker-Pro,结合 CFG 和 DFG(Data Flow Graph)以形成 LSFG(LabeledSemantic Flow Graph)作为特征向量并且应用了深度学习执行跨平台二进制漏洞搜索的工具。与现有的方法(如 Gemini)相比,精确度要高很多。IoTSeeker无缝结点了 Vulseeker 和Vulseeker-pro,并且支持跨体系结构的函数仿真以获取更好的性能。通过将动态方法应用到快速获取的与漏洞相似的小范围候选函数,提高了搜索的精度,同时又减少了时间的需求。