tabby静态分析实践
字数 1467 2025-08-19 12:42:28

Tabby静态分析实践指南

0x01 Tabby测试

1a 工具印象

Tabby是一个基于代码属性图的Java静态分析工具,主要特点包括:

  • 支持分析编译后的War包、Jar包等形式
  • 工作流程分为两个阶段:
    • 代码属性图生成阶段:由tabby.core负责生成带污点信息的代码属性图
    • 漏洞发现阶段:使用neo4j扩展tabby path finder查询source-sink语句寻找调用链路

1b 安装和运行

环境准备:

  1. 下载Neo4j 5.12.0
  2. 下载apoc-5.12.0-core.jar和apoc-5.12.0-extended.jar
  3. 下载tabby-path-finder-1.0.jar或1.1版本

配置:

# 允许apoc扩展
dbms.security.procedures.unrestricted=jwt.security.*,apoc.*,tabby.*

启动数据库后执行:

CREATE CONSTRAINT c1 IF NOT EXISTS FOR (c:Class) REQUIRE c.ID IS UNIQUE;
CREATE CONSTRAINT c2 IF NOT EXISTS FOR (c:Class) REQUIRE c.NAME IS UNIQUE;
CREATE CONSTRAINT c3 IF NOT EXISTS FOR (m:Method) REQUIRE m.ID IS UNIQUE;
CREATE CONSTRAINT c4 IF NOT EXISTS FOR (m:Method) REQUIRE m.SIGNATURE IS UNIQUE;
CREATE INDEX index1 IF NOT EXISTS FOR (m:Method) ON (m.NAME);
CREATE INDEX index2 IF NOT EXISTS FOR (m:Method) ON (m.CLASSNAME);
CREATE INDEX index3 IF NOT EXISTS FOR (m:Method) ON (m.NAME, m.CLASSNAME);
CREATE INDEX index4 IF NOT EXISTS FOR (m:Method) ON (m.NAME, m.NAME0);
CREATE INDEX index5 IF NOT EXISTS FOR (m:Method) ON (m.SIGNATURE);
CREATE INDEX index6 IF NOT EXISTS FOR (m:Method) ON (m.NAME0);
CREATE INDEX index7 IF NOT EXISTS FOR (m:Method) ON (m.NAME0, m.CLASSNAME);

运行Tabby:

java -Xmx8g -jar tabby.jar

1c 运行配置

推荐配置config/settings.properties

tabby.debug.details = true 
tabby.build.target = cases/java-sec-code-1.0.0.jar 
tabby.build.libraries = libs 
tabby.build.mode = web # 或gadget

1d 测试结果

  • 254MB Jar包分析:16w classes,耗时极长
  • 31MB业务代码:2w+ classes,耗时约7分钟

1e 踩坑记录

  • 大Jar包分析需要足够内存:建议至少8G
  • 分析时间可能很长,需耐心等待

0x02 图数据库Neo4j

2a 入门介绍

Neo4j属性图模型由节点和关系组成,使用Cypher查询语言。

节点表示:

  • () - 匿名节点
  • (p:Person) - 带变量和标签的节点
  • (:Technology) - 只有标签的节点
  • (work:Company) - 带变量和标签的节点

关系表示:

  • [:Likes] - 关系类型
  • -[rel:Is_Friends_With {since: 2018}]-> - 带属性和变量的关系

2b 概念指南

属性图基本概念:

  • 节点(nodes):表示实体
  • 标签(labels):对节点分组
  • 关系(relationships):连接节点
  • 属性(properties):节点和关系的键值对

2c Cypher指南

基本Cypher操作:

-- 创建节点
CREATE (ee:Person {name: 'Emil', from: 'Sweden', kloutScore: 99})

-- 查找节点
MATCH (ee:Person) WHERE ee.name = 'Emil' RETURN ee;

-- 创建关系和节点
MATCH (ee:Person) CREATE (js:Person), (ee)-[:KNOWS {since: 2001}]->(js)

-- 查询所有Person节点
match (any:Person) return any

2d 查询代码属性图

常用查询:

-- 查看图结构
call db.schema.visualization

-- 获取所有标签
call db.labels

-- 获取所有关系类型
call db.relationshipTypes

-- 获取所有节点属性
match (n) unwind keys(n) as allkeys return distinct allkeys

0x03 Tabby实践

3a 查询方法

基本查询模板:

match (source:Method) 
match (sink:Method {IS_SINK:true}) 
call apoc.algo.allSimplePaths(m1, source, "ALIAS>|CALL>", 12) yield path 
return * limit 20

3b 静态分析技术问题

Tabby的污点分析特点:

  • 对class/method节点建模
  • call edge会添加pollution_positions保存污点信息
  • 主要关注method->method的数据流追踪

3c 端点识别

Tabby内置端点识别:

  • Struts类型
  • Servlet类型
  • JSP类型
  • 注释类型

查询模板:

