1、 漏洞补丁存在性检测技术是什么?
漏洞补丁存在性检测技术通俗的理解就是检测目标对象中是否包含修复特定已知漏洞的补丁代码,目标检测对象可能是源码,也能是二进制文件。
2、 漏洞补丁存在性检测技术业务背景
3、 漏洞补丁存在性检测技术有哪些应用场景?
给定某个存在漏洞的某版本开源软件源码/二进制文件,以及对应漏洞信息,检查它是否已经对该漏洞进行打补丁操作,从而消减对应文件检出的漏洞信息。
4、 漏洞补丁存下性检测技术方案
对于检查漏洞是否存在当前主流方法通常分为动态和静态两种方法。
检测对象通常为二进制文件,常用的动态方法就是通过POC进行检测。对于一个特定的漏洞poc信息,通常为能触发该漏洞的一种方法,可能是一段脚本代码、一串命令参数、一个文件等。将软件运行起来,输入或者执行poc,检查程序输出是否存在异常即可检查是否存在漏洞。
优点:
缺点:
静态检查方法是指不需要运行检测目标就可以实现检测的技术统称。根据检查对象的不同静态检查方法有针对源代码的检测技术和针对二进制的检测技术。
基于源码的漏洞补丁存性静态检测核心技术是代码克隆检测。代码克隆检测技术通常有2大类4小类不同的检测方法,其中Type-4技术难点最大,同时检测鲁棒性也最好。
小类 | 大类 | 描述 |
---|---|---|
Type-1 | 句法克隆检测 | 去除空格、空行和注释后,源码内容格式完全相同 |
Type-2 | 句法克隆检测 | 除了对一下函数名、类名、变量从命名以外,源码内容格式完全相同 |
Type-3 | 句法克隆检测 | 片段部分被修改,如添加、删除、从新排序部分代码片段 |
Type-4 | 语义克隆检测 | 语义相似,但源码句法完全不同 |
应用场景:开源软件检测、隐秘漏洞发现、已知漏洞补丁存在性检测等。
优点:
缺点:
基于二进制的漏洞补丁存在性静态检测核心技术是函数代码相似性检测,俗称二进制代码克隆检查 Binary code similarity detection (BCSD),通俗的理解就是来检测两个二进制代码是否由相同源代码编译而来的。
虽然两者的检测的最终目的都是判断两段代码是否一致,但由于源代码文件编译生成的二进制文件影响因素非常的多,即使相同的源代码通过不同编译参数或相同参数多次构建,生成的二进制文件也是不同的,甚至是差别巨大。影响二进制生成的主要因素有:
另外从源代码编译成二进制的过程中,很多源码中存在的信息都被丢弃了,比如变量类型、函数名称等符号信息。由于在源代码编译成二进制文件过程中存在多种影响因素,所以二进制克隆检测技术一直是业界研究的前沿技术,特别是怎么样来提升检测技术的鲁棒性,即一个检测算法或模型能对相同源码生成的不同二进制文件都有好的检测效果,正是二进制克隆检测技术难度大,所以工业界一直也没有一款好的商业工具可以提供漏洞补丁存在性检测能力。
同时由于二进制克隆检测对象为二进制文件,因此和源代码相比对工具的部署方式和运行环境相对宽松很多,既可以公有云方式来部署,也可以本地化来部署。
a. 传统方法
通过二进制反汇编出汇编指令,然后生成中间语言IR(可选),结合控制流图cfg进行图匹配,下面这篇论文的的结构很经典,大多数的BCSD问题基本都是这个结构。然后辅以一些统计学上的信息,比如反汇编出来的函数基本块中包含某些常量/指令信息、基本块哈希什么的处理方法。
?
一个典型例子是谷歌开发的bindiff,通过ida pro反汇编文件,然后对于cfg和基本块信息进行匹配。对于相同优化选项的函数匹配效果尚可,但是如果算上 架构 * 优化选项 数量的样本构建 与解析这个时间成本就难以接受了。
优点:
缺点:
b. 结合AI的检查方法
传统方法历史悠久,但对于跨编译选项和跨架构情况处理效果不好。所以在近期AI流行之后,学界主流对于BCSD问题解决的方法转向了使用AI。由于上述传统方法的效率问题,也导致只能求助于AI方法。
从较远的CNN、RNN、LSTM, 再到现在较为主流的BERT,处理原理大致相似。都是采用自然语言理解(nlp)的方法套用到汇编语言的检查上。
?
单个函数检测流程如上图所示,将汇编语言通过语言模型进行编码,函数编码后生成向量信息,然后对于这些向量直接进行相似度匹配,或者再通过孪生网络训练,最后进行相似度匹配。通常使用向量间的余弦距离来确认两个向量(函数)之间的相似度。对于单次匹配来说,如果相同架构相同编译选项的待检测函数与漏洞函数与补丁函数相似度一定会有差异,这样便实现了补丁函数与漏洞函数相似度确认,达成补丁检测的目的。
原理上大致与机器翻译类似。(以seq2seq模型举例便于理解,仅做打比方, 忽略实际token处理细节) seq2seq模型是一种循环神经网络模型(RNN) 在机器翻译上表现效果不错。网络分为一个Encoder和一个Decoder, 一种语言通过encoder进行编码,然后通过另一种语言的decoder来解码实现机器翻译。这样一个“简单”的模型却行之有效。
?
解决传统方法解决困难的跨架构问题大致原理就是如此,将一种架构指令集看作为第一种语言,然后将第二种架构指令集看作为第二种语言,通过神经网络将其编码成向量,然后进行相似度比较。差异在于seq2seq是直接翻译成另一种语言,而补丁检测使用的是将两边指令集编码为向量。而解决跨优化选项则将两种不同优化选项的汇编语言看成是相同语言的相同语义的不同表达, 让模型学习到该架构指令集的语义信息。
优点:
缺点:
c. 学术论文及工程实践
TREX: Learning Execution Semantics from Micro-Traces for Binary Similarity,这篇论文投在IEEE 2022上,可以算是通过BERT解决BCSD问题的鼻祖了,之前大多数是通过使用卷积神经网络(GNN)训练CFG,结合提取基本块/函数级特征然后通过CNN/LSTM等网络来训练。作者使用相对先进的BERT模型(相比于CNN RNN等),采用unicorn框架对二进制代码进行模拟执行。然后对于执行路径的汇编代码和寄存器随机初始化的进行记录。然后对汇编代码和寄存器进行Mask了MLM任务训练。(BERT用作强化理解语义的一个任务) 然后对训练的模型对样本进行微调处理,最后用来预测未训练的函数的效果。总体来说基于BERT模型来实现汇编层面的语言理解,可以交好的解决由于编译影响因素不同而生成的不同二进制的检测鲁棒性。
另外最有工程化成果的就是腾讯科恩实验室的两篇论文:
基于Gemini论文上又进行优化,将基本块调用升级为邻接矩阵训练https://keenlab.tencent.com/zh/2019/12/10/Tencent-Keen-Security-Lab-Order-Matters/
codecmr 跨模态代码搜索检测, 基于上一篇论文的基础,实现的二进制代码到原代码的搜索。https://keenlab.tencent.com/zh/2020/11/03/neurips-2020-cameraready/
这应该是这个方向上唯一算是工程化了的成果。但是限制很多,腾讯的方案是通过ghidra(美国国安局开源的一款逆向工具)将汇编代码反编译为源码,然后将反编译出来的源码进行代码搜索。这就涉及了上文所说的反汇编工具好坏的问题了。二进制文件->汇编语言相对有唯一性,用什么工具反汇编结果都差不多。但是汇编语言->c伪代码这个中间的变数就很多了,当今暂时没有一款工具能完美还原这个问题的,所以这条路要实现精准漏洞匹配还有很长的路和技术问题需要解决。
【总结】:二进制漏洞补丁存下性检测技术,总体来说是技术难度极大,通过依靠传统检测方法无法很好的解决编译影响因素导致的检测鲁棒性,但随着AI技术的引入,特别是LLM大语言模型的涌现,模型对于二进制汇编代码语义理解能力的增强,对二进制代码克隆的检测能力在工业界工具中落地使用成为可能,我相信在不久的将来一定会有成熟的工具来实现已知漏洞补丁存下性检测。
原文作者:安全技术猿