阿里云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 潜在利用链
-
Hutool自带getter触发
- 利用条件较为苛刻
AbstractAction→equalsPriorityQueue→compare
-
Feilong中的PropertyComparator
- 类似于Commons BeanUtils中的触发机制
- 可用于触发getter方法
3.3 利用链查找方法
使用CodeQL构建分析库,编写通用规则查找sink点:
-
任意类构造函数调用
- 类似于CC3链触发TrAXFilter的
newInstance - 但TrAXFilter在黑名单中
- 类似于CC3链触发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查询示例
// 查找符合条件的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反序列化漏洞的利用链。