阿里云jtools详解及codeql分析调用链
字数 1569 2025-09-01 11:26:17

Apache Fury反序列化漏洞分析与利用链构造

1. 漏洞概述

本文详细分析了一个基于Apache Fury反序列化的漏洞利用链,涉及多个Java库的交互和特殊利用技巧。该漏洞允许攻击者通过精心构造的序列化数据执行任意代码。

2. 环境与依赖分析

2.1 关键组件

  • Apache Fury: 一个高性能的跨语言序列化框架
  • Hutool: 一个Java工具库
  • Feilong: 另一个Java工具库

2.2 配置情况

  • 关闭了需要注册才能反序列化的配置
  • 存在黑名单机制,但存在绕过可能

3. 漏洞利用链分析

3.1 初始入口点

  • 反编译发现HTTP接口直接接受Fury反序列化参数
  • 会直接调用toString()方法
  • 黑名单参考: Fury文档

3.2 潜在利用链

  1. Hutool自带getter触发

    • 利用条件较为苛刻
    • AbstractActionequals
    • PriorityQueuecompare
  2. Feilong中的PropertyComparator

    • 类似于Commons BeanUtils中的触发机制
    • 可用于触发getter方法

3.3 利用链查找方法

使用CodeQL构建分析库,编写通用规则查找sink点:

  1. 任意类构造函数调用

    • 类似于CC3链触发TrAXFilter的newInstance
    • 但TrAXFilter在黑名单中
  2. Hutool MapProxy二次反序列化

    • 正解路径
    • Fury文档说明:没有继承反序列化接口的类也可以参与反序列化

4. Sink点分析

4.1 主要可利用sink点

  1. ReflectUtil.newInstance - 任意类构造函数调用
  2. IoUtil.readObj - 二次反序列化

4.2 筛选条件

  • 排除Feilong黑名单中的类
  • 不考虑JNDI注入(因JDK版本未知且无Tomcat依赖)

5. 数据流分析

5.1 触发点类型

  1. toString触发点
  2. readObject触发点
  3. invoke触发点

5.2 污点传播规则

  • 调用Convert.convert,参数可控
  • filename来自methodname,从当前map中获取对应值
  • 最终调用到BeanConverter.convertInternal转换为byte进行二次反序列化

6. 利用链构造细节

6.1 MapProxy利用关键

  • MapProxy中塞入二次反序列化数据的byte数组
  • key为fieldname
  • fieldname截取自调用的方法名:
    • getis开头
    • 无参方法
    • 返回类型不能为void

6.2 触发机制

  1. 使用PriorityQueue触发PropertyComparator.compare
  2. 控制Convert.convert的第二个参数
  3. 确保进入BeanConverter.convert而非其他路径

6.3 关键条件

  • 传入的Class type不在已知convert列表中
  • 最后一层必须是Bean
  • 必须有setter或public field

7. 问题与解决方案

7.1 常见报错

  • PropertyComparator与CB链中的BeanComparator行为差异
  • 会检查是否加载了Spring工具类
    • 存在Spring依赖时:调用Spring工具类处理
    • 无Spring依赖时:进入类似CB链的处理流程

7.2 解决方案

  • 修改payload,移除或处理Spring依赖相关部分
  • 使用纯净环境测试

8. 最终利用

构造payload使命令执行结果输出到desc.txt,然后通过web访问获取结果。

附录:CodeQL查询示例

// 查找符合条件的getter方法
from Method m
where 
  (m.getName().matches("get%") or m.getName().matches("is%")) and
  m.getNumberOfParameters() = 0 and
  m.getReturnType() != void
select m
// 污点传播规则示例
class MyTaintTrackingConfiguration extends TaintTracking::Configuration {
  MyTaintTrackingConfiguration() { this = "MyTaintTrackingConfiguration" }
  
  override predicate isSource(DataFlow::Node source) {
    // 定义source点
  }
  
  override predicate isSink(DataFlow::Node sink) {
    // 定义sink点
  }
  
  override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
    // 定义额外的污点传播步骤
  }
}

通过以上分析和步骤,可以成功构造出针对该Fury反序列化漏洞的利用链。

Apache Fury反序列化漏洞分析与利用链构造 1. 漏洞概述 本文详细分析了一个基于Apache Fury反序列化的漏洞利用链,涉及多个Java库的交互和特殊利用技巧。该漏洞允许攻击者通过精心构造的序列化数据执行任意代码。 2. 环境与依赖分析 2.1 关键组件 Apache Fury : 一个高性能的跨语言序列化框架 Hutool : 一个Java工具库 Feilong : 另一个Java工具库 2.2 配置情况 关闭了需要注册才能反序列化的配置 存在黑名单机制,但存在绕过可能 3. 漏洞利用链分析 3.1 初始入口点 反编译发现HTTP接口直接接受Fury反序列化参数 会直接调用 toString() 方法 黑名单参考: Fury文档 3.2 潜在利用链 Hutool自带getter触发 利用条件较为苛刻 AbstractAction → equals PriorityQueue → compare Feilong中的PropertyComparator 类似于Commons BeanUtils中的触发机制 可用于触发getter方法 3.3 利用链查找方法 使用CodeQL构建分析库,编写通用规则查找sink点: 任意类构造函数调用 类似于CC3链触发TrAXFilter的 newInstance 但TrAXFilter在黑名单中 Hutool MapProxy二次反序列化 正解路径 Fury文档说明:没有继承反序列化接口的类也可以参与反序列化 4. Sink点分析 4.1 主要可利用sink点 ReflectUtil.newInstance - 任意类构造函数调用 IoUtil.readObj - 二次反序列化 4.2 筛选条件 排除Feilong黑名单中的类 不考虑JNDI注入(因JDK版本未知且无Tomcat依赖) 5. 数据流分析 5.1 触发点类型 toString 触发点 readObject 触发点 invoke 触发点 5.2 污点传播规则 调用 Convert.convert ,参数可控 filename 来自 methodname ,从当前map中获取对应值 最终调用到 BeanConverter.convertInternal 转换为byte进行二次反序列化 6. 利用链构造细节 6.1 MapProxy利用关键 在 MapProxy 中塞入二次反序列化数据的byte数组 key为 fieldname fieldname 截取自调用的方法名: 以 get 或 is 开头 无参方法 返回类型不能为 void 6.2 触发机制 使用 PriorityQueue 触发 PropertyComparator.compare 控制 Convert.convert 的第二个参数 确保进入 BeanConverter.convert 而非其他路径 6.3 关键条件 传入的 Class type 不在已知convert列表中 最后一层必须是Bean 必须有setter或public field 7. 问题与解决方案 7.1 常见报错 PropertyComparator 与CB链中的 BeanComparator 行为差异 会检查是否加载了Spring工具类 存在Spring依赖时:调用Spring工具类处理 无Spring依赖时:进入类似CB链的处理流程 7.2 解决方案 修改payload,移除或处理Spring依赖相关部分 使用纯净环境测试 8. 最终利用 构造payload使命令执行结果输出到 desc.txt ,然后通过web访问获取结果。 附录:CodeQL查询示例 通过以上分析和步骤,可以成功构造出针对该Fury反序列化漏洞的利用链。