源代码与二进制文件 SCA 检测原理
【摘要】 SCA(Software Composition Analysis)软件成分分析,通俗的理解就是通过分析软件包含的一些信息和特征来实现对该软件的识别、管理、追踪的技术。本文探讨的是SCA具体的检测原理,源代码SCA检测和二进制SCA检测有哪些相同点和不同点,在进行安全审计、漏洞检测上各自又有什么样的优势和适用场景。
1、源代码与二进制的关系和特点
SCA(Software Composition Analysis)软件成分分析,通俗的理解就是通过分析软件包含的一些信息和特征来实现对该软件的识别、管理、追踪的技术。SCA具体的检测原理又是如何实现的,源代码和二进制文件的SCA检测又有哪些相同点和不同点,下面内容就来回答一下上述疑问。
对应编译类型的语言(C/C++/Go/Rust),都是遵循:源代码—>编译—>链接—>二进制文件的过程。影响二进制文件的因素包括不同的CPU架构(ARM、X86、PPC、MIPS…),不同的操作系统(Wndows、Linux、iOS、Android…),不同的编译优化选项(O0~O3),即使是同一套源代码,最终编译生成的二进制文件之间也是差别非常大的。注:上述影响因素不涉及java语言
从上面可知源代码和二进制文件之间存在巨大的差别,源代码是基于高阶语言来编写,是给人看的,人看了很方便理解其中语句的语义;而二进制是由流(指令流或字节流)来构成的,是给计算机“看”的,对人来说是非常不友好,不好理解。
源代码包含了变量符号类型、函数名称、类名称、代码逻辑结构等大量丰富的代码信息,相反为保留二进制文件的紧凑性,编译生成的二进制文件中会丢弃掉很多运行时用不到的信息,只保留程序正确运行必要的信息,比如被丢弃的信息有变量类型、变量名称等符号信息,可能被保留的有类名称、函数名称等信息,一定会保留的有常量字符串数据。另外为了保证程序的正确运行,还会有保留一个相应的配置信息,比如jar包中的manifest信息、POM信息、maven信息、资源文件等。基于这些特点源代码SCA和二进制SCA的检测原理也存在很大的不同。
2、源代码SCA检测原理
由于源代码中包含有丰富的程序信息,因此源代码的SCA检测既有大颗粒度的检测方法,也有细颗粒度的检测方法。
2.1 大颗粒度检测方法:根据源代码文件的相似度来判断属于什么组件和版本;文件相似度可以基于hash的严格匹配方法,也可以根据文本相似度匹配方法;这种匹配方法的优点是效率高,匹配速度极快,确定是也很明显,基于hash的容易漏报,基于文本相似度的准确率低;
2.2 细颗粒度检测方法:经过源代码—>词法分析—>Token提取—>语法分析—>AST抽象语法树—>语义分析过程来提取相应的数据,再通过机器学习、NLP、CFG调用图、DFG数据流图等等匹配算法进行代码相似度的检测,这种基于语义的代码相似度检测与基于文本相似度检测相比准确率高;
2.3 具备包管理机制的语言,比如Java、Go,可以通过引用的开源软件包信息来实现开源软件的关联分析,这种方法可以几乎可以100%准确的分析出引用的开源软件名称。
3、二进制SCA检测原理
3.1 虽然好多源代码中具有的信息在二进制文件中不存在,但是对于常量字符串、部分类名称、函数名称、以及一些配置信息还是存在的,并且这些信息具备一定的不变性,即受cpu架构、不同编译优化选项的影响很小,因此二进制SCA主要从二进制文件中提取这些方面的不同特征,再运用匹配算法进行相似度计算,并根据相似度门限来检测出引用的开源软件名称和版本号。
3.2 结合分析二进制代码中的CFG调用图、DFG数据流图等信息进行更加精准的检测,但由于这些分析需要对二进制文件进行指令反汇编,导致分析时间非常的长,分析效率低下,因此这种SCA检测方法不适合对大规模二进制文件进行扫描。
4、源代码SCA和二进制SCA功能对比
比较项 | 源代码SCA | 二进制SCA | 备注 |
---|---|---|---|
检测对象 | 源代码 | 二进制 | |
检测效率 | 高 | 高 | |
检测准确率 | 稍高 | 高 | 检测准确率和目标程序引用开源软件功能多少相关 |
嵌套组件检测能力 | 弱 | 强 | 二进制中不会遗漏所有引入的开源软件功能特征信息 |
检测语言种类 | 多 | 少 | 二进制SCA只支持能够编译出指令流或字节流二进制文件的语言 |
文件格式 | 简单 | 复杂 | 源代码都可看作文本格式,二进制文件存在pe、elf、coff、jar、apk… |
文件特点 | 一个开源软件包含N源码文件 | 一个二进制文件包含N个开源软件 | 一个开源软件由N>=1个源码文件;一个二进制文件包含N>=1个开源软件 |
检测阶段 | 开发阶段 | 测试阶段 | |
检测绕过 | 存在 | 不存在 | 源码在构建环境中引入或链接静态库引入的开源软件存在绕过源代码SCA检测 |
样本特征构建难度 | 低 | 高 | 需要编译构建出二进制 |
人工确认分析难度 | 低 | 高 | 源代码人工对比分析容易 |