【论文阅读】MOVERY:一种针对修改后开源软件组件的漏洞代码克隆精确发现方法

这篇文章质量很高,也是我非常欣赏的一个作者,他们之前发表了一个类似的方向的文章叫Vuddy,这次这个是上次工具的升级,主要是处理了代码演化上的检测问题。

在这里插入图片描述

摘要

第三方开源软件(OSS)组件继承的漏洞可能威胁整个软件系统的安全性。然而,由于开源软件在演化过程中会经历各类修改(具体表现为内部修改如OSS版本更新,以及外部修改如OSS复用过程中的代码变更),导致漏洞代码会以不同语法形式扩散传播,这使得追踪传播性漏洞代码极具挑战性。

本文提出MOVERY方法,该技术能够从修改后的OSS组件中精确发现漏洞代码克隆(VCC)。通过定位最原始的漏洞函数,并从安全补丁中提取核心漏洞代码行和补丁代码行,MOVERY构建的漏洞特征和补丁特征能有效应对OSS的各类修改。为提高可扩展性,MOVERY通过仅分析从其他OSS项目引入的代码,显著缩小目标软件的检测范围。最终,当函数同时满足漏洞特征匹配且与补丁特征存在差异性时,MOVERY将判定该函数为VCC。

我们在十个跨领域热门软件上的实验结果表明:91%的已发现VCC与其披露的漏洞函数存在语法差异。MOVERY的检测效能显著优于现有技术——其发现的415个VCC具有96%精确率和96%召回率,而两种最新VCC检测技术(均未充分考虑OSS内外修改)仅发现163和72个VCC,且最高精确率和召回率分别仅为77%和38%。数据表明,MOVERY的检测数量至少多出现有技术2.5倍,同时保持更高的检测精度。


1 引言

随着开源软件(OSS)数量的快速增长,开发者能够便捷地复用优质开源项目的功能模块[11, 12, 37]。然而,第三方OSS组件传播的漏洞可能威胁整个系统的安全性[14, 17, 48, 49]。*Heejo Lee为通讯作者。

从理论上讲,保持OSS组件处于最新版本是防范此类威胁的有效手段。然而,仓促的组件更新可能对系统产生负面影响(例如向后兼容性问题[40, 44]),这在开发者复用经过代码或结构修改的OSS项目时尤为显著[48]。因此,开发者通常选择回移植上游安全补丁[43]而非直接更新整个组件,以避免漏洞带来的潜在威胁。为实现这一目标,他们首先需要定位待修复组件中的漏洞代码[13, 43],例如借助漏洞代码克隆(VCC)检测技术(如[17, 49])以及识别目标程序中复用组件的软件成分分析(SCA)技术(如[9, 48])。

遗憾的是,从修改后的OSS组件中精确发现漏洞正变得日益困难,其核心挑战在于漏洞代码的语法多样性,这主要由以下两类OSS修改导致:

• OSS内部修改:OSS源码在版本更新过程中频繁变更。在此背景下,漏洞代码可能以不同形态存在于各OSS版本中,并会以多种语法形式传播至其他软件。

• OSS外部修改:由于OSS生态系统中源码常在复用过程中被修改的特性[48],漏洞代码可能在OSS复用阶段被改写。

这两类OSS修改共同导致传播漏洞代码的语法与公开披露的漏洞代码(如通过公共漏洞数据库[31])存在差异,从而严重影响了漏洞代码发现的准确性。据我们所知,现有技术均无法有效检测修改后OSS组件中存在的多种语法形态的漏洞代码。


现有技术局限性分析

当前漏洞代码克隆(VCC)检测技术(如[14,17,49])未考虑OSS内部修改,且对外部修改的检测方式存在局限,导致大量漏报现象。具体而言,这些技术仅能发现包含安全补丁中已删除代码行的VCC,而此类代码行在修改后的OSS组件中常被移除。相较之下,现有软件成分分析(SCA)工具(如[9,48])仅基于复用OSS版本判定漏洞存在性,当漏洞代码通过回移植修补或未被复用时易产生误报。此外,传统代码克隆检测技术(如[35,42])虽可用于VCC发现,但由于无法区分具有高相似度的漏洞代码与已修补代码[17,49],普遍存在误报风险。

MOVERY方法论
为突破上述技术瓶颈,本文提出MOVERY(MOdified Vulnerable code clone discovERY)——一种从修改后OSS组件中精确检测漏洞代码克隆的创新方法。

相较于现有VCC检测技术,MOVERY的核心创新在于生成可扩展的复合特征签名,其覆盖范围从最原始漏洞函数延伸至已披露漏洞函数。MOVERY工作流程包含两大阶段:(1) P1特征生成阶段 与 (2) P2漏洞检测阶段。

P1特征生成阶段 通过重构安全补丁中的漏洞函数与修补函数,生成漏洞特征与补丁特征。本阶段采用两项关键技术:
1. 函数校勘技术:除已披露漏洞函数外,MOVERY额外溯源最原始漏洞函数并进行跨版本比对。由于最原始漏洞函数与已披露漏洞函数间的差异可反映OSS更新过程中的漏洞代码演变,该方法可有效应对内部修改。
2. 核心代码行提取技术:仅保留核心漏洞代码行与补丁代码行构建特征签名。该策略使检测过程免受非核心代码变更干扰(详见第3.1节)。

P2漏洞检测阶段 基于生成特征在目标软件中发现VCC。本阶段实现两大优化:
• 可扩展性优化:集成SCA技术[48]的代码溯源能力,仅检测源自其他OSS的代码片段,显著缩小搜索空间。

• 精确性优化:采用选择性抽象技术应对OSS外部修改。当目标函数同时满足漏洞特征匹配且与补丁特征存在差异性时,MOVERY方将其判定为VCC(详见第3.2节)。

实验评估

实验结果表明,MOVERY在漏洞代码克隆(VCC)检测性能上显著优于ReDeBug [14]和VUDDY [17]等现有技术。为开展评估,本研究从美国国家漏洞数据库(NVD)[31]收集了4,219个通用漏洞披露(CVE)补丁,涵盖所有通过Git平台[19,47]发布的C/C++语言相关CVE补丁。

在跨领域选取的十款热门软件测试中,91%的已检测VCC与公开漏洞函数存在语法差异。MOVERY的VCC检出量至少超出现有技术2.5倍且准确率显著提升——由于ReDeBug与VUDDY未考虑OSS修改且无法有效处理VCC语法多样性,导致严重漏报。具体而言,MOVERY检测到415个VCC(精确率96%,召回率96%),而ReDeBug与VUDDY分别仅发现163和72个VCC(最高精确率77%,召回率38%)(详见第5.1节)。

进一步实验表明,在检测修改组件中的VCC时,MOVERY的准确性显著优于MVP [49](一种循环漏洞检测技术)与CENTRIS [48](一种SCA技术):未考虑OSS内部修改的MVP在十款目标软件中出现184例漏报(召回率54%),而基于CENTRIS的VCC检测方法因忽略回移植补丁导致272例误报(精确率51%)(详见第5.2与5.3节)。

