Java
  • About This Book
  • 🍖Prerequisites
    • 反射
      • 反射基本使用
      • 高版本JDK反射绕过
      • 反射调用命令执行
      • 反射构造HashMap
      • 方法句柄
    • 类加载
      • 动态加载字节码
      • 双亲委派模型
      • BCEL
      • SPI
    • RMI & JNDI
      • RPC Intro
      • RMI
      • JEP 290
      • JNDI
    • Misc
      • Unsafe
      • 代理模式
      • JMX
      • JDWP
      • JPDA
      • JVMTI
      • JNA
      • Java Security Manager
  • 👻Serial Journey
    • URLDNS
    • SerialVersionUID
    • Commons Collection 🥏
      • CC1-TransformedMap
      • CC1-LazyMap
      • CC6
      • CC3
      • CC2
    • FastJson 🪁
      • FastJson-Basic Usage
      • FastJson-TemplatesImpl
      • FastJson-JdbcRowSetImpl
      • FastJson-BasicDataSource
      • FastJson-ByPass
      • FastJson与原生反序列化(一)
      • FastJson与原生反序列化(二)
      • Jackson的原生反序列化利用
    • Other Components
      • SnakeYaml
      • C3P0
      • AspectJWeaver
      • Rome
      • Spring
      • Hessian
      • Hessian_Only_JDK
      • Kryo
      • Dubbo
  • 🌵RASP
    • JavaAgent
    • JVM
    • ByteCode
    • JNI
    • ASM 🪡
      • ASM Intro
      • Class Generation
      • Class Transformation
    • Rasp防御命令执行
    • OpenRASP
  • 🐎Memory Shell
    • Tomcat-Architecture
    • Servlet API
      • Listener
      • Filter
      • Servlet
    • Tomcat-Middlewares
      • Tomcat-Valve
      • Tomcat-Executor
      • Tomcat-Upgrade
    • Agent MemShell
    • WebSocket
    • 内存马查杀
    • IDEA本地调试Tomcat
  • ✂️JDBC Attack
    • MySQL JDBC Attack
    • H2 JDBC Attack
  • 🎨Templates
    • FreeMarker
    • Thymeleaf
    • Enjoy
  • 🎏MessageQueue
    • ActiveMQ CNVD-2023-69477
    • AMQP CVE-2023-34050
    • Spring-Kafka CVE-2023-34040
    • RocketMQ CVE-2023-33246
  • 🛡️Shiro
    • Shiro Intro
    • Request URI ByPass
    • Context Path ByPass
    • Remember Me反序列化 CC-Shiro
    • CB1与无CC依赖的反序列化链
  • 🍺Others
    • Deserialization Twice
    • A New Blazer 4 getter RCE
    • Apache Commons Jxpath
    • El Attack
    • Spel Attack
    • C3P0原生反序列化的JNDI打法
    • Log4j
    • Echo Tech
      • SpringBoot Under Tomcat
    • CTF 🚩
      • 长城杯-b4bycoffee (ROME反序列化)
      • MTCTF2022(CB+Shiro绕过)
      • CISCN 2023 西南赛区半决赛 (Hessian原生JDK+Kryo反序列化)
      • CISCN 2023 初赛 (高版本Commons Collections下其他依赖的利用)
      • CISCN 2021 总决赛 ezj4va (AspectJWeaver写字节码文件到classpath)
      • D^3CTF2023 (新的getter+高版本JNDI不出网+Hessian异常toString)
      • WMCTF2023(CC链花式玩法+盲读文件)
      • 第六届安洵杯网络安全挑战赛(CB PriorityQueue替代+Postgresql JDBC Attack+FreeMarker)
  • 🔍Code Inspector
    • CodeQL 🧶
      • Tutorial
        • Intro
        • Module
        • Predicate
        • Query
        • Type
      • CodeQL 4 Java
        • Basics
        • DFA
        • Example
    • SootUp ✨
      • Intro
      • Jimple
      • DFA
      • CG
    • Tabby 🔦
      • install
    • Theory
      • Static Analysis
        • Intro
        • IR & CFG
        • DFA
        • DFA-Foundation
        • Interprocedural Analysis
        • Pointer Analysis
        • Pointer Analysis Foundation
        • PTA-Context Sensitivity
        • Taint Anlysis
        • Datalog
Powered by GitBook
On this page
  • 0x01 What Is FastJson
  • 0x02 Basic Usage

Was this helpful?

  1. 👻Serial Journey
  2. FastJson 🪁

