长亭百川云 - 文章详情

科恩BinaryAI@ICSE2024论文解读|基于大模型的二进制软件成分分析

腾讯科恩实验室

287

2024-07-13

0

引言

随着开源软件在商业及个人项目中变得日益普及,开发团队越来越多地依赖外部组件库以加速开发进程,软件供应链的复杂性不断增加,同时也带来了潜在的安全风险。例如,XZ后门漏洞(CVE-2024-3094)导致了潜在的供应链攻击,它影响了Linux/Unix系统中用于处理.xz和.lzma文件的命令行压缩工具XZ Utils。这个漏洞允许攻击者在编译过程中植入恶意代码,进而可能破坏sshd认证并远程获取对整个系统的未授权访问。二进制软件成分分析(SCA)作为一项重要的软件工程实践,通过对软件构件进行审查,识别二进制中所包含的第三方代码库(Third-party Library, TPL)及其版本号,帮助确定许可证合规性问题和潜在的1-day安全漏洞。

在此背景下,腾讯安全科恩实验室基于在静态分析和AI安全领域的经验研发出二进制安全智能分析平台—BinaryAI(https://www.binaryai.cn/),其智能分析引擎可支持软件成分分析和恶意软件分析,对用户上传的二进制文件,BinaryAI可以在GitHub全量C/C++库范围中做相似性检索,以业界领先的识别准确率匹配到文件所使用的开源组件。

BinaryAI相关的学术论文《BinaryAI: Binary Software Composition Analysis via Intelligent Binary Source Code Matching》已被软件工程领域顶级学术会议 ICSE 2024录用,该项研究由腾讯安全科恩实验室和南方科技大学计算机科学与工程系张煜群教授团队联合完成。

文末阅读原文查收论文

**1
**

背景与现状

二进制SCA可识别的第三方库(TPL)数据集由大规模开源C/C++项目组成,其中大部分是来自GitHub代码库以及GNU/Linux社区的源代码包,通常现有的二进制SCA技术从大规模的TPL数据集中提取源代码特征以构建特征到对应第三方库的倒排索引并存储在SCA数据库中。随后,二进制SCA工具利用代码克隆检测等技术来识别TPL与二进制文件之间的相似代码特征,如果相似特征的比例超过预定义的阈值则将其识别为二进制所包含的开源组件。

二进制SCA中的关键步骤是二进制-源代码匹配,这一步骤将二进制代码映射到相应的源代码,进而实现二进制到源代码仓库的相似特征检测。B2SFinder,作为最先进的二进制SCA工具之一,选择了在编译前后仍保持一致的基本语法特征(例如,字符串常量)来匹配源代码和对应的开源第三方组件。除了二进制SCA之外,二进制-源代码匹配在软件安全的其他场景中也至关重要,例如逆向工程和恶意软件分析等。

现有二进制SCA利用基本语法特征进行二进制-源代码匹配,建立了二进制代码与TPL源代码之间的对应关系,但是由于C/C++语法特性(例如,函数内联)、编译器优化等因素,二进制代码和源代码之间通常存在巨大差异,因而二进制SCA工具的有效性通常受到影响。首先,这些基本特征在大规模TPL数据集中往往表现出显著的冗余性,降低了各自在数据集中的独特性和有效性,进而影响了SCA的识别精确度。此外,在部分情况下,目标二进制文件与第三方库之间几乎或完全没有共同的基本语法特征,特别是剥离了符号表信息的二进制文件(stripped binary),导致二进制SCA的召回率受到影响。

因此,在二进制SCA中采用细粒度的代码特征(例如,函数级特征)是至关重要的,这样可以通过处理高层次的语义信息以减轻基本特征带来的问题。考虑到编译过程中引入的二进制和源代码函数之间的显著差异,我们在BinaryAI中首次尝试利用海量有监督数据训练自回归大语言模型,将二进制和源代码特征映射到同一高维向量空间得到其函数向量(function embeddings),并相应地进行二进制到源代码函数的相似度计算和检索匹配,以增强二进制SCA第三方库的识别准确度。

2

BinaryAI技术解析

二进制安全智能分析平台BinaryAI基于大模型的二进制-源代码匹配进行二进制软件成分分析。图中展示的BinaryAI基本工作流程由四个阶段组成:特征提取、基于大模型的函数向量检索、链接时局部相关性驱动的函数匹配和第三方组件库检测

首先,BinaryAI分别从大规模TPL数据集中的代码库提取C/C++源代码函数,以及通过反编译从目标二进制文件中提取类C的伪代码函数(即,二进制函数)。相应地,BinaryAI采用自研的代码匹配模型BAI为源代码和二进制函数生成函数向量用于相似度计算。在BinaryAI中,二进制-源代码匹配过程被划分为两个单独的阶段进行。首先,代码匹配模型BAI架构基于自回归大语言模型,通过学习基于Token的函数语法特征,为每个二进制函数从数据库中检索到top-k相似的源代码函数。接下来,BinaryAI利用额外的结构化信息来捕获函数间的语义特征,进而从top-k个相似函数中准确匹配到对应的源代码函数。最终,BinaryAI通过计算目标二进制与第三方库之间匹配的源代码函数比例识别出二进制包含的第三方库。

2.1.特征提取

**源代码侧:**对于TPL数据集中的每个开源项目,我们收集所有版本中的C/C++源文件,通过tree-sitter内置的解析器构建文件的AST并提取所有的C/C++源代码函数并去重。与此同时,我们在SCA数据库中维护了两个倒排索引来存储提取的源函数到对应源文件和第三方库的映射关系。最终,我们从12K个开源项目中提取到了亿数量级独一无二的C/C++源代码函数。

**二进制侧:**我们利用Ghidra来实时反编译上传后的二进制文件,以生成二进制代码的类C伪代码表示作为二进制函数,用于后续BinaryAI的分析。此外,我们还利用Ghidra提取每个二进制函数的相对虚拟地址作为表示二进制文件中函数链接时局部相关性(link-time locality)的位置序号,以及二进制函数的调用图(function call graph)。

2.2**.基于大模型的函数向量检索**

BinaryAI的核心是基于函数向量执行函数级别的二进制-源代码匹配,即我们的首要目标是训练一个Embedding模型,该模型能够在单一向量空间中为二进制和源代码函数学习到有意义的向量表示,其中相似的二进制到源函数对在向量空间中保持接近,而不相似的函数向量则相距较远。

对于二进制-源代码匹配,二进制代码和源代码之间可能存在显著差异,然而典型的代码表示学习只匹配单一代码格式,即仅源代码到源代码或者二进制到二进制的代码匹配。现有的大语言模型在自然语言的语法学习方面极为有效,并且这种能力也扩展到了代码语言。尤其是一个在多种编程语言上训练的大模型能够跨不同代码格式识别相似的基于Token的语法特征,这有助于代码克隆检测,即使代码已经被翻译成不同的语言。为此,我们使用现有的大语言模型作为基础模型,并进一步使用标注好的二进制-源代码函数对作为语料库,采用有监督的对比学习方法进行预训练以构建BAI模型。

在BinaryAI中,我们采用Pythia套件中的模型作为基础模型来初始化BAI模型,然后进一步使用对比学习进行预训练。为了获得大量匹配的二进制源代码函数对作为训练模型的正样本,我们基于官方ArchLinux软件包和Arch用户仓库(AUR)构建了自动化的编译流水线。具体来说,我们使用makepkg命令自动编译所有的ArchLinux软件包。同时,我们通过编译器生成DWARF格式的调试信息。一方面,我们使用Ghidra反编译二进制文件以获得从虚拟地址到二进制函数的映射。另一方面,我们解析DWARF调试信息,并提取从虚拟地址到源文件及行号的映射关系。我们进一步利用tree-sitter来切分文件中相应的源函数。通过合并双方的映射,我们构建了包含10M二进制到源代码函数正样本对的训练语料,平均每个函数具有500个token。

作为对比学习中的关键要素之一,增加批内负样本(in-batch negatives)可以有效地帮助Embedding模型学习更具区分性的向量表示并提高下游SCA任务的性能。为此,我们使用Info NCELoss损失函数作为我们的对比训练目标,该函数最初设计用于对齐图像和文本标题的向量表示。图中展示了基于CLIP对比学习方法的训练过程,一个批次包含N个二进制到源代码的函数对,CLIP计算所有可能对之间的余弦相似度矩阵。训练目标是通过对称交叉熵损失对矩阵最大化N个正样本之间的相似度,同时最小化其余N*(N-1)个负样本之间的相似度。

我们在BinaryAI中部署了训练好的模型,首先离线地为SCA数据库中的所有源代码函数生成对应的函数向量,并存储到向量数据库。对于在线的二进制SCA,BinaryAI从目标二进制中提取二进制函数,并实时生成二进制函数向量作为查询,从向量数据库中检索给定二进制函数的top-k相似的源代码函数。

2.3**.接时局部相关性驱动的二****次精排**

理想情况下,我们可以直接选择相似度最高的源函数作为匹配结果。然而,由于不同版本间源函数的细微修改,大规模TPL数据集内存在大量相似函数。仅依靠语言模型生成的函数向量来捕捉基于Token的语法特征对于准确匹配源代码函数是不够的,因为检索到的top-k可能非常接近。为此,我们尝试利用链接时局部相关性和函数调用图作为表示结构化的语义特征,这可以帮助在二进制源代码匹配的第二阶段从top-k相似函数中进一步识别出正样本。

对于用于构建二进制文件的传统C/C++工具链,源代码文件最初由编译器编译成目标文件。随后,链接器解析目标文件之间的符号引用,并将它们组合成二进制文件。通过分析编译过程,我们可以得出几个基本发现。

1.同一源文件中的所有源函数被编译进单个目标文件,尽管它们相对于源文件的局部位置可能会发生改变。

2.目标文件被连续地链接进二进制文件,目标文件代码段内的所有函数(即,机器代码格式的二进制函数)保持它们的相对位置不变。

因此,我们可以进一步推导出,从同一源文件编译的二进制函数在二进制文件中是连续的。我们称之为链接时局部相关性。相应地,给定二进制文件的地址空间,我们可以通过切割包含连续二进制函数的区间来进行逆向,以恢复目标文件的边界(CodeCut问题),并进一步识别出编译进二进制文件的相对应源文件,从而准确匹配出这些文件中包含的源函数。

BinaryAI中链接时局部相关性驱动的函数匹配的具体算法流程如下,首先我们将检索到的top-k相似函数构建为索引文件到二进制源代码函数对的映射。对于每个源文件,我们根据链接时局部相关性驱动对函数对进行排序,并使用两个独立指针的滑动窗口来切片文件,以提取包含连续函数对的区间并映射回二进制文件的地址空间。与其他文件相比,我们发现编译进二进制文件的文件有着更长的函数连续区间。因此,我们将文件选择视为二进制文件地址空间内的区间覆盖问题并且采用贪心算法进行求解,这使我们能够优先选择能够覆盖更多函数对并且较长的函数区间。与此同时,我们进一步利用函数调用图来限定在所选文件内的二进制源函数匹配。最终,我们 将所选文件中所有剩余的函数对更新为二进制到源函数的匹配结果。

2.4**.**第三方组件库识别

BinaryAI 获取匹配的源函数后进一步对目标二进制文件运行第三方库检测,(即软件成分分析任务)。通过查询SCA数据库中包含的从源函数到第三方库的倒排索引,我们保留了每个匹配源函数的所有包含的TPL。一般情况下,由于源函数在不同TPL之间中被广泛复用,如果我们保留所有包含的TPL,这种内部的代码克隆可能导致不可避免的误报。为了缓解这个问题,我们基于TPL依赖关系过滤无效的第三方库,该依赖关系显示了TPL之间的复用关系,并且我们只保留被复用方的第三方库。具体来说,我们提前生成TPL依赖关系,作为软件成分分析的额外输入。对于SCA任务,BinaryAI首先从 SCA 数据库中提取每个匹配的源函数的所有包含的 TPL,然后根据 TPL 依赖关系做进一步过滤,同时计算所有保留的函数个数。最后,我们计算每个选定TPL的匹配函数与源函数总数的比率,表示为二进制文件和第三方库的相似性。如果比率超过预定义的阈值,BinaryAI会将其标识为二进制文件中包含的组件。同时,BinaryAI检测这些组件是否会引入安全威胁。

3

技术评估

我们从以下三个方面对BinaryAI的性能进行了全面评估:函数向量的有效性,二进制-源代码函数匹配准确度,二进制-源代码函数匹配准确度

3.1**.**函数向量的有效性

我们首先在基于向量的函数检索方面比较BinaryAI和CodeCMR。CodeCMR作为目前最先进的二进制源代码匹配模型,采用单独的函数编码器(源函数的 DPCNN 和二进制函数的 GNN)和Triplet Loss作为对比学习目标。在两个查询集中BinaryAI在MRR(平均倒数排名)方面都优于CodeCMR。通过结合两个查询集,BinaryAI的MRR达到了0.3407,与CodeCMR的0.1769,这表明BinaryAI检索到的正样本平均排名更高。此外,与CodeCMR相比,BinaryAI有效地将recall@1从10.75%提高到22.54%,recall@100从33.87%提高到56.60%。

我们进一步研究了基于模型的技术(BinaryAI,CodeCMR)与传统依赖基本特征的技术(BinPro,B2SFinder)之间的差异。我们发现传统技术在检索源代码函数方面的性能相当有限。具体来说,BinPro和B2SFinderMRR都小于0.005,top-100内召回的正样本少于10%,在top-1的召回率不到5%。接下来,我们调查原因后发现几个导致性能下降的因素。首先,数据集中许多源代码函数共享类似的基本特征,这使得有效区分它们变得具有挑战性。其次,作为查询的一些二进制函数缺乏有意义的基本特征,进一步影响了检索结果。

3.2**.**二进制-源代码函数匹配准确度

尽管BinaryAI 在从大规模数据中检索源代码函数方面相较于现有最先进技术展现出了显著的性能提升。然而,BinaryAI 在二进制-源代码匹配方面仍然存在局限性,尤其是在直接应用recall@1指标时(如表所示,在SCA测试集中的23,529次查询中达到了22.73%的召回率),这对于后续的二进制SCA任务而言是不够的。所以我们进而探究了链接时局部相关性驱动的函数匹配的准确性及其对二进制-源代码匹配的贡献。

表中展示了以top-10相似函数为输入的匹配结果。除了精确匹配的结果之外,我们还评估了模糊匹配的结果,因为这些结果适用于其他不依赖极高精确度的下游任务,例如逆向工程。总体来看,我们发现精确匹配的平均精确度达到了81.63%,所有二进制文件的精确度均超过了75%。此外,模糊匹配的平均精确度为95.86%,在所有二进制文件中均超过了90%。这些结果表明,基于链接时局部相关性和函数调用图的函数匹配具有高准确性,并且能够适用于SCA测试集中的所有二进制文件。

我们进一步评估了对二进制-源代码匹配的贡献。图中展示了基于向量检索的原始recall@1,不同top-k检索结果作为链接时局部相关性驱动匹配的输入并得到更新后的recall@1,以及相应的recall@k,recall@k表示了模型能力限制下的召回上限。总体而言,链接时局部相关性驱动的函数匹配显著提高了原始的recall@1,几乎达到了BinaryAI和CodeCMR的各自的性能上限。对于BinaryAI,链接时局部相关性驱动的匹配将recall@1从22.73%提高到54.70%,对应top-10的上限为57.35%,并进一步将recall@1提高到66.90%,对应top-100的上限为70.45%。

实验结果表明了链接时局部相关性驱动的函数匹配的贡献,以及BinaryAI中二进制-源代码匹配分两个阶段来识别语法和语义代码特征的有效性。

3.3**.二进制SCA性能**

最后,我们比较了BinaryAI与现有二进制SCA工具的性能。表中展示了150个二进制文件中人工标记的1,045个TPL组件检测的总体结果。BinaryAI第三方库检测的准确率85.84%以及召回率64.98%,显著优于其他SCA工具。

4

总结

二进制软件成分分析是降低第三方库(TPL)引入风险的重要手段,保障了软件供应链安全。传统依赖基本语法特征的SCA 技术在大规模TPL数据集表现出较高的误报率。腾讯安全科恩实验室自研二进制分析工具BinaryAI基于底座的二进制-源代码匹配模型BAI以及链接时局部相关性驱动的函数匹配实现相似源代码函数的高召回率,使得二进制SCA效果达行业高阶水准。

5

参考文献

1. Synopsys. 2023. Black Duck Binary Analysis (BDBA). https://www. synopsys.com/software-integrity/security-testing/software-compositionanalysis/binary-analysis.html.

2. Zimu Yuan, Muyue Feng, Feng Li, Gu Ban, Yang Xiao, Shiyang Wang, Qian Tang, He Su, Chendong Yu, Jiahuan Xu, et al. 2019. B2sfinder: detecting open-source software reuse in cots software. In 2019 34th IEEE/ACM International Conference on Automated Software Engineering (ASE). IEEE, 1038–1049.

3. Scantist. 2023. Scantist Binary Analysis. https://scantist.io

4. Ruian Duan, Ashish Bijlani, Meng Xu, Taesoo Kim, and Wenke Lee. 2017. Identifying open-source license violation and 1-day security risk at large scale. In Proceedings of the 2017 ACM SIGSAC Conference on computer and communications security. 2169–2185. 

5. Stella Biderman, Hailey Schoelkopf, Quentin Gregory Anthony, Herbie Bradley, Kyle O’Brien, Eric Hallahan, Mohammad Aflah Khan, Shivanshu Purohit, USVSN Sai Prashanth, Edward Raff, et al. 2023. Pythia: A suite for analyzing large language models across training and scaling. In International Conference on Machine Learning. PMLR, 2397–2430.

**6.**Wei Tang, Yanlin Wang, Hongyu Zhang, Shi Han, Ping Luo, and Dongmei Zhang. 2022. LibDB: An Effective and Efficient Framework for Detecting Third-Party Libraries in Binaries. In 2022 IEEE/ACM 19th International Conference on Mining Software Repositories (MSR). 423–434.

7. Zeping Yu, Wenxin Zheng, Jiaqi Wang, Qiyi Tang, Sen Nie, and Shi Wu. 2020. Codecmr: Cross-modal retrieval for function-level binary source code matching. Advances in Neural Information Processing Systems 33 (2020), 3872–3883.

8. Ling Jiang, Hengchen Yuan, Qiyi Tang, Sen Nie, Shi Wu, and Yuqun Zhang. 2023. Third-Party Library Dependency for Large-Scale SCA in the C/C++ Ecosystem: How Far Are We?. In Proceedings of the 32nd ACM SIGSOFT International Symposium on Software Testing and Analysis.

“关于ICSE”

ICSE全称International Conference on Software Engineering,是软件工程领域公认的旗舰学术会议,中国计算机学会推荐的A类国际学术会议,Core Conference Ranking A*类会议。ICSE 2024于2024年4月在葡萄牙里斯本举行。

点击“阅读原文”获取论文全文

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2