就检测效率而言,MOVERY对十款不同规模目标软件(代码量范围:212,672至14,489,534行C/C++代码)的平均检测耗时控制在200秒以内。该耗时低于ReDeBug(298秒)与VUDDY(798秒),证明MOVERY具备实际应用所需的效率与可扩展性(详见第5.4节)。

技术贡献

本研究的主要贡献可概括为以下三方面:
• 首创精确检测方法:提出首个针对修改后OSS组件的VCC精确检测方法MOVERY。核心技术在于生成能够有效应对OSS内外修改的特征签名。

• 揭示内部修改影响:首次证实OSS内部修改(现有技术鲜少考虑)是导致VCC语法多样性的主导因素。

• 实现高效精准检测:尽管修改组件中91%的VCC语法与公开漏洞函数存在差异,MOVERY仍成功在跨领域十款目标软件中检测到415个VCC,且达到96%精确率与96%召回率。

以下是您提供的学术文本的专业翻译:


2 研究动机

本章明确MOVERY方法的目标问题,并通过典型案例阐明研究动机。

2.1 问题定义

MOVERY致力于发现修改后OSS组件中的传播性漏洞。假设某漏洞在OSS中引入后被修补,定义以下三个函数实体:

  • fd:通过公共漏洞数据库披露的漏洞函数
  • fp:已修补函数
  • fo:旧版OSS中包含的漏洞函数(其代码语法与fd存在差异,见图1)

无论漏洞传播形式如何,所有衍生漏洞函数均需被有效检测与修补。

技术挑战
核心挑战在于应对漏洞代码的语法多样性,其根源可归结为两类OSS修改行为:

  1. OSS内部修改:OSS版本更新导致漏洞函数语法变更(如C3、C4类漏洞)
  2. OSS外部修改:开发者在复用过程中对OSS组件实施定制化代码修改(如C2、C4类漏洞)

现有VCC检测技术(如[14,17,49])仅能覆盖C1及部分C2类漏洞,存在显著漏报问题。此类技术通常将安全补丁中删除的代码行定义为漏洞行,并要求目标函数完全包含这些漏洞行方可判定为VCC。然而,当OSS修改导致fd中定义的漏洞行在fo中不存在时,现有技术即失效。

2.2 典型案例分析

本节通过两个已修复的VCC实例,展示因OSS内外修改导致的语法多样性问题。所有案例均经开发团队确认并修补。

案例1:LibZip v1.3.0之前版本存在内存分配失败漏洞(CVE-2017-14107)。代码清单1展示了该漏洞的补丁片段。研究发现,PHP项目在2017年复用漏洞版LibZip时曾回移植此安全补丁(修补后函数见代码清单2)。

以下是对两个代码清单的技术翻译:


代码清单1:LibZip项目中CVE-2017-14107补丁片段
(代码差异对比格式,展示漏洞修复过程)

