Fastjson反序列化漏洞基础
Fastjson反序列化漏洞基础
FastJson是alibaba的一款开源JSON解析库,可用于将Java对象转换为其JSON表示形式,也可以用于将JSON字符串转换为等效的Java对象。
0x0 简单使用
pom.xml加入FastJson
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>
新建一个User1类,注意这个类有两个属性age和name,并且其两个属性都有get/set方法:
package com.yy.FastJson.demo;
public class User1 {
private String name;
public User1() {
System.out.println("User()");
}
public String getName() {
System.out.println("getName()");
return name;
}
public void setName(String name) {
System.out.println("setName()");
this.name = name;
}
}
0x1 Fastjson的序列化
fastjson是用toJSONString方法来进行的序列化,使用方法:
package com.yy.FastJson.demo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
public class serialize {
public static void main(String[] args){
User student = new User();
student.setName("yangyang");
String st = JSON.toJSONString(student, SerializerFeature.WriteClassName);
System.out.println(st);
}
}
这里输出结果为:

可以看到在序列化成json字符串时候会调用get方法,而这里的SerializerFeature.WriteClassName是toJSONString()方法中的一个属性值,设置之后在序列化的时候会多写入一个@type,后面指定反序列化的类名
# 设置了SerializerFeature.WriteClassName属性
{"@type":"com.yy.FastJson.demo.User1","name":"yangyang"}
# 未设置SerializerFeature.WriteClassName属性
{"name":"yangyang"}
0x2 Fastjson的反序列化
在fastjson中,有三种方式进行反序列化:
JSON.parse(json)
JSON.parseObject(json)
JSON.parseObject(json, User.class)
新建一个unserialize类来理解这三个方法的区别:
package com.yy.FastJson.demo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class unserialize {
public static void main(String[] args){
String json ="{\"@type\":\"com.yy.FastJson.demo.User1\",\"name\":\"yangyang\"}";
System.out.println("parse(json)");
User1 obj01 = (User1)JSON.parse(json);
System.out.println(obj01);
System.out.println("--------------------------------------");
System.out.println("parseObject(json)");
JSONObject obj02 = JSON.parseObject(json);
System.out.println(obj02);
System.out.println("--------------------------------------");
System.out.println("parseObject(json, User.class)");
User1 obj03 = JSON.parseObject(json, User1.class);
System.out.println(obj03);
}
}
输出结果:
parse(json)
User()
setName()
com.yy.FastJson.demo.User1@6d21714c
--------------------------------------
parseObject(json)
User()
setName()
getName()
{"name":"yangyang"}
--------------------------------------
parseObject(json, User.class)
User()
setName()
com.yy.FastJson.demo.User1@5b80350b
可以看到,只有parseObject(json)调用了getName方法
其原因是因为parseObject(json) 本质上也是调用 parse(json) 进行反序列化的。但是 parseObject(json) 会额外的将Java对象转为 JSONObject对象,即 JSON.toJSON(),所以会多调用一个get方法
引出问题:是不是除了parseObject(json) ,其余两种方式是无法调用get方法的呢
新建一个User2,加入一个age方法,并且类型是Properties
import java.util.Properties;
public class User2 {
private String name;
private Properties age;
public User2() {
System.out.println("User()");
}
public String getName() {
System.out.println("getName()");
return name;
}
public void setName(String name) {
System.out.println("setName()");
this.name = name;
}
public Properties getAge() {
System.out.println("getAge()");
return age;
}
public Properties setAge() {
System.out.println("setAge()");
return age;
}
}
修改unserialize里面得User1成User2
package com.yy.FastJson.demo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class unserialize {
public static void main(String[] args){
String json ="{\"@type\":\"com.yy.FastJson.demo.User2\",\"name\":\"yangyang\",\"age\":{ }}";
System.out.println("parse(json)");
User2 obj01 = (User2)JSON.parse(json);
System.out.println(obj01);
System.out.println("--------------------------------------");
System.out.println("parseObject(json)");
JSONObject obj02 = JSON.parseObject(json);
System.out.println(obj02);
System.out.println("--------------------------------------");
System.out.println("parseObject(json, User.class)");
User2 obj03 = JSON.parseObject(json, User2.class);
System.out.println(obj03);
}
}
运行结果:
parse(json)
User()
setName()
getAge()
com.yy.FastJson.demo.User2@4459eb14
--------------------------------------
parseObject(json)
User()
setName()
getAge()
getAge()
getName()
{"name":"yangyang"}
--------------------------------------
parseObject(json, User.class)
User()
setName()
getAge()
com.yy.FastJson.demo.User2@4f2410ac
可以看到,所有的getAge方法都调用了一次。
这里除了parseObject(json)会直接调用getAge()外,其他两种方式调用getAge方法是有条件的。
条件一、方法名需要长于4
条件二、不是静态方法
条件三、以get字符串开头,且第四个字符需要是大写字母
条件四、方法不能有参数传入
条件五、继承自Collection || Map || AtomicBoolean || AtomicInteger ||AtomicLong
条件六、此getter不能有setter方法(程序会先将目标类中所有的setter加入fieldList列表,因此可以通过读取fieldList列表来判断此类中的getter方法有没有setter)
更详细的解析可以看看这篇文章:
https://www.anquanke.com/post/id/211035#h3-3
为了方便记忆,拿了一张大佬的图:

