cc7的思路同样是找了另一条调用链来触发Lazy.get方法
在ysoserial中给出的调用链中,选取了java.util.Hashtable.readObject方法作为反序列化的起点
Hashtable提供put方法,这里的key和value为手动put进的键值对
java.util.Hashtable.readObject方法会调用reconstitutionPut方法,参数key,value可控,跟进reconstitutionPut方法,截取关键部分
当e不为null时,会进入for语句。for语句中有一个if语句,可触发e.hash和e.key.equals方法
在java.util.Hashtable.readObject方法有个for循环语句,以Hashtable中的键值对来循环次数。每次循环会执行reconstitutionPut方法,将上一次的键值对信息写进tab中
所以要执行两次put语句,才能保证tab不为空
Java语言还存在一个布尔短路运输的特性,也就是说当e.hash == hash
判定为假,就会直接退出if语句,导致不执行e.key.equals(key)
ysoserial这里设置e.key为LazyMap对象,由于LazyMap下没有equals方法,所以它会调用父类AbstractMapDecorator.equals方法
还会调用this.map.equals(object)
方法
判断this.map:
想要执行transformer的transform方法,那么需要用Lazy.decorate方法对transformerChain进行修饰
Map innerMap = new HashMap();
Map outerMap = LazyMap.decorate(innerMap, transformerChain);
还需要将这个outerMap用put存进Hashtable,以达到e.key为LazyMap对象的目的
Hashtable table = new Hashtable();
table.put(outerMap, 1);