前言
最近回顾了下之前的关于Commons Collections这块的笔记,从CC1到CC10,从调用链来看,其实都是很相似的。为了巩固下复习的效果,尝试挖掘一条新的调用链,遂出现了本文,大佬轻喷。
建议读者对Commons Collections链有一定了解后再阅读此文。
基础准备
这里直接用ysoserial的源码就可以,jdk的版本我这里用的是1.8u131。我们应该知道,在这个jdk版本下,CC1和CC3中利用的AnnotationInvocationHandler是经过修复的,在CC1和CC3的调用链中,都是利用AnnotationInvocationHandler.readObject()来作为入口。
所以,首先我们全局搜索“readObject(”:
经过筛选,找到org.apache.commons.collections.bidimap.DualHashBidiMap这个类,其依赖于commons-collections-3.1.jar
我们来看DualHashBidiMap的readObject():
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
maps[0] = new HashMap();
maps[1] = new HashMap();
Map map = (Map) in.readObject();
putAll(map);
}
跟进DualHashBidiMap的父类AbstractDualBidiMap#putAll方法:
public void putAll(Map map) {
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
put(entry.getKey(), entry.getValue());
}
}
跟进AbstractDualBidiMap.put():
public Object put(Object key, Object value) {
if (maps[0].containsKey(key)) {
maps[1].remove(maps[0].get(key));
}
if (maps[1].containsKey(value)) {
maps[0].remove(maps[1].get(value));
}
final Object obj = maps[0].put(key, value);
maps[1].put(value, key);
return obj;
}
注