图片来源:https://www.cnblogs.com/sijidou/p/13121332.html?ivk_sa=1024320u
parseObject(json)会直接调用get方法,其他的则需要满足条件
所以,在反序列化的时候,会把目标类的构造函数、getter方法、setter方法、is方法执行,如果此时这四个方法中有危险操作,则会导致反序列化漏洞。
参考:
https://www.anquanke.com/post/id/211035#h2-5
https://blog.csdn.net/qq_34101364/article/details/111706189
Fastjson反序列化漏洞基础的更多相关文章
- Java安全之Fastjson反序列化漏洞分析
Java安全之Fastjson反序列化漏洞分析 首发:先知论坛 0x00 前言 在前面的RMI和JNDI注入学习里面为本次的Fastjson打了一个比较好的基础.利于后面的漏洞分析. 0x01 Fas ...
- Fastjson反序列化漏洞概述
Fastjson反序列化漏洞概述 背景 在推动Fastjson组件升级的过程中遇到一些问题,为帮助业务同学理解漏洞危害,下文将从整体上对其漏洞原理及利用方式做归纳总结,主要是一些概述性和原理上的东 ...
- fastjson反序列化漏洞研究(上)
前言 最近护网期间,又听说fastjson传出“0day”,但网上并没有预警,在github上fastjson库中也有人提问关于fastjson反序列化漏洞的详情.也有人说是可能出现了新的绕过方式.不 ...
- fastjson反序列化漏洞实际案例利用
fastjson反序列化rce实际案例利用全过程: 存在问题网站:http://***.com/ 在网站上寻找一些安全漏洞的时候,发现一条json数据包 数据包如下: POST /*** HTTP/1 ...
- Fastjson反序列化漏洞复现
Fastjson反序列化漏洞复现 0x00 前言 对Fastjson反序列化漏洞进行复现. 0x01 漏洞环境 靶机环境:vulhub-fastjson-1.2.24 ip:172.16.10.18 ...
- JAVA反序列化漏洞基础原理
JAVA反序列化漏洞基础原理 1.1 什么是序列化和反序列化? Java序列化是指把Java对象转换为字节序列的过程: Java反序列化是指把字节序列恢复为Java对象的过程: 1.2 为什么要序列化 ...
- Fastjson反序列化漏洞分析 1.2.22-1.2.24
Fastjson反序列化漏洞分析 1.2.22-1.2.24 Fastjson是Alibaba开发的Java语言编写的高性能JSON库,用于将数据在JSON和Java Object之间互相转换,提供两 ...
- .NET高级代码审计(第三课)Fastjson反序列化漏洞
0X00 前言 Java中的Fastjson曾经爆出了多个反序列化漏洞和Bypass版本,而在.Net领域也有一个Fastjson的库,作者官宣这是一个读写Json效率最高的的.Net 组件,使用内置 ...
- FastJson反序列化漏洞利用的三个细节 - TemplatesImpl的利用链
0. 前言 记录在FastJson反序列化RCE漏洞分析和利用时的一些细节问题. 1. TemplatesImpl的利用链 关于 parse 和 parseObject FastJson中的 pars ...
随机推荐
- Spring Cloud Gateway自定义异常处理Exception Handler
版本: Spring Cloud 2020.0.3 常见的方法有 实现自己的 DefaultErrorWebExceptionHandler 或 仅实现ErrorAttributes. 方法1: Er ...
- [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码
[洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...
- vulnhub靶机-XXE Lab 1
目录 信息收集 漏洞利用 信息收集 扫描目标主机,ip为192.168.88.154 nmap扫描结果 存在robots.txt文件.直接访问其中的admin.php显示404,加一层目录访问/xxe ...
- 雪花算法ID在前端丢失精度解决方案
首先说一下背景,目前笔者的工作是物联网方面的,设备有对应的智慧运营平台,平台开发中建表的主键用的是Mybatis plus默认的雪花算法来生成的,也就是分布式系统比较常用的雪花ID,技术栈就是常用的S ...
- MySQL:JDBC批量插入数据的效率
平时使用mysql插入.查询数据都没有注意过效率,今天在for循环中使用JDBC插入1000条数据居然等待了一会儿 就来探索一下JDBC的批量插入语句对效率的提高 首先进行建表 create tabl ...
- Linux 基础学习篇 序篇
读序篇可以知道的: 1.有些指令知道前和知道后,自己的操作是完全不同的,可能知道前,会用reset把系统重新启动一遍,而知道后会使用ps和kill来关闭进程. 2.如果对Linus的学习知识" ...
- (四)Linux之用户管理(用户和用户组)
Linux之用户管理(用户和用户组) 目录 Linux之用户管理(用户和用户组) 一.概述 二.用户和组的关系 三.关于UID和GID(用户ID和组ID) 四.用户和组的数据 /etc/passwd内 ...
- Python中用max()筛选出列表中出现次数最多的元素
1 List = [1,2,3,4,2,3,2] # 随意创建一个只有数字的列表 2 maxTimes = max(List,key=List.count) # maxTimes指列表中出现次数最多的 ...
- vue + iview 怎样在vue项目下添加ESLint
参考:https://segmentfault.com/a/1190000012019019?utm_source=tag-newest 使用iview框架的MenuGroup标签,vscode报红, ...
- .net core2.1 迁移.net core 3.1
1.解决方案->属性-->目标框架 .net core3.1 2.删除旧的Nuget包添加新的NuGet包 3.修改Startup.cs 修改ConfigureServices 修改Con ...