FastJson基础

FastJson基础

FastJson 简介

Fastjson 是 Alibaba 开发的 Java 语言编写的高性能 JSON 库,用于将数据在 JSON 和 Java Object 之间互相转换。

提供两个主要接口来分别实现序列化和反序列化操作。

JSON.toJSONString 将 Java 对象转换为 json 对象,序列化的过程。

JSON.parseObject/JSON.parse 将 json 对象重新变回 Java 对象;反序列化的过程

  • 所以可以简单的把 json 理解成是一个字符串

环境配置

  • JDK7u21
  • Fastjson 1.2.24
1
2
3
4
5
<dependency>  
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>

简单小demo

定义一个Person类,为其设置setter/getter方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com;

public class Person {
private String name;
private int age;

public Person() {
System.out.println("Person");
}

public int getAge() {
System.out.println("getAge");
return age;
}

public void setAge(int age) {
System.out.println("setAge");
this.age = age;
}

public String getName() {
System.out.println("getName");
return name;
}

public void setName(String name) {
System.out.println("setName");
this.name = name;
}
}

序列化

写一个序列化的代码,调用JSON.toJsonStirng()来序列化Person对象

1
2
3
4
5
6
7
8
9
10
public class JSONUser {
public static void main(String[] args) throws Exception {
String s = "{\"@type\":\"com.Person\",\"age\":18,\"name\":\"abc\"}";

Person person = new Person();
person.setAge(18);
String jsonString = JSON.toJSONString(person);
System.out.println(jsonString);
}
}

反序列化

写一个反序列化的代码,调用JSONObject.parseObject()来反序列化Person对象

(当需要还原出private的属性时,需要在JSON.parseObject/JSON.parse中加上Feature.SupportNonPublicField参,当然一般没人给私有属性加setter)

1
2
3
4
5
6
7
8
public class JSONUser {
public static void main(String[] args) throws Exception {
String s = "{\"@type\":\"com.Person\",\"age\":18,\"name\":\"abc\"}";

Object parse = JSON.parse(s);
System.out.println(parse);
}
}

小知识

Fastjson反序列化采用两个反序列化方法,分别为
  • JSON.parseObject()
  • JSON.parse()

parseObject():返回fastjsonJSONObject

parse():返回我们的类

下面我们可以看到,parseObject()返回parseObject类,而<font style="color:rgb(80, 80, 92);">parse()</font>返回我们的User类

但是可以通过在parseObject参数中传入类,达到和parse相同效果(也可以传入Student.class)

1
parseObject(input,Object.class)

Fastjson反序列化漏洞

fastjson在反序列化字符串时,会寻找@type中的类,在反序列化过程中会自动调用该类的setter和getter方法,但并不是所有getter和setter都会被调用

以下是满足条件的setter和getter的条件(可以根据源码分析出来,这里不多说了):

满足条件的setter

  • 非静态函数
  • 返回类型为void或当前类
  • 参数个数为1个

满足条件的getter

  • 非静态方法
  • 无参数
  • 返回值类型继承自Collection或Map或AtomicBoolean或AtomicInteger或AtomicLong

漏洞原理

Fastjson拥有自己的一套实现序列化和反序列化的机制,针对不同版本的Fastjson反序列化漏洞,原理都是一样的,只是针对不同黑名单的绕过利用

攻击者传入一个恶意构造的JSON字符串,Fastjson在反序列化字符串时,得到恶意类并执行恶意类的恶意函数,导致恶意代码执行

我们看之前的代码Demo,他会调用该类的 构造方法、getter、setter方法,若这些方法中存在危险方法的话,即存在Fastjson的 反序列化漏洞

1
2
String s = "{\"@type\":\"com.Person\",\"age\":18,\"name\":\"abc\"}";
Object parse = JSON.parse(s);

POC写法

一般Fastjson反序列化的POC写法如下
1
2
3
4
5
{
"@type":"xxx.xxx.xxx",
"xxx":"xxx",
...
}

小结

在学习过程中,发现fastjson的好多东西都没学到,回来重新学习一下,前两天有点忙,所以博客没来得及更新QAQ