扫码领资料
获网安教程
免费&进群
JSON: JavaScript Object Notation (对象表示法),js 对象简谱,是一种轻量级的数据交换格式.
Fastjson 优点:速度快,使用广泛,测试完备,使用简单,功能完备
导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
Json 数组
中扩号包裹,数组的元素之间逗号分开,数组元素类型没有数据类型限制
例子:
<script type="text/javascript">
var jsonArray = ["m1","m2",99,9.9,true];
for ( i=0 ; i<jsonArray.length; i++){
console.log(jsonArray[i]);
}
</script>
Json 对象
大括号包裹,定义为键值对,键必须上字符串类型,值对数据类型不限制,键与值之间为冒号分开,键值对之间为逗号分开
例子:
<script type="text/javascript">
var jsonObject = {"m1":99,"m2":9.9,"m3":true,"m4":"who are you?"};
console.log(jsonObject.m1);
console.log(jsonObject.m2);
console.log(jsonObject.m3);
console.log(jsonObject.m4);
</script>
数组和对象可以互相嵌套
JSON.toJSONString:支持将 Java 基本类型和 JavaBean 转换成 jsonString;
JSON.parseObject:支持将 json 类型的 String 转换成 T 类型的对象;
测试类
import com.oracle.webservices.internal.api.databinding.DatabindingMode;
public class Student {
public int id;
public String name;
public int age
public void setId(int i) {
this.id = i;
}
public void setName(String m1) {
this.name = m1;
}
public void setAge(int i) {
this.age = i;
}
}
import com.alibaba.fastjson.JSON;
public class FastjsonTest {
public static void main(String[] args) {
display();
}
public static void display(){
Student student = new Student();
student.setId(1);
student.setName("m1");
student.setAge(6);
String s = JSON.toJSONString(student);
System.out.println(s);
System.out.println("=============================================");
Student student1 = JSON.parsObject(s, Student.class);
System.out.println(student1);
}
}
输出
JSON.toJSONString:支持将 Java 基本类型和 JavaBean 转换成 jsonString;
JSON.parseArray:将 json 字符串转换成一个一个的实体类,存到 List 集合中;
import com.alibaba.fastjson.JSON;
import java.util.ArrayList;
import java.util.List;
public class FastjsonTest {
public static void main(String[] args) {
testListJson();
}
public static void testListJson(){
List<Student> list = new ArrayList<Student>();
Student student1 = new Student();
student1.setId(1);
student1.setName("m1");
student1.setAge(6);
Student student2 = new Student();
student2.setId(2);
student2.setName("m2");
student2.setAge(7);
list.add(student1);
list.add(student2);
String s = JSON.toJSONString(list);
System.out.println(s);
System.out.println("==============================");
List<Student> students = JSON.parseArray(s, Student.class);
for (Student student : students) {
System.out.println(student);
}
}
}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FastjsonTest {
public static void main(String[] args) {
testListJson();
}
public static void testListJson(){
Map<String,Student> map =new HashMap<String,Student>();
Student student1 = new Student();
student1.setId(1);
student1.setName("m1");
student1.setAge(6);
Student student2 = new Student();
student2.setId(2);
student2.setName("m2");
student2.setAge(7);
map.put("student1",student1);
map.put("student2",student2);
String s = JSON.toJSONString(map);
System.out.println(s);
System.out.println("==============================");
Map<String,Student> jsonObject = (Map) JSON.parseObject(s);
for (String key:jsonObject.keySet()){
System.out.println(key+":"+jsonObject.get(key));
}
}
}
可以在进行序列化时,自己定义特殊需求
JSON 的静态方法:toJSONString ()
方法参数:第一个为需要序列化的对象,第二个为 SerializerFeature 枚举类型的可变参数
SerializerFeature 枚举的常量,可以通过我们进行个性修改
SerializerFeature 属性
QuoteFieldNames 输出key时是否使用双引号,默认为true
UseSingleQuotes 使用单引号而不是双引号,默认为false
WriteMapNullValue 是否输出值为null的字段,默认为false
WriteEnumUsingToString Enum输出name()或者original,默认为false
UseISO8601DateFormat Date使用ISO8601格式输出,默认为false
WriteNullListAsEmpty List字段如果为null,输出为[],而非null
WriteNullStringAsEmpty 字符类型字段如果为null,输出为”“,而非null
WriteNullNumberAsZero 数值字段如果为null,输出为0,而非null
WriteNullBooleanAsFalse Boolean字段如果为null,输出为false,而非null
SkipTransientField 如果是true,类中的Get方法对应的Field是transient,序列化时将会被忽略。默认为true
SortField 按字段名称排序后输出。默认为false
WriteTabAsSpecial 把\t做转义输出,默认为false 不推荐
PrettyFormat 结果是否格式化,默认为false
WriteClassName 序列化时写入类型信息,默认为false。反序列化是需用到
DisableCircularReferenceDetect 消除对同一对象循环引用的问题,默认为false
WriteSlashAsSpecial 对斜杠’/’进行转义
BrowserCompatible 将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE 6,默认为false
WriteDateUseDateFormat 全局修改日期格式,默认为false。JSON.DEFFAULT_DATE_FORMAT = “yyyy-MM-dd”;JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat);
DisableCheckSpecialChar 一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false
NotWriteRootClassName 含义
BeanToArray 将对象转为array输出
WriteNonStringKeyAsString 含义
NotWriteDefaultValue 含义
BrowserSecure 含义
IgnoreNonFieldGetter 含义
WriteEnumUsingName 含义
该注解用于方法上,字段和参数上,都可在序列化和反序列化时进行特性定制
FastJson 中的注解 @JSONField,一般作用在 get/set 方法上面,常用的使用场景有下面三个:
修改和json字符串的字段映射【name】
格式化数据【format】
过滤掉不需要序列化的字段【serialize】
源码如下
放在实体类上就会只装配列举的字段或者排除列举的成员变量
属性
includes 要被序列化的字段
orders 要被序列化的顺序
serialzeFeatures 序列化时特性定义
源码
FastJson 利用 toJSONString 方法来序列化对象,而反序列化还原回 Object 的方法,主要的 API 有两个,分别是 JSON.parseObject 和 JSON.parse ,最主要的区别就是前者返回的是 JSONObject 而后者返回的是实际类型的对象,当在没有对应类的定义的情况下,通常情况下都会使用 JSON.parseObject 来获取数据,使用 SerializerFeature.WriteClassName 时 会在序列化中写入当前的 type, @type 可以指定反序列化任意类,调用其 set,get,is 方法。而问题恰恰出现在了这个特性,我们可以配合一些存在问题的类,然后继续操作,造成 RCE 的问题
但是由于 1.2.25 及之后的版本,fastjson 禁用了部分 autotype 的功能,也就是”@type” 这种指定类型的功能会被限制在一定范围内使用。所以需要我们主动增加白名单。
来源:http://blog.m1kael.cn/index.php/archives/598/
声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权!
(hack视频资料及工具)
(部分展示)
往期推荐
【精选】SRC快速入门+上分小秘籍+实战指南
爬取免费代理,拥有自己的代理池
漏洞挖掘|密码找回中的套路
渗透测试岗位面试题(重点:渗透思路)
漏洞挖掘 | 通用型漏洞挖掘思路技巧
干货|列了几种均能过安全狗的方法!
一名大学生的黑客成长史到入狱的自述
攻防演练|红队手段之将蓝队逼到关站!
巧用FOFA挖到你的第一个漏洞