Java 反序列化漏洞原理(六)fastjson 1.2.68 绕过原理
声明 本文章中所有内容仅供学习交流,严禁用于非法用途,否则由此产生的一切后果均与作者无关。 Fastjson <= 1.2.68 expectClass 绕过原理 当 fastjson 更新到 1.2.68 之后,大部分安全漏洞都已经封堵住了,但不排除还有人手里握着一些 0day 没有放出来。 fastjson 1.2.68 在进行反序列化的时候,会进入 ObjectDeserializer 的 deserialze 方法,而 安全人员发现 当 @type 为 java.lang.AutoCloseable 的时候会找到实现类 JavaBeanDeserializer 调用 deserialze,而 JavaBeanDeserializer 的 deserialze 方法还会继续解析得到第二个 @type 对应的值进行反序列化,并且 expectClass 则不再是 null 值,而是 java.lang.AutoCloseable。 JavaBeanDeserializer 的 deserialze 部分代码示例。 if (lexer.token() == JSONToken.LITERAL_STRING) { // 第二个 @type 的值 String typeName = lexer.stringVal(); lexer.nextToken(JSONToken.COMMA); if (typeName.equals(beanInfo.typeName)|| parser.isEnabled(Feature.IgnoreAutoType)) { if (lexer.token() == JSONToken.RBRACE) { lexer.nextToken(); break; } continue; } // 这里没有获取到 deserializer ObjectDeserializer deserializer = getSeeAlso(config, this.beanInfo, typeName); Class<?> userType = null; if (deserializer == null) { // 第一个 @type 的值 Class<?> expectClass = TypeUtils.getClass(type); // 在包含 expectClass 时会绕过 userType = config.checkAutoType(typeName, expectClass, lexer.getFeatures()); deserializer = parser.getConfig().getDeserializer(userType); } // 再次进行反序列化,会触发反射构造实例 Object typedObject = deserializer.deserialze(parser, userType, fieldName); if (deserializer instanceof JavaBeanDeserializer) { JavaBeanDeserializer javaBeanDeserializer = (JavaBeanDeserializer) deserializer; if (typeKey != null) { FieldDeserializer typeKeyFieldDeser = javaBeanDeserializer.getFieldDeserializer(typeKey); if (typeKeyFieldDeser != null) { typeKeyFieldDeser.setValue(typedObject, typeName); } } } return (T) typedObject; } ParseConfig 的 checkAutoType 部分代码示例,只要第二个 @type 继承了 第一个 @type 即可触发。 ...