FastJson-Basic Usage

0x01 What Is FastJson

fastjson 是阿里巴巴的开源 JSON 解析库,支持将 Java Bean 序列化为 JSON 字符串,也可以从 JSON 字符串反序列化到 JavaBean。顾名思义,FastJson的特点就是快。

0x02 Basic Usage

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.23</version>
</dependency>

POJO => JSON

JSON.toJSONString()

参数设置:

  • SerializerFeature.WriteClassName

    序列化时,会多出一个@type跟上类名

package org.example;

public class Person {
    public String name;
    public Integer age;

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

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

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

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

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public Person(){
        System.out.println("Non-Arg Constructor");
    }

    @Override
    public String toString() {
        return "I am " + this.name + " and " + this.age + " years old";
    }
}
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.example.Person;

public class Test {
    public static void main(String[] args) {
        Person person1 = new Person("Tom", 18);
        String str1 = JSON.toJSONString((person1));
        System.out.println(str1);

        Person person2 = new Person("Lisa", 20);
        String str2 = JSONObject.toJSONString(person2, SerializerFeature.WriteClassName);
        System.out.println(str2);
    }
}

getAge

getName

{"age":18,"name":"Tom"}

getAge

getName

{"@type":"org.example.Person","age":20,"name":"Lisa"}

JSON => POJO

JSON.parseObject()

参数设置:

  • Feature.SupportNonPublicField 反序列化时,加上该参数才能还原private属性

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import org.example.Person;

public class Test {
    public static void main(String[] args) {
        Person person = JSON.parseObject("{\"@type\":\"org.example.Person\",\"age\":20,\"name\":\"Lisa\"}", Person.class, Feature.SupportNonPublicField);
        System.out.println(person);
    }
}

Non-Arg Constructor

setAge

setName

I am Lisa and 20 years old

parse vs parseObject

import com.alibaba.fastjson.JSON;

public class Test {
    public static void main(String[] args) {
        String s = "{\"@type\":\"org.example.Person\",\"age\":20,\"name\":\"Lisa\"}";
        Object obj1 = JSON.parse(s);
        System.out.println(obj1);
        Object obj2 = JSON.parseObject(s);
        System.out.println(obj2);
    }
}

Non-Arg Constructor

setAge

setName

I am Lisa and 20 years old

Non-Arg Constructor

setAge

setName

getAge

getName

{"name":"Lisa","age":20}

可以看到JSON.parseObject()的打印结果和我们定义的toString()不同,说明它不是Person对象。(实际上得到的是JSONObject类对象)

结论:

  • parse()会识别并调用目标类的setter方法

  • parseObject()会触发目标类的getter和setter方法

因此若能找到一个类、在反序列化这个类对象时,fastjson调用其setter或getter方法,且setter或getter方法存在漏洞,可以执行恶意代码。

下面再列举一些FastJson的结论,在后续调试中可以观察得到:

  • JSON.parse(jsonString) 和 JSON.parseObject(jsonString, Target.class),前者会在 jsonString 中解析字符串获取 @type 指定的类,后者则会直接使用参数中的class。

  • JSON.parseObject(jsonString) 将会返回 JSONObject 对象,且类中的所有 getter 与setter 都被调用。

  • 如果目标类中私有变量没有 setter 方法,但是在反序列化时仍想给这个变量赋值,则需要使用 Feature.SupportNonPublicField 参数。

  • fastjson 在反序列化时,如果 Field 类型为 byte[],将会调用com.alibaba.fastjson.parser.JSONScanner#bytesValue 进行 base64 解码,对应的,在序列化时也会进行 base64 编码。

  • fastjson 在为类属性寻找 get/set 方法时,调用函数 com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#smartMatch() 方法,会忽略 _|- 字符串,假如字段名叫 _a_g_e_,getter 方法为 getAge(),fastjson 也可以找得到。

配置类:

com.alibaba.fastjson.parser.ParserConfig:后面的AutoType开关和黑名单体现在这个类中

满足条件的setter:

  • 函数名大于等于4

  • 非静态函数

  • 以set开头且第4个字母为大写

  • 返回类型为void或当前类

  • 参数个数为1个

满足条件的getter

  • 函数名长度大于等于4

  • 非静态方法

  • 以get开头且第4个字母为大写

  • 无参数

  • 返回值类型继承自Collection或Map或AtomicBoolean或AtomicInteger

PreviousFastJson 🪁NextFastJson-TemplatesImpl

Last updated 1 year ago

Was this helpful?