1 index 3bd593b1..9d3a4cbb 100644
2 ––– a/lib/zip_open.c
3 +++ b/lib/zip_open.c
4 @@ ... @@ _zip_read_eocd64 (...) {
5     zip_cdir_t *cd;
6     zip_uint64_t offset;
7     zip_uint8_t eocd[EOCD64LEN];
8     ...
9     zip_error_set(error, ZIP_ER_SEEK, EFBIG);
10    return NULL;
11 }
12 - if ((flags & ZIP_CHECKCONS) && offset+size != eocd_offset) {
13 + if (offset+size > buf_offset + eocd_offset) {
14 +    /* 目录记录跨越EOCD记录边界 */
15 +    zip_error_set(error, ZIP_ER_INCONS, 0);
16 +    return NULL;
17 + }
18 + if ((flags & ZIP_CHECKCONS) && offset+size != buf_offset + eocd_offset) {
19     zip_error_set(error, ZIP_ER_INCONS, 0);

代码清单2:PHP项目中修补后的_zip_read_eocd64函数
(【差异点】标注与LibZip原始补丁的语法差异,该函数与LibZip披露漏洞函数仅13%语法相似)

1 static struct zip_cdir * _zip_read_eocd64 (...) {
2     struct zip_cdir_t *cd;
3     zip_uint64_t offset;
4     const zip_uint8_t *cdp;  // 【差异点】新增指针变量
5     ...
6     _zip_error_set(error, ZIP_ER_SEEK, EFBIG);  // 【差异点】函数名前缀差异
7     return NULL;
8 }
9     if (offset+size > buf_offset + eocd_offset) {
10        /* 目录记录跨越EOCD记录边界 */
11        _zip_error_set(error, ZIP_ER_INCONS, 0);  // 【差异点】错误处理函数调用方式
12        return NULL;
13     }
14     if ((flags & ZIP_CHECKCONS) && offset+size != buf_offset + eocd_offset) {
15        _zip_error_set(error, ZIP_ER_INCONS, 0);


由于PHP复用了2013年发布的旧版LibZip并进行了代码修改,其漏洞函数的语法与CVE-2017-14107公开补丁中指定的形式存在差异。当将函数视为代码行集合时,通过计算PHP中漏洞函数与LibZip披露漏洞函数间的Jaccard相似度[46],测得两者相似度仅为13%。此外,由于语法差异问题,PHP开发团队无法直接应用该安全补丁。因此,他们选择对披露的安全补丁进行适应性修改并集成至代码库,而非将整个LibZip组件升级至安全版本(即v1.3.0及以上版本)。

此案例表明,针对与公开漏洞函数存在显著代码差异(本案例中达87%)的VCC进行检测具有必要性。MOVERY通过溯源最原始漏洞函数的语法特征,并在特征签名生成时仅采用核心代码行,能够有效检测此类高差异度VCC(具体技术细节详见第3节)。

技术局限性验证
然而,可扩展VCC检测技术VUDDY [17]由于仅考虑漏洞函数的有限变更,无法检测此类VCC。ReDeBug [14](一种通过分析补丁中相邻三行代码变更的VCC检测技术)同样失效——因其依赖补丁删除行附近的三行代码(即代码清单1第9-11行),而PHP中的漏洞函数对应代码行(代码清单2第6-8行)存在语法差异。

案例2
以Lua语言解释器v5.1至v5.2.2版本存在的缓冲区溢出漏洞(CVE-2014-5461)为例,该漏洞可导致攻击者实施拒绝服务攻击。代码清单3展示了Lua v5.2.3的补丁片段。研究发现,Redis项目在复用旧版Lua时进行了代码修改,并于2020年9月通过回移植方式应用了该补丁(见代码清单4)。

具体而言,Redis应用的补丁与Lua官方仓库存在差异。原因在于Redis复用的是Lua v5.1.5旧版本,其漏洞函数语法与公开披露版本不同。由于Lua旧版本中缺失代码清单3第12行等关键上下文,Redis开发团队无法直接应用原始补丁,最终选择参照Lua官方漏洞追踪系统建议的方案进行适配性修补。


在这里插入图片描述

以下是对该段技术文本的翻译及解析:


技术启示
本案例凸显了检测基于旧版本语法传播的VCC的必要性——此类VCC可能不包含安全补丁中已删除的代码行。MOVERY通过校勘最原始漏洞版本与已披露版本间的漏洞函数(详见第3节),成功实现此类检测。然而,当现有VCC检测技术[14,17,49]所定义的漏洞行(如本案例中代码清单3第12行)未包含在目标VCC中时,此类技术即告失效。反观现有软件成分分析(SCA)技术[9,48],尽管Redis开发团队已通过回移植修复漏洞,仍会因Redis复用Lua v5.1.5(含漏洞版本)而误判系统存在安全隐患。


3 MOVERY方法论

MOVERY方法包含两个核心阶段:(1) **特征生成阶段(P1)**与 (2) VCC检测阶段(P2)。P1阶段通过函数校勘与核心代码行提取技术生成可扩展特征签名,旨在应对漏洞代码的语法多样性问题。P2阶段为提升可扩展性,通过聚焦目标软件中源自其他OSS的代码片段来缩减检测范围,并基于双重判据实现精准检测:当且仅当目标函数满足漏洞特征匹配且与补丁特征存在显著差异时,方判定为VCC。图2展示了MOVERY的整体工作流程。

3.1 特征生成(P1)

给定三元组函数集合——最原始漏洞函数(fo)、已披露漏洞函数(fd)及修补后函数(fp),MOVERY将生成漏洞特征与补丁特征(漏洞函数与修补函数的获取方法详见第4.1节)。


以下是对该技术文本的专业翻译及解析:


3.1.1 特征生成原理
为有效应对漏洞代码克隆(VCC)的语法多样性问题,MOVERY的特征签名生成需满足以下三项核心原则:

(1)最小化原则
特征签名包含的代码行数与语法多样性处理能力呈负相关[49]。因此,MOVERY通过收集能够检测漏洞克隆的最少核心代码行构建特征签名。

(2)可扩展性原则
漏洞特征需具备版本扩展能力(即覆盖从最原始漏洞函数至已披露漏洞函数的语法变体),以应对OSS内部修改。

(3)可感知性原则
特征签名需能判定漏洞代码的上下文环境(如控制依赖关系)在传播过程中是否保持完整。


3.1.2 阶段流程
针对每个漏洞,MOVERY首先通过函数校勘技术分析fo与fd的共有代码行(实现可扩展性),随后从中提取两类核心代码行:
• 本质漏洞代码行(Essential Vulnerable Lines)

• 依赖漏洞代码行(Dependent Vulnerable Lines)(实现可感知性)

通过聚合上述核心代码行(遵循最小化原则),MOVERY生成漏洞特征。补丁特征的生成流程类似:分析fp后提取本质补丁代码行与依赖补丁代码行,最终合成补丁特征。


3.1.3 函数校勘技术
与现有VCC检测技术[14,17,49]仅关注fd不同,MOVERY通过分析(fo, fd)函数对生成可扩展漏洞特征,以应对OSS内部修改引发的语法多样性。由于fo与fd包含相同漏洞,我们推断同时存在于两者且被安全补丁删除的代码行(详见第6节)对漏洞表现具有关键作用。


3.1.4 本质漏洞/补丁行提取
为应对OSS外部修改导致的语法差异,MOVERY在特征生成时仅保留核心代码行。具体定义如下:

▶ 定义I:本质漏洞行与补丁行
• 本质漏洞行(EV):在安全补丁中被删除,且同时存在于fo与fd的代码行

• 本质补丁行(EP):在安全补丁中被添加,且不存在于fo与fd的代码行

数学形式化定义(设l为源代码行):

EV = { l | l ∈ (fd \ fp) ∧ l ∈ (fo ∩ fd) ∧ l ∉ fp }
EP = { l | l ∈ (fp \ fd) ∧ l ∉ (fo ∪ fd) ∧ l ∈ fp }

3.1.5 依赖漏洞/补丁行提取
技术背景:传播性本质漏洞行并不能完全确保漏洞行为在目标环境中依然有效。为此,MOVERY进一步分析依赖代码行——即与本质漏洞/补丁行存在控制流或数据流依赖关系的代码行,这些依赖关系对漏洞表现具有决定性影响[3,49]。

▶ 定义II:依赖漏洞行与补丁行
• 依赖漏洞行(DV):与本质漏洞行存在控制或数据依赖关系,且同时存在于fo与fd的代码行

• 依赖补丁行(DP):与本质补丁行存在依赖关系,且包含于fp的代码行


案例验证(以CVE-2016-8654为例)
该漏洞为Jasper图像库中发现的堆缓冲区溢出漏洞。代码清单5展示Jasper v1.900.31的补丁片段,代码清单6呈现Jasper v1.900.1最原始漏洞函数。在补丁删除的代码行(代码清单5第10-12行)中:
• 第10行存在于最原始漏洞函数,故属于EV

• 第13-15行(补丁新增行)不属于fo或fd,故归入EP



代码清单5:CVE-2016-8654补丁片段(Jasper v1.900.31版本)

1 // Jasper_1.900.31/src/libjasper/jpc/jpc_qmfb.c
2 void jpc_qmfb_split_col (...) {
3     ...
4     if (bufsize > QMFB_SPLITBUFSIZE) {
5         if (!(buf = jas_alloc2(bufsize, sizeof(jpc_fix_t)))) {  // 【差异点】内存分配函数变更
6             abort();
7         }
8     }
9     if (numrows >= 2) {
10 -    hstartcol = (numrows + 1 - parity) » 1;  // 【差异点】变量名变更(hstartcol → hstartrow)
11 -    // 原始(错误)代码:m = (parity) ? hstartcol : (numrows - hstartcol);
12 -    m = numrows - hstartcol;
13 +    hstartrow = (numrows + 1 - parity) » 1;
14 +    // 修复代码:m = (parity) ? hstartrow : (numrows - hstartrow);
15 +    m = numrows - hstartrow;
16     n = m;
17     dstptr = buf;
18     srcptr = &a[(1 - parity) * stride];

代码清单6:CVE-2016-8654最原始漏洞函数片段(Jasper v1.900.1版本)

1 // Jasper_1.900.1/src/libjasper/jpc/jpc_qmfb.c
2 void jpc_qmfb_split_col (...) {
3     ...
4     if (bufsize > QMFB_SPLITBUFSIZE) {
5         if (!(buf = jas_alloc(bufsize * sizeof(jpc_fix_t)))) {  // 【差异点】单参数分配函数
6             abort();
7         }
8     }
9     if (numrows >= 2) {
10     hstartcol = (numrows + 1 - parity) » 1;  // 【差异点】与补丁变量名不同
11     m = (parity) ? hstartcol : (numrows - hstartcol);  // 【漏洞点】错误条件判断逻辑
12     n = m;
13     dstptr = buf;
14     srcptr = &a[(1 - parity) * stride];

技术差异分析:

  1. 函数接口变更
    • 行5:jas_alloc()(单参数)→ jas_alloc2()(双参数)内存分配函数接口升级

  2. 变量语义重构
    • 行10:变量名从hstartcol(列起始)变更为hstartrow(行起始),反映计算维度修正

  3. 逻辑优化
    • 行12/15:删除冗余三元运算符,直接计算m = numrows - hstartrow提升代码健壮性

  4. 漏洞模式
    • 行11:原始错误条件判断导致整数溢出漏洞(CVE-2016-8654根本原因)

以下是对该技术文本的翻译及解析:


3.1.6 控制流代码行提取

数学形式化定义
设x 7→c y表示代码行x与y间的控制流依赖,x 7→d y表示数据流依赖,则依赖漏洞行(DV)与依赖补丁行(DP)可形式化定义为:

D<sub>V</sub> = { l | l ∈ (f<sub>o</sub> ∩ f<sub>d</sub>) ∧ (l 7→<sub>c</sub> l<sub>V</sub> ∨ l 7→<sub>d</sub> l<sub>V</sub>) }  
D<sub>P</sub> = { l | l ∈ f<sub>p</sub> ∧ (l 7→<sub>c</sub> l<sub>P</sub> ∨ l 7→<sub>d</sub> l<sub>P</sub>) }  

其中lV ∈ EV,lP ∈ EP。以CVE-2016-8654为例:
• 控制流依赖:代码清单5和6第9行(条件语句if(numrows >= 2)

• 数据流依赖:代码清单5第18行/代码清单6第14行(指针操作srcptr = &a[...]


3.1.7 漏洞控制流代码行提取

▶ 定义III:漏洞控制流代码行
漏洞控制流代码行(FV)定义为:从漏洞函数入口到本质漏洞代码行路径上的条件语句集合。

技术必要性:
漏洞函数控制流变更可能导致漏洞触发环境失效,进而引发误报。MOVERY通过提取关键控制流代码行(FV)增强环境感知能力。

CVE-2016-8654案例:
在代码清单5和6中,存在三条通向本质漏洞行(第10行)的条件语句:

  1. 第4行:if(bufsize > QMFB_SPLITBUFSIZE)
  2. 第5行:if(!(buf = jas_alloc(...)))
  3. 第9行:if(numrows >= 2)

经函数校勘后,MOVERY提取共有的第4行与第9行作为FV,排除版本差异导致的第5行(内存分配检查)。

在这里插入图片描述

在这里插入图片描述


3.1.8 特征签名合成
最终,MOVERY通过聚合以下要素生成特征签名:

漏洞特征 SV = (EV, DV, FV)
补丁特征 SP = (EP, DP)

关键优化策略:

  1. 文本预处理:对特征代码行进行规范化处理(Normalization)与抽象化处理(Abstraction),消除不影响语义的语法变更(如空格、变量重命名)
  2. 冗余过滤:补丁特征中新增的控制流代码行已包含在EP,故无需重复纳入DP

以下是对该技术文本的翻译及解析:


3.1.9 特征预处理机制


预处理技术实现
MOVERY采用双重预处理策略生成鲁棒性特征签名:

  1. 规范化处理(Normalization)
    • 删除函数中所有空格与注释

• 统一转换为全小写字符格式

  1. 抽象化处理(Abstraction)
    • 参数/变量名 → PARAM

• 变量类型 → DTYPE

• 被调用函数 → FCALL

• 数据变量 → DNAME


处理流程

  1. 特征元素识别:从三元组函数(fo, fd, fp)中提取EV/DV/FV等要素

  2. 双重预处理:
    • 首轮仅应用规范化处理,生成norm特征

    • 次轮联合应用抽象化+规范化,生成abst特征

  3. 特征存储策略:
    • 同时保留两种预处理形式,缓解单一抽象方法导致的误报(详见3.2节)

    • 自动过滤字符数<15的代码行,避免通用短代码干扰(详见第6节讨论)


3.2 漏洞代码克隆检测(P2阶段)

给定目标软件 ( T ) ( T ) (T)、漏洞特征 ( S v ) ( S_v ) (Sv)、补丁特征 ( S p ) ( S_p ) (Sp)及漏洞函数集合 ( { f o , f d } ) (\{f_o, f_d\}) ({fo,fd}) ,MOVERY通过以下技术实现高效精准的VCC检测:


3.2.1 阶段流程概览

MOVERY采用双重优化策略:

  1. 搜索空间缩减:仅聚焦于复用OSS代码区域
  2. 选择性抽象匹配:动态选择特征匹配粒度

检测判据:目标函数被判定为VCC需同时满足:

  • (1) 包含 ( S v ) ( S_v ) (Sv)特征
  • (2) 不包含 ( S p ) ( S_p ) (Sp)特征
  • (3) 语法与 ( f o / f d ) ( f_o/f_d ) (fo/fd)相似 :语法与补丁对应的漏洞函数相似或者最原始的漏洞函数相似

3.2.2 搜索空间缩减技术

技术原理
基于先进软件成分分析(SCA)技术[48],将目标软件( T )的代码库划分为:

  • 复用代码区:来自第三方OSS的代码片段
  • 应用代码区:软件独有功能代码

MOVERY仅检测复用代码区,通过以下流程定位该区域:

  1. 函数路径提取:提取( T )和原始漏洞组件( C )的所有函数及其文件路径(如./src/file.c
  2. 公共函数比对
    • 存在公共函数:收集( T )中所有公共函数的目录路径,标记为复用代码区
    • 无公共函数:判定( T )未复用( C ),跳过检测

技术优势

  • 避免全代码库扫描,提升检测效率(详见5.5节实验验证)
  • 自动过滤无关OSS漏洞,增强可扩展性

3.2.3 选择性抽象匹配技术

技术挑战
现有技术(如VUDDY[17])的全量抽象策略可能导致误判。例如当补丁仅修改变量名时(见代码清单5),抽象后的漏洞函数与补丁函数将无法区分。

MOVERY解决方案

  1. 双重预处理:对( f_d )和( f_p )分别进行规范化与抽象化处理
  2. 动态匹配策略
    • 抽象特征差异:当( f_d )与( f_p )的抽象形式不同时,使用签名中的abst字段匹配
    • 抽象特征相同:仅使用norm字段匹配,规避抽象失效场景

案例说明(参考代码清单7):

  • 若补丁仅修改hstartcolhstartrow(变量名变更),抽象后均为DVAL,此时启用规范化匹配
  • 若补丁修改控制逻辑(如操作符变更),抽象形式不同,启用抽象化匹配


代码清单7:CVE-2016-8654漏洞特征签名示例

Sv = (
    Ev = [{ 
        "norm": "hstartcol=(numrows+1-parity)>>1;",
        "abst": "DVAL=(PARAM+1-PARAM)>>1;" 
    }],
    Dv = [{ 
        "norm": "if(numrows>=2){", 
        "abst": "if(PARAM>=2){" 
      },{
        "norm": "srcptr=&a[(1-parity)*stride];",
        "abst": "DVAL=&PARAM[(1-PARAM)*PARAM];" 
      },...],
    Fv = [{ 
        "norm": "if(bufsize>QMFB_SPLITBUFSIZE){",
        "abst": "if(DVAL>QMFB_SPLITBUFSIZE){" 
      },...]
)

预处理定义

  • 规范化(Normalization)
    删除函数中所有空格与注释,并将函数内所有字符转换为小写形式。
  • 抽象化(Abstraction)
    将函数中出现的参数、变量名、变量类型及被调用函数名分别替换为符号 PARAMDNAMEDTYPEFCALL

签名生成流程

  1. 代码行识别:MOVERY首先确定需存入签名的所有代码行。
  2. 规范化处理:对给定三元组函数(即 f_of_df_p)应用规范化,并将处理后的代码行存入签名的 "norm" 字段。
  3. 联合处理:对三元组函数同时应用抽象化与规范化,结果存入签名的 "abst" 字段。

双重存储目的
同时保留规范化与抽象化形式,旨在最小化因简单抽象方法导致的误报(详见第3.2节)。

过滤规则
若规范化代码行字符数小于15,MOVERY将跳过该行,以避免通用短代码引发的误报(该决策分析详见第6节)。


漏洞代码克隆检测流程

MOVERY最终通过对比漏洞特征( S_v )与补丁特征( S_p ),在目标软件的复用代码区域中识别漏洞代码克隆(VCC)。


▶ 定义IV:漏洞代码克隆
若目标软件( T )中的函数( f )满足以下条件,则判定为VCC:

  • 条件1:( f )包含( S_v )中所有代码行
    ( ∀ l ∈ S v .   ( l ∈ f ) ) ( \forall l \in S_v.\ (l \in f) ) (lSv. (lf))
  • 条件2:( f )不包含( S_p )中任何代码行
    ( ∀ l ∈ S p .   ( l ∉ f ) ) ( \forall l \in S_p.\ (l \notin f)) (lSp. (l/f))
  • 条件3:( f )的语法与( f_o )或( f_d )相似
    ( Sim ( f , f o ) ≥ θ   ∨  Sim ( f , f d ) ≥ θ ) ( \text{Sim}(f, f_o) \geq \theta \ \lor \ \text{Sim}(f, f_d) \geq \theta ) (Sim(f,fo)θ  Sim(f,fd)θ)

检测实现细节

  1. 候选函数筛选
    当函数( f )满足条件1和条件2时,MOVERY将其标记为VCC候选。

  2. 误报过滤机制
    为避免签名代码行过少或过于通用导致的误报,引入条件3:

    • 将( f )与漏洞函数 ( f o / f d ) ( f_o/f_d ) (fo/fd)拆分为代码行集合
    • 计算Jaccard相似度[46]:
      ( ∣ f ∩ f d ∣ ∣ f ∪ f d ∣ ) ( \frac{|f \cap f_d|}{|f \cup f_d|} ) (ffdffd) ( ∣ f ∩ f o ∣ ∣ f ∪ f o ∣ ) ( \frac{|f \cap f_o|}{|f \cup f_o|} ) (ffoffo)
    • 设置低阈值 ( θ ) ( \theta ) (θ)(如0.5)以兼容OSS外部修改

特殊场景处理策略

为覆盖更多漏洞类型,MOVERY采用条件组合检测:

场景条件组合技术应对
1. 补丁无新增代码仅用( S_v )(条件1+3)忽略( S_p )检测
2. 补丁无删除代码仅用( S_p )(条件2+3)忽略( S_v )检测
3. 无原始漏洞版本仅用( f_d )生成签名及条件3跳过内部修改分析
4. 代码行顺序变更条件1+3 + 代码行顺序验证记录漏洞函数代码顺序

实验验证:上述四类非主导场景(占比<30%)下,MOVERY仍能保持高检测精度。



4 MOVERY系统实现

本章介绍MOVERY的具体实现方案,包括漏洞数据集构建方法与系统架构设计。


4.1 漏洞数据集构建

安全补丁采集
我们采用既有研究方法[19,32],通过美国国家漏洞数据库(NVD)筛选包含Git提交链接(即安全补丁提交记录)的CVE条目,并爬取对应Git仓库中的补丁提交。选择C/C++语言漏洞作为初始目标,因为C/C++软件中普遍存在代码片段复用与修改后OSS复用现象[17,47-49]。截至2021年3月,共收集4,219个C/C++安全补丁。

函数重构方法
从安全补丁中重建漏洞函数( f_d )与修补函数( f_p ):

  1. 解析补丁头信息获取漏洞文件与修补文件的提交ID(如代码清单3中aafa3dca2表示漏洞文件,d02e11328表示修补文件)
  2. 从漏洞文件中提取包含补丁删除行的函数作为( f_d )
  3. 从修补文件中提取包含补丁新增行的函数作为( f_p )
  4. 排除非漏洞修复性变更(如注释/空格修改)的( (f_d,f_p) )对

最旧漏洞函数( f_o )重建

  1. 根据NVD提供的通用平台枚举(CPE)[30]定位漏洞起源的最旧软件版本
  2. 手动验证CPE准确性:从CPE标注的最旧版本开始顺序检测,首个包含与( f_d )同名函数的版本被确定为最旧漏洞版本
  3. 处理并行版本分支(如OpenSSL 1.0.0与1.0.1):依据版本发布日期推断时序关系
  4. 从最旧版本中提取满足以下条件的( f_o ):
    • 函数名与( f_d )一致
    • 存在于漏洞文件路径中
    • 语法与( f_d )存在差异

最终重构7,762组( (f_d,f_p) )对与5,936个最旧漏洞函数(数据统计见表2)。


数据集观测分析

OSS内部修改对漏洞代码语法多样性具有主导影响:

  • 在5,936个存在多版本漏洞函数中,78%(4,623例)的( f_d )与( f_o )存在语法差异
  • ( f_d )与( f_o )的Jaccard相似度平均值仅为56%
  • 上述事实表明:44%的漏洞代码语法变更由OSS内部更新引起,验证了VCC检测中考虑内部修改的必要性

4.2 系统架构

MOVERY由以下三大核心模块构成:

  1. 数据集采集器:负责收集安全补丁并重构漏洞函数与修补函数
  2. 特征生成器:为每个漏洞生成漏洞特征与补丁特征
  3. VCC检测器:在目标软件中执行实际漏洞代码克隆检测

各模块采用800-1,000行Python代码实现(不含函数解析器等外部依赖)。MOVERY源代码已开源:
https://github.com/wooseunghoon/MOVERY-public


函数解析与分析工具

  • 函数提取:采用高精度开源工具Universal Ctags[6]从漏洞文件、修补文件及目标软件中提取函数
  • 依赖分析:使用Joern解析器[50]分析函数的控制流与数据流依赖关系,用于特征生成
    • 生成代码属性图(整合抽象语法树、控制流图与程序依赖图)
    • 通过图结构获取:
      (1) 函数的完整控制流路径
      (2) 代码行间依赖关系

5 实验评估

本章从多维度评估MOVERY性能:

  • 5.1节:对比现有VCC检测技术(VUDDY[17]、ReDeBug[14]),验证MOVERY在修改组件中的检测精度
  • 5.2-5.3节:分别对比循环漏洞检测技术MVP[49]与SCA技术CENTRIS[48]
  • 5.4节:评估MOVERY检测速度与可扩展性
  • 5.5节:分析搜索空间缩减机制的实际效能
  • 5.6节:典型检测案例研究

实验环境

  • 操作系统:Ubuntu 16.04 LTS
  • 处理器:Intel Xeon @ 2.40GHz
  • 内存:32GB DDR4
  • 存储:6TB HDD


5.1 MOVERY检测精度评估

目标软件选择标准

为验证MOVERY的泛化能力,目标软件需满足:

  1. 热门性:属于热门的C/C++开源软件
  2. 组件修改性:包含足够数量的修改后OSS组件
  3. 领域多样性:避免特定领域偏差

筛选流程

  1. 从GitHub收集星标数(stargazer counts)>1,000的C/C++仓库(星标数作为流行度指标)
  2. 使用CENTRIS[48]根据修改组件数量对仓库排序
  3. 从高到低筛选至少被MOVERY检测到1个VCC的软件

目标软件数据集

表3汇总了最终选定的10款目标软件,其特点包括:

  • 领域覆盖:跨领域选取(网络服务、数据库、嵌入式系统等)
  • 代码规模:C/C++代码量跨度大(212,672 - 14,489,534行)
  • 数据代表性:累计代码量达VUDDY[17]数据集的80倍,与MVP[49]数据集规模相当

实验方法论

对比基准

  • ReDeBug[14](基于补丁行上下文的VCC检测)
  • VUDDY[17](基于函数哈希的克隆检测)

实验配置

  • 对10款目标软件同时应用MOVERY、ReDeBug与VUDDY
  • 基准工具采用默认参数配置(参照原始论文[14,17])
  • MOVERY相似度阈值θ设为0.5(本节末尾含阈值敏感性分析)

评估指标

  1. 真阳性(TP):正确检测的VCC数量
  2. 假阳性(FP):误报的VCC数量
  3. 假阴性(FN):漏报的VCC数量
  4. 精确率(Precision):( \text{Precision} = \frac{#TP}{#TP + #FP} )
  5. 召回率(Recall):( \text{Recall} = \frac{#TP}{#TP + #FN} )

FN测量约束
由于无法穷尽检测目标软件中所有漏洞,仅测量无可争议的FN(例如:被VUDDY/ReDeBug检出但MOVERY漏报的VCC[17,49])

人工验证流程
由两名安全分析师对检测结果进行人工审核,通过以下步骤判定结果有效性:

  1. 审查VCC代码上下文
  2. 验证漏洞触发环境是否完整
  3. 交叉核对补丁修复有效性

代码清单8:FreeType2中CVE-2014-9669补丁片段

1 tt_cmap12_validate (...) {
2     num_groups = TT_NEXT_ULONG( p );
3     if ( length > (FT_ULong)( valid->limit - table ) ||
4 -        length < 16 + 12 * num_groups )
5 +        /* length < 16 + 12 * num_groups ? */
6 +        length < 16 ||
7 +        ( length - 16 ) / 12 < num_groups )

代码清单9:CVE-2014-9669最原始漏洞函数片段(FreeType2 v2.1.10)

1 // 提取自FreeType2 v2.1.10("./src/sfnt/ttcmap.c")
2 tt_cmap12_validate (...) {
3     ...
4     num_groups = TT_NEXT_ULONG( p );
5     if ( table + length > valid->limit || length < 16 + 12 * num_groups )  // 【差异点】条件表达式结构不同

检测精度总览

表4汇总了MOVERY、VUDDY与ReDeBug的VCC检测结果。实验中共发现434个VCC(来自121个CVE漏洞),其中ReactOS项目因包含大量漏洞函数导致检出数最多。

关键发现

  • 高语法差异场景:91%的VCC(396个)与公开漏洞函数存在语法差异
  • MOVERY优势:检出415个VCC(精确率96%,召回率96%)
  • 基准工具对比
    • ReDeBug检出163个(精确率65%,召回率38%)
    • VUDDY检出72个(精确率77%,召回率17%)

覆盖性分析

  • MOVERY覆盖了VUDDY检出的所有VCC(100%),以及ReDeBug检出的88%(144个)
  • VUDDY与ReDeBug仅分别覆盖MOVERY检出量的17%(72个)与35%(144个)

现有技术漏报(FN)分析

  1. ReDeBug漏报

    • 62.4%漏报率(271个)
    • 失效场景
      • 安全补丁中删除的代码行在目标函数中不存在
      • 代码语法超出ReDeBug处理能力(如多行逻辑重构)
  2. VUDDY漏报

    • 83.4%漏报率(362个)
    • 失效场景
      • 代码修改类型超出其检测范围(如Type-3语义克隆)
      • 内部OSS修改导致签名失效(见CVE-2014-9669案例)

典型案例(CVE-2014-9669)

  • 漏洞类型:FreeType2整数溢出漏洞
  • 技术失效原因
    • ReDeBug/VUDDY依赖的漏洞行(代码清单8第4行)在原始漏洞函数中因内部修改呈现不同语法(代码清单9第5行)
    • 导致基准工具无法检测,MOVERY通过溯源最旧版本成功捕获

ReDeBug与VUDDY的误报(FP)分析

ReDeBug误报根源

  1. 缺乏代码规范化:未对非安全变更(如注释修改)进行标准化处理,误判未修改代码为漏洞
  2. 忽略函数语义:当补丁新增代码行与补丁前代码行部分相同时,误将已修补函数标记为漏洞[17,49]

VUDDY误报根源

  • 抽象化局限性:若补丁仅修复VUDDY的抽象目标(如变量重命名),抽象后漏洞函数与补丁函数无法区分,导致误报

MOVERY检测精度详析

表5总结了MOVERY可检测但现有技术难以发现的VCC类型:

类型定义占比技术突破
T1与最旧漏洞函数( f_o )语法高度相似8%(32个)函数校勘技术溯源原始漏洞
T2与( f_o )的代码相似度高于( f_d )56%(221个)兼容内部版本演化差异
T3与( f_d )相似度<50%166个(T2子集)外部修改鲁棒性检测

关键优势

  • 选择性抽象优化:消除VUDDY报告的22个误报中的21个(95.5%)
  • 跨类型检测能力:检出34个ReDeBug无法发现的Type-2[34]类VCC

MOVERY误报场景

  1. 抽象化失效
    • 案例:代码清单10中第5-6行经抽象化后均转换为FCALL(PARAM);,即使应用补丁仍误判为漏洞
    // Listing 10示例
    5 original_function(param);  // 抽象后 → FCALL(PARAM);
    6 patched_function(param);   // 抽象后 → FCALL(PARAM);
    
  2. 语法相似函数干扰
    • 场景:补丁( p )与( p’ )分别应用于语法相似函数( f )与( f’ ),MOVERY误判( p’ )未应用于( f )(反之亦然)
    • 概率:实验中出现概率极低(<0.5%)


MOVERY漏报(FN)场景

MOVERY在以下两种场景中报告漏报:

  1. 语义相似但语法变更的代码(例如for循环改为while循环)
  2. VCC与漏洞函数的相似度低于阈值θ

尽管降低θ值可增加检出量,但会引入更多误报。实验表明当前θ=0.5的设置实现了精确率与召回率的最佳平衡,MOVERY性能显著优于现有技术。


阈值敏感性分析

在VCC检测实验中,默认阈值θ设为0.5。为评估参数敏感性,以0.1为步长在[0,1]区间调整θ并测量指标变化:

评估方法

  • 数据基础:基于已检出的434个VCC(因新检出VCC人工验证成本过高)
  • 评估指标
    • 精确率(Precision)召回率(Recall)
    • F1分数[45]:
      F 1 = 2 × Precision × Recall Precision + Recall F1 = \frac{2 \times \text{Precision} \times \text{Recall}}{\text{Precision} + \text{Recall}} F1=Precision+Recall2×Precision×Recall

实验结果(图3)

  • 最优平衡点:θ=0.5时F1分数最高
  • 项目差异
    • Crown与Emscripten项目在θ>0.5时F1更高(因其VCC修改比例低,高θ减少误报)
  • 全局趋势
    • θ<0.5时精确率下降
    • θ>0.6时召回率显著降低

边界案例

  • 低θ扩展性:θ<0.5时MOVERY额外检出15个VCC(原始实验未覆盖)
  • 残余误差
    • θ=0时仍存在4个漏报
    • θ=1时仍存在3个误报
      (详见第6节讨论)

5.2 与MVP的对比

我们进一步将MOVERY与MVP[49](一种循环漏洞检测技术)进行对比,以验证MOVERY在检测修改组件中VCC的优越性。由于MVP未开源,我们基于其论文[49]复现了该工具并采用默认配置。

实验结果分析
MVP在10款目标软件中共发现220个VCC(真阳性,TP),但报告了46个误报(FP)和184个漏报(FN)(详见表6)。关键发现如下:

  1. 检测局限性

    • MVP未考虑OSS内部修改,导致其几乎无法检测T1与T2类VCC(见表5)
    • T1类漏报(32个):漏洞函数未包含安全补丁删除的代码行
    • T2类漏报(142个):漏洞函数因内部修改(如变量类型/调用函数名变更)导致语法差异
  2. 误报根源

    • 语法相似性误判(11个FP):安全函数与漏洞函数语法相似但语义不同
    • 抽象化失效(35个FP):补丁仅修复MVP的抽象目标(如变量名)导致无法区分漏洞与修补函数
    • MOVERY通过选择性抽象消除了35个误报中的31个
  3. MOVERY漏报

    • MVP检出8个MOVERY未发现的VCC,均与公开漏洞函数语法相似度低于θ
    • 其中2个VCC未被VUDDY和ReDeBug检出

结论:MVP因未考虑OSS内部修改,漏报量(184个)显著高于MOVERY,验证了MOVERY在修改组件检测中的高效性。

有效性威胁

  • MVP复现可能存在细节偏差,且其设计初衷为检测循环漏洞而非传播性漏洞
  • 本研究旨在证明MOVERY在修改组件检测中的优势,而非否定MVP的总体有效性

5.3 与CENTRIS的对比

现有方法(如商业工具Trivy[1]、Black Duck[38])及SCA技术CENTRIS[48]试图通过识别复用OSS组件及其版本来发现漏洞,但未考虑修改后组件的复用问题。我们基于CENTRIS的组件识别能力,利用CVE Details[7]的"产品搜索"和"版本搜索"功能关联漏洞,模拟其VCC检测流程。

实验结果分析
CENTRIS方法在10款目标软件中报告553个VCC,其中:

  • 误报率高达49%(272个FP)

    1. 漏洞代码未被实际复用
    2. 漏洞已通过回移植修补(案例见第2.2节)
  • 漏报率38%(152个FN)

    1. CENTRIS未能识别含漏洞的组件
    2. 版本信息预测错误
  • MOVERY未覆盖的37个VCC
    均因补丁未通过Git发布导致,若补丁加入数据集,MOVERY亦可检出

结论:仅基于组件名称和版本的漏洞检测方法因忽略OSS修改产生大量误报,MOVERY在修改组件的漏洞发现能力显著优于SCA方法。


关键数据总结

指标MOVERYMVPCENTRIS
真阳性(TP)415220553*
误报(FP)2246272
漏报(FN)21184152
精确率(Precision)96%65%51%
召回率(Recall)96%38%62%

*注:CENTRIS报告的TP中包含大量误判,实际有效TP需人工验证。


5.4 MOVERY的检测速度与可扩展性

本节评估MOVERY在VCC检测中的时间效率与扩展能力。我们将总耗时划分为三个部分:

  1. 特征生成时间:生成漏洞/补丁签名的耗时
  2. 目标预处理时间:分析目标软件代码结构的耗时
  3. 匹配时间:执行VCC检测的耗时

实验结果对比

指标MOVERYReDeBugVUDDY
特征生成时间32小时0小时*2小时
平均预处理时间/软件45秒28秒298秒
平均匹配时间/软件155秒132秒85秒
总耗时/软件200秒160秒383秒

*注:ReDeBug直接使用原始补丁,无需特征生成阶段。


关键发现

  1. 特征生成效率

    • MOVERY需32小时处理4,219个补丁(见表2),耗时高于VUDDY(2小时),原因包括:
      • 需重构最旧漏洞函数
      • 分析代码行依赖关系
    • 该阶段为一次性任务,不影响日常检测
  2. 预处理时间对比

    • VUDDY因需构建全量函数哈希表,预处理时间最长(298秒/软件)
    • MOVERY通过复用代码区域缩减,预处理时间仅45秒/软件
  3. 匹配时间分析

    • MOVERY因采用细粒度代码行集合匹配(而非函数单元)及依赖分析,匹配时间最长(155秒)
    • 但总耗时仍为三者最短(200秒/软件),且在14.5M行代码量下仍保持稳定(见表3)

5.5 搜索空间缩减机制效能

MOVERY通过聚焦"借用代码部分"(borrowed code parts)优化检测效率:

可扩展性提升

指标全代码库借用代码部分缩减比例
目录数量539,781375,48930%↓
需扫描代码行数28,548,34013,417,72053%↓

技术收益:跳过约53%的非复用代码,显著降低计算负载。


检测精度提升

  • 误报减少机制
    • 现有技术在全代码库搜索时,易将语法相似但语义无关的函数误判为VCC
    • MOVERY通过限制检测范围,消除:
      • VUDDY的3个误报
      • ReDeBug的24个误报

典型案例

  • 误报场景:某日志处理函数与漏洞签名语法相似(如memcpy调用模式),但位于非复用区域
  • MOVERY应对:通过代码区域过滤自动排除

5.6 案例研究:Git中的漏洞

MOVERY发现,针对Glibc v2.30之前版本存在的堆缓冲区越界读取漏洞(CVE-2019-9169)的修复补丁,未应用于最新版Git(最流行的版本控制系统之一)。由于Git复用了v2.27之前的旧版Glibc,其漏洞代码与CVE-2019-9169公开补丁的语法差异显著(相似度仅为65%)。更为严重的是,我们验证了该漏洞在最新版Git中仍可引发内存泄漏。我们已向Git团队提交责任报告,其确认漏洞存在并回复称将在后续任务中修复,因当前漏洞未构成严重威胁(责任披露机制详见第6节讨论)。


6 讨论

阈值设定策略
实验中使用了两项阈值:

  1. 短代码行过滤:跳过字符数<15的规范化代码行
  2. 相似度阈值θ:设为0.5(相关实验见第5.1节)

短代码行过滤依据
人工分析显示,字符数<15的规范化代码行中,超过90%为高频出现的非漏洞代码,例如:

  • return语句
  • 常见变量声明(如int i;
  • 括号
  • else/continue等控制语句

若特征签名包含此类短代码行,可能引发误报。当略微提高字符限制(如16-17字符)时,非漏洞代码比例下降。因此,最终设定阈值为15字符。

阈值适应性
此阈值依赖具体漏洞数据集。若MOVERY应用于其他数据集,需重新校准该值。



6.1 最旧漏洞函数的应用

MOVERY在生成特征签名时引入最旧漏洞函数( f_o ),以应对OSS内部修改。尽管MOVERY可使用任何与已披露漏洞函数( f_d )存在语法差异的旧版本函数,但选择最旧版本的动机在于覆盖更多内部修改场景。

核心逻辑验证
假设需从漏洞函数中提取本质漏洞代码行(详见3.1节),可能存在三种情况:

  1. 同时存在于( f_o )与( f_d )
  2. 均不存在于两者
  3. 仅存在于其中一个

设( v_o )为最旧漏洞版本,( v_d )为已披露漏洞版本。通过以下推论可验证MOVERY方法的合理性:

  • 推论1:若本质漏洞代码行在( f_o )与( f_d )中均不存在,则( v_o )与( v_d )应被排除出受影响版本
  • 推论2:若本质漏洞代码行仅存在于( f_d ),则( v_o )不属于受影响版本

因此,只要NVD提供的CPE信息正确(数据源见4.1节),且漏洞影响范围包含( v_o )与( v_d ),本质漏洞代码行必然同时存在于两者,验证了MOVERY方法的有效性。


6.2 漏洞披露实践

我们向开发团队报告了14个可触发的VCC(含PoC验证),涉及Git、OpenMVG等目标软件及LibAV、LibGDX等流行OSS项目。其中:

  • 10个VCC(71%)为MOVERY独有检出(现有技术[14,17,49]无法发现)

处理进展

  1. 已确认漏洞:9个团队确认报告(2个已修复,2个计划修复)
  2. 讨论中:5个案例(如LibAV、OpenMVG)仍在沟通(含1个待处理PR)
  3. 暂缓披露:未复现的VCC暂不披露,待通过协作复现(参考方法[18,27])或补丁应用后跟进

6.3 局限性分析

MOVERY存在以下应用限制:

1. 依赖源码可获取性

  • 当前仅支持源码级检测,若二进制文件能精确提取函数控制/数据流依赖,未来可扩展至二进制场景

2. NVD的CPE准确性[8,47]

  • 部分CVE的CPE信息错误,可能影响最旧漏洞函数重构精度
  • 尽管已人工验证(见4.1节),但效率低下,需依赖CPE准确性提升

3. 函数内漏洞检测局限

  • 无法检测跨函数漏洞(如函数间依赖或C预处理器相关漏洞)
  • 未来计划通过引入函数间数据流关联信息扩展检测能力

4. 残余误差

  • 即使θ设为极值(0或1),仍存在4个漏报(FN)与3个误报(FP):
    • FN根源:语义相似但语法变更的代码(如循环结构转换)
    • FP根源:语法相似但补丁不同的函数
  • 若支持Type-4克隆检测或停用抽象化可缓解,但会牺牲可扩展性与精度
  • 当前方案在性能均衡性上显著优于现有技术,残余误差留待未来研究


7 相关工作

本节系统梳理与本研究相关的技术领域。

7.1 代码克隆检测技术

现有代码克隆检测技术(如[4,10,15,16,24,28,29,33-36,41,42])主要关注通用代码复用场景。由于未考虑漏洞特异性,此类技术直接应用于VCC检测时会产生大量误报[17,49]。

7.2 软件成分分析技术

软件成分分析(SCA)技术(如[2,9,21,25,39,48,51,52])旨在识别目标软件中的第三方组件。典型应用包括:

  • OSSPolice[9]:通过常量特征匹配检测Android应用的1-day漏洞
  • ATVHunter[51]:利用控制流信息精准识别Android第三方库版本

但此类技术无法应对补丁回移植或非复用漏洞场景(详见5.3节误报分析),难以解决本研究核心问题。

7.3 VCC检测技术

主流VCC检测方案包括:

  • ReDeBug[14]:基于切片窗口技术的Token级检测
  • VUDDY[17]:函数级可扩展检测框架
  • VGRAPH[3]:基于代码属性图(CPG)的Type-3克隆检测
  • MVP[49]:通过切片代码行实现低相似度漏洞检测

现有技术存在两大局限:

  1. 无法有效检测OSS内部修改引发的VCC
  2. 过度依赖补丁删除行检测(详见5.1-5.2节精度对比)

此外,基于学习的方法(如[22,23])与缺陷检测技术(如[20,26])虽具备通用漏洞发现潜力,但难以精准识别修改后OSS传播的VCC。


8 结论

修改后OSS组件中传播性漏洞的检测是软件安全领域的紧迫挑战。本研究提出MOVERY方法,通过三重技术创新实现高精度VCC检测:

  1. 跨版本函数校勘:溯源最旧漏洞函数应对内部修改
  2. 选择性抽象匹配:动态调整特征粒度平衡检测效能
  3. 复用代码空间缩减:聚焦风险区域提升可扩展性

实验表明,MOVERY在检测精度(96%精确率/96%召回率)与效率(200秒/项目)上显著优于现有技术。通过MOVERY的检测结果,开发者可及时修复修改后OSS组件中的潜在威胁,助力构建更安全的软件生态体系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值