match (source:Method {IS_ENDPOINT:true}) 
with collect(source) as sources
match (sink:Method {IS_SINK: true, VUL:"FILE_WRITE"})
with sources, collect(sink) as sinks
call tabby.algo.findPath(sources, "forward", sinks, 8, false) yield path
where none(n in nodes(path) where n.NAME0 in ["java.io.OutputStream.flush","java.io.Writer.flush", "java.util.Iterator.hasNext", "java.lang.Object.toString", "java.io.ObjectOutputStream.<init>", "java.io.PrintWriter.write"])
return path limit 10

3d 查找危险方法

文件上传漏洞检测:

-- 查找顶层service方法
match (source:Method {NAME:"service", CLASSNAME:"com.sun.jersey.spi.container.servlet.ServletContainer"}) 

-- 查找FileOutputStream构造方法
match (sink:Method {SIGNATURE:"<java.io.FileOutputStream: void <init>(java.lang.String)>",CLASSNAME:"java.io.FileOutputStream"})

-- 查找调用路径
call tabby.algo.findPath(source, ">", sink, 15, false) YIELD path 
return path

请求输入流检测:

MATCH path=(source:Method)-[:CALL]->(sink:Method {NAME:"getInputStream"}) 
where source.CLASSNAME starts with "com.esafenet.servlet"
return path

0x04 实践小结

4a 数据流分析对象

Tabby 1.2版本分析特点:

  • 以class、method作为图节点建模
  • 节点关系类型:
    • class->class: Interface、Extends
    • class->method: Has
    • method->method: Call、Alias

4b 整体感知

优势:

  • 基于Soot生成的字节码分析,支持Jar、classes等文件
  • 对反序列化等有明确触发点方法的漏洞检测效果好
  • 在查找特定类、Controller/Servlet及其方法方面有优势

劣势:

  • 污点流(taint flow)信息较少
  • 默认全量分析,难以对大Jar包进行选择性分析
  • 数据流调试资料较少

理想污点分析:

  • 标记request对象中所有外部可控的数据流
  • 追踪这些数据流是否经过指定的危险函数
  • 减少底层方法追踪,关注如new FileOutputStream(path)等高层次方法
Tabby静态分析实践指南 0x01 Tabby测试 1a 工具印象 Tabby是一个基于代码属性图的Java静态分析工具,主要特点包括: 支持分析编译后的War包、Jar包等形式 工作流程分为两个阶段: 代码属性图生成阶段:由tabby.core负责生成带污点信息的代码属性图 漏洞发现阶段:使用neo4j扩展tabby path finder查询source-sink语句寻找调用链路 1b 安装和运行 环境准备: 下载Neo4j 5.12.0 下载apoc-5.12.0-core.jar和apoc-5.12.0-extended.jar 下载tabby-path-finder-1.0.jar或1.1版本 配置: 启动数据库后执行: 运行Tabby: 1c 运行配置 推荐配置 config/settings.properties : 1d 测试结果 254MB Jar包分析:16w classes,耗时极长 31MB业务代码:2w+ classes,耗时约7分钟 1e 踩坑记录 大Jar包分析需要足够内存:建议至少8G 分析时间可能很长,需耐心等待 0x02 图数据库Neo4j 2a 入门介绍 Neo4j属性图模型由节点和关系组成,使用Cypher查询语言。 节点表示: () - 匿名节点 (p:Person) - 带变量和标签的节点 (:Technology) - 只有标签的节点 (work:Company) - 带变量和标签的节点 关系表示: [:Likes] - 关系类型 -[rel:Is_Friends_With {since: 2018}]-> - 带属性和变量的关系 2b 概念指南 属性图基本概念: 节点(nodes):表示实体 标签(labels):对节点分组 关系(relationships):连接节点 属性(properties):节点和关系的键值对 2c Cypher指南 基本Cypher操作: 2d 查询代码属性图 常用查询: 0x03 Tabby实践 3a 查询方法 基本查询模板: 3b 静态分析技术问题 Tabby的污点分析特点: 对class/method节点建模 call edge会添加pollution_ positions保存污点信息 主要关注method->method的数据流追踪 3c 端点识别 Tabby内置端点识别: Struts类型 Servlet类型 JSP类型 注释类型 查询模板: 3d 查找危险方法 文件上传漏洞检测: 请求输入流检测: 0x04 实践小结 4a 数据流分析对象 Tabby 1.2版本分析特点: 以class、method作为图节点建模 节点关系类型: class->class: Interface、Extends class->method: Has method->method: Call、Alias 4b 整体感知 优势: 基于Soot生成的字节码分析,支持Jar、classes等文件 对反序列化等有明确触发点方法的漏洞检测效果好 在查找特定类、Controller/Servlet及其方法方面有优势 劣势: 污点流(taint flow)信息较少 默认全量分析,难以对大Jar包进行选择性分析 数据流调试资料较少 理想污点分析: 标记request对象中所有外部可控的数据流 追踪这些数据流是否经过指定的危险函数 减少底层方法追踪,关注如new FileOutputStream(path)等高层次方法