Tabby 论文阅读
字数 3026 2025-08-22 22:47:39
Tabby: Java反序列化漏洞自动化利用链检测工具教学文档
1. 概述
1.1 研究背景与问题
Java反序列化漏洞挖掘存在以下主要问题:
- 利用链复用困难:每条链通常针对特定环境,复用需要大量调试
- 人工挖掘效率低:从sink method回溯到source method的过程依赖人工审计
- 现有工具局限性:只能分析源码,无法同时分析源码和依赖组件
1.2 Tabby解决方案
Tabby是一个自动化框架,基于soot框架和Neo4j图数据库半自动化寻找gadgets chains:
- 使用代码属性图(CPG)存储代码语义信息
- 支持源码+依赖组件联合分析
- 通过Neo4j存储查询到的利用链,提高复用性
1.3 主要贡献
- 提出使用代码属性图(CPG)作为中间层数据结构
- 开发可控变量算法优化CPG构建
- 实现支持多模块分析的解决方案
- 通过图数据库存储利用链提高复用性
2. 设计与实现
2.1 总体架构
Tabby工作流程分为三个阶段:
- 语义信息提取:从Jar/tar包中提取类、方法、控制流图等信息
- 代码属性图构建:ORG + PCG + MAG = CPG
- 利用链查找:通过finder插件从sink回溯查找source
2.2 代码属性图(CPG)构建
2.2.1 CPG定义
CPG是有向图,包含以下元素:
节点类型:
- Class
- Method
边类型及含义:
| 边类型 | 含义 |
|---|---|
| Extend | 类继承关系 |
| Interface | 类实现接口关系 |
| Has | 类包含方法关系 |
| Alias | 方法别名关系(多态) |
| Call | 方法调用关系 |
2.2.2 CPG组成
-
对象关系图(ORG):
- 包含所有class和method节点
- 包含基于静态分析的基本关系(has, extends, interface)
- CPG构建的基础图
-
精确函数调用图(PCG):
- 包含精确的函数调用关系
- 由函数调用图(MCG)经可控性分析剪枝得到
- MCG由控制流图(CFG)生成
-
同名函数图(MAG):
- 存储父类与子类、接口类与实现类间的同名函数关系
- 解决Java多态带来的函数定位困难问题
2.2.3 CPG构造过程
- 以ORG为基础图
- 添加PCG中的精确调用关系
- 添加MAG中的同名函数关系
2.3 参数可控性分析算法
2.3.1 关键概念
-
Action:
- method节点的属性,字典类型
- 表示函数参数和返回值在执行过程中的变化
- 格式:
<key, value>,表示变量key最终指向变量value
-
变量类型定义:
类型 描述 CONSTANT 常量 LOCAL 局部变量 PARAMETER 参数 RETURN 返回值 FIELD 字段 ARRAY_ELEMENT 数组元素 UNKNOWN 未知 -
LocalMap:
- method节点属性,字典类型
- 存储当前函数的
<变量, 权重> - 权重分配规则:
变量类型 权重 CONSTANT ∞ LOCAL 1 PARAMETER 0 RETURN 0 FIELD 2 ARRAY_ELEMENT 2 UNKNOWN ∞
-
Pollution Position:
- 函数调用边的属性,数组类型
- 存储调用函数的caller和传入参数的权重
- 用于gadgets chain finding
2.3.2 算法实现
函数主体: doMethodAnalysis
输入: 程序控制流图(CFG)
输出: results
算法流程:
- 遍历CFG中的每条语句
- 对于非return和非函数调用语句:
- 解析语句中的变量
- 根据变量类型分配权重
- 对于函数调用语句:
- 递归调用doMethodAnalysis()
- 处理caller和callee的LocalMap合并(使用calc()和correct()函数)
- 对于return语句:
- 保存result到results
- 开始分析下一行代码
2.4 利用链查找算法
2.4.1 核心概念
-
Trigger Condition (TC):
- sink method的属性,数组类型
- 存储哪些参数必须是可控的(触发条件)
-
常见sink method:
- Runtime.exec()
- Method.invoke()
- ProcessBuilder.start()
- 等Java反序列化常见危险方法
2.4.2 算法组件
-
traverse函数:
- 输入:TC、PP数组
- 输出:新的TC next数组
- 功能:根据当前TC截取PP
-
Expander算法:
- 功能:判断PP是否满足TC要求,决定回溯路线
- 输入:path、node_end、Relationship、TC
- 输出:path_next、TC_next
- 流程:
a. 如果是函数调用关系:- 用traverse计算tc_next
- 如果tc_next包含∞,返回(存在不可控变量)
b. 如果是同名函数关系: - 更新TC_next为TC
c. 返回更新后的path和tc
-
Evaluator算法:
- 功能:判断搜索深度或是否到达source node
- 输入:source、path、depth
- 输出:true/false
- 规则:
- 回溯到source → 返回利用链
- 未达设定深度 → 返回true
- 到达设定深度 → 返回false
2.4.3 算法示例分析
示例链条:
- 失败链条:A->C->C1->I
- 成功链条:A->C->C2->H
分析过程:
- 在node E发现有变量不可控 → 链不通
- 在node I发现有变量不可控 → 链不通
- 通过PP和TC判断:
- node I和node C1不通:TC要求第二个参数可控,但PP显示不可控
- 成功链满足expander和evaluator的所有条件
3. 实验与评估
3.1 对比实验
对比工具:gadgetinspector、serianalyzer和Tabby
评估指标:
- 准确性
- 耗时
实验结果:
- Tabby在Apache Dubbo组件分析中发现80+利用链
- 获得7个CVE编号
- 在准确性和效率上优于对比工具
3.2 实际应用
- GitHub star数:1.4k
- 已验证在实际漏洞挖掘中的有效性
4. 局限性与未来方向
4.1 当前限制
-
反射和动态代理:
- 静态分析难以确定将使用哪个类或方法
- 灵活性导致分析困难
-
语言限制:
- 目前仅支持Java反序列化利用链
- 尚未扩展到其他语言(C#、PHP等)
4.2 未来方向
- 改进对反射和动态代理的分析能力
- 将设计思路扩展到其他语言的反序列化漏洞检测
- 增强对复杂利用场景的支持
5. 总结
Tabby通过以下创新解决了Java反序列化利用链挖掘的关键问题:
- 代码属性图(CPG)作为中间表示
- 可控变量算法优化图构建
- 源码+依赖联合分析
- 图数据库存储提高复用性
实际应用证明Tabby是一个高效、实用的自动化利用链检测工具,为Java反序列化漏洞挖掘提供了有力支持。