尝试CodeQL自动化分析2025 SUCTF SU_Solon
字数 1718 2025-08-29 08:30:31

CodeQL自动化分析Hessian反序列化漏洞利用链

1. Hessian反序列化基础

1.1 Hessian简介

Hessian是一个轻量级的remoting onhttp工具,提供Java序列化/反序列化功能,特点包括:

  • 二进制RPC协议
  • 比WebService更简单快捷
  • 适合发送二进制数据

1.2 Hessian反序列化流程

  1. 客户端发起请求并按照RPC协议格式填充信息
  2. 将二进制格式文件转化为流并通过传输协议传输
  3. 服务端接收流并转换为二进制格式文件
  4. 按照RPC协议格式获取请求信息并处理
  5. 处理结果写入二进制格式文件并返回

1.3 与原生反序列化的区别

  • 不需要实现Serializable接口:显著扩展了可利用类的范围
  • 起始方法限制:只能为hashCode/equals/compareTo方法
  • 成员变量限制:不能为transient修饰
  • 不依赖:不依赖readObject逻辑和getter/setter逻辑

2. SUCTF SU_Solon题目分析

2.1 题目特点

  • 明确的Hessian反序列化题目
  • 触发任意类的toString方法作为入口点
  • 依赖包含:
    • Fastjson 1.2.83
    • H2数据库

2.2 利用思路

  1. 利用Fastjson的JSONArray/JSONObject类的toString方法触发任意类的getter方法
  2. 结合H2数据库的JDBC连接实现RCE

3. CodeQL分析过程

3.1 分析目标

寻找getter方法触发JDBC连接的途径

3.2 分析方法选择

  • 全局污点分析(TaintTracking2):复杂但全面
  • 构造查询谓词:相对简单,本文采用此方法

3.3 查询构建

  1. 通过getASupertype*()递归超类实现全面覆盖
  2. 查询静态调用目标和动态调度目标
  3. 使用Callable作为查询子集(包含MethodConstructor

3.4 查询结果

发现14种可能的触发点,重点关注:

  1. UnpooledDataSource
  2. JdbcDataSource
  3. DataSourceWrapper
  4. DataSourceProxy

4. 利用链分析

4.1 UnpooledDataSource利用

  • 方法getConnection()
  • 利用步骤
    1. 本地启动HTTP服务器存放恶意SQL文件
    2. 绕过SecurityManager限制:System.setSecurityManager(null);
    3. 生成反序列化对象触发RCE

4.2 JdbcDataSource利用

  • 验证:可以触发JDBC连接
  • 问题org.h2.jdbcx.JdbcDataSource在Hessian黑名单中
  • 黑名单范围org.h2.jdbcx全限定类名前缀被过滤

4.3 其他利用点分析

  1. DataSourceWrapper

    • 包装类,本质仍是触发DataSource接口的getConnection()
    • 与直接触发UnpooledDataSource/JdbcDataSource无本质区别
  2. DataSourceProxy

    • 效果与DataSourceWrapper类似
  3. UnixPrintService

    • JDK低版本可利用getter实现命令注入
    • 仍在sofa-hession黑名单中

5. 防御与绕过

5.1 SecurityManager绕过

  • 直接关闭:System.setSecurityManager(null);

5.2 黑名单绕过策略

  1. 寻找不在黑名单中的类似功能类
  2. 利用包装类间接调用
  3. 寻找新的利用链

6. 总结与最佳实践

6.1 最佳利用链

  • 首选:UnpooledDataSource的getConnection()方法
  • 原因:不在黑名单中且功能完整

6.2 CodeQL分析价值

  • 快速定位潜在利用链
  • 全面覆盖可能的调用路径
  • 辅助识别黑名单外的可用类

6.3 扩展思考

  • 结合Fastjson漏洞扩大攻击面
  • 探索更多不在黑名单中的DataSource实现
  • 研究其他toString到getter的触发方式

附录:关键QL查询示例

// 基本查询结构示例
from Callable c
where c.getName() = "getConnection" 
  and c.getDeclaringType().getASupertype*().hasQualifiedName("javax.sql", "DataSource")
select c
// 更全面的查询示例
from Method m
where m.getName().matches("get%") 
  and m.getDeclaringType().getASupertype*().hasQualifiedName("javax.sql", "DataSource")
  and not m.getDeclaringType().getQualifiedName().matches("org.h2.jdbcx.%")
select m
CodeQL自动化分析Hessian反序列化漏洞利用链 1. Hessian反序列化基础 1.1 Hessian简介 Hessian是一个轻量级的remoting onhttp工具,提供Java序列化/反序列化功能,特点包括: 二进制RPC协议 比WebService更简单快捷 适合发送二进制数据 1.2 Hessian反序列化流程 客户端发起请求并按照RPC协议格式填充信息 将二进制格式文件转化为流并通过传输协议传输 服务端接收流并转换为二进制格式文件 按照RPC协议格式获取请求信息并处理 处理结果写入二进制格式文件并返回 1.3 与原生反序列化的区别 不需要实现Serializable接口 :显著扩展了可利用类的范围 起始方法限制 :只能为hashCode/equals/compareTo方法 成员变量限制 :不能为transient修饰 不依赖 :不依赖readObject逻辑和getter/setter逻辑 2. SUCTF SU_ Solon题目分析 2.1 题目特点 明确的Hessian反序列化题目 触发任意类的toString方法作为入口点 依赖包含: Fastjson 1.2.83 H2数据库 2.2 利用思路 利用Fastjson的JSONArray/JSONObject类的toString方法触发任意类的getter方法 结合H2数据库的JDBC连接实现RCE 3. CodeQL分析过程 3.1 分析目标 寻找getter方法触发JDBC连接的途径 3.2 分析方法选择 全局污点分析(TaintTracking2) :复杂但全面 构造查询谓词 :相对简单,本文采用此方法 3.3 查询构建 通过 getASupertype*() 递归超类实现全面覆盖 查询静态调用目标和动态调度目标 使用 Callable 作为查询子集(包含 Method 和 Constructor ) 3.4 查询结果 发现14种可能的触发点,重点关注: UnpooledDataSource JdbcDataSource DataSourceWrapper DataSourceProxy 4. 利用链分析 4.1 UnpooledDataSource利用 方法 : getConnection() 利用步骤 : 本地启动HTTP服务器存放恶意SQL文件 绕过SecurityManager限制: System.setSecurityManager(null); 生成反序列化对象触发RCE 4.2 JdbcDataSource利用 验证 :可以触发JDBC连接 问题 : org.h2.jdbcx.JdbcDataSource 在Hessian黑名单中 黑名单范围 : org.h2.jdbcx 全限定类名前缀被过滤 4.3 其他利用点分析 DataSourceWrapper : 包装类,本质仍是触发DataSource接口的 getConnection() 与直接触发UnpooledDataSource/JdbcDataSource无本质区别 DataSourceProxy : 效果与DataSourceWrapper类似 UnixPrintService : JDK低版本可利用getter实现命令注入 仍在sofa-hession黑名单中 5. 防御与绕过 5.1 SecurityManager绕过 直接关闭: System.setSecurityManager(null); 5.2 黑名单绕过策略 寻找不在黑名单中的类似功能类 利用包装类间接调用 寻找新的利用链 6. 总结与最佳实践 6.1 最佳利用链 首选 :UnpooledDataSource的 getConnection() 方法 原因 :不在黑名单中且功能完整 6.2 CodeQL分析价值 快速定位潜在利用链 全面覆盖可能的调用路径 辅助识别黑名单外的可用类 6.3 扩展思考 结合Fastjson漏洞扩大攻击面 探索更多不在黑名单中的DataSource实现 研究其他toString到getter的触发方式 附录:关键QL查询示例