LAVA : Large-scale Automated Vulnerability Addition
发表于IEEE Symposium on Security and Privacy 2016
基本信息
这篇论文的重点在于
✅自动化、大规模、系统地
✅ 在真实程序中植入可控漏洞
✅ 生成一个有 Ground truth(已知漏洞位置+触发条件)的标准语料库(corpus)如果有一个针对该程序的漏洞语料库,就能相对公平地评价哪些漏洞挖掘工具更强
因此
LAVA 通过少量、自动的源代码修改,把真实严重的漏洞自然地注入到真实大程序中, 注入过程快、广泛分布、符合真实数据流、每个漏洞都带有精确触发输入。 这样,LAVA就能生成高质量、可实验、可复现的漏洞语料库LAVA注入漏洞的流程
- 识别DUA数据(Dead, Uncomplicated and Available data)
- TCN小 -> 数据简单 -> 可用。每次做合并计算时,新的 TCN = 输入中最大的 TCN + 1
- liveness - 与污点标签和输入的字节相关联。liveness为0或者非常低的字节就非常适合用来做DUA。liveness 的值是该字节被用来决定多少个分支的计数,越小说明对程序的影响越小
- fig3和fig4中,越长且颜色越浅,越适合作为DUA。颜色浅说明TCN低或者liveness低,对程序的控制流影响少;长说明在程序中存活时间长
- 找到潜在攻击点(Attack point能够利用DUA数据的位置)
- 攻击必须发生在找到的DUA之后
- 注入代码(让DUA数据在攻击点处可用,并利用这些数据引发漏洞)
- 在DUA和攻击点之间引入数据流关系
- 注意两点
- 为了保证DUA的有效访问,可能会将其抽取为静态变量或者全局变量
- 为了保证漏洞不是随时可以触发的,会对代码添加一些确保条件
- 识别DUA数据(Dead, Uncomplicated and Available data)
其他设计方法
- 直接修改源程序,降低代码安全性 - 漏洞不可控;破坏程序基本的正确性
- 符号执行,判断哪些条件阻止了漏洞,直接修改条件绕过它 - 分析成本太大(符号执行、约束求解),因此只能制造浅层的漏洞
具体实现
- 编译一个被污点查询动态插桩的目标程序版本
- 基于PANDA(QEMU) - 能够对执行过程进行回放;可添加插件;集成S2E,能够将执行过程中的IR转为LLVM IR
- 运行程序,并使用不同的输入来测试
- 在QEMU中执行,以ISO的形式插入可执行程序,同时通过端口给QEMU发送执行指令
- 识别DUA和攻击点
- DUA - TCN足够小;liveness足够小;
- 目前攻击点(选择为指针或者整数)选择函数的参数,通过将dua注入来修改攻击点,造成漏洞。但是这种方法还是比较局限
- 插入漏洞重新编译,测试能否触发漏洞
- 使用Clang生成代码,该代码能进行漏洞触发。主要分为两步:1)保存DUA的值到静态变量等后续可以使用的位置;2)在attack point处判断DUA是否等于某个值,是则将其添加到函数的参数中,从而触发漏洞
实验结果
- 评估LAVA的有效性
- 在开源程序中注入大量漏洞,统计程序的相关数据和漏洞注入情况
- 分析注入的漏洞的分布和真实性
- 使用fuzzer和符号执行工具来测试对LAVA漏洞的
- 定义不同漏洞的标准:自动化漏洞检测工具对两个漏洞采用不同的推理分析方式
- 漏洞现实性评估标准
- DUA和attack point在程序执行中的分布情况
- 程序的原始行为是否被保留
- 实验选择 - FUZZER和SES,都分别在目标程序上运行5小时
- Coverage guided fuzzer (referred to as FUZZER)
- Symbolic execution + SAT solving (referred to as SES)
局限性:
- 仅关注往源码里插入漏洞,不关注二进制
- 限制为linux平台上的C语言写的开源软件
- 重点关注越界读写,后续会扩展
- 不能插入逻辑bug
- LAVA的污点分析方法是基于数据流的,这意味着它特别擅长生成那些通过特定数据输入(例如攻击者控制的数据)来触发的漏洞。然而,逻辑错误、加密缺陷 和 侧信道漏洞 的触发方式通常不依赖于数据流控制,而是涉及程序内部复杂的逻辑判断、加密算法的设计缺陷或外部信息泄漏等机制。因此,这些漏洞的注入方式和LAVA目前的设计目标不匹配
- LAVA引入了意外的漏洞(如使用后释放和解引用未初始化指针)
- 没有关注误报率