Fastjsonfan反序列链学习前置知识
Fastjson前置知识
Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。
Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象
1、Fastjson基础用法
1.1、序列化与反序列基础用法
//序列化
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类
1.2、使用案例
实体类User
package com.akkacloud.pojo;
public class User {
public int id;
public String name;
public int age;
public User() {
}
public User(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
对象转字符串(序列化)
package com.akkacloud.pojo.demo;
import com.akkacloud.pojo.User;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
public class fastjsonTest {
public static void main(String[] args) {
User user = new User();
user.setId(1);
user.setName("zhangsan");
user.setAge(18);
//对象转字符串
String s1 = JSON.toJSONString(user);
String s2 = JSON.toJSONString(user, SerializerFeature.WriteClassName);
System.out.println(s1);
System.out.println(s2);
}
}
输出结果
{"age":18,"id":1,"name":"zhangsan"}
{"@type":"com.akkacloud.pojo.User","age":18,"id":1,"name":"zhangsan"}
字符串转对象(反序列化)
package com.akkacloud.pojo.demo;
import com.akkacloud.pojo.User;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
public class fastjsonTest {
public static void main(String[] args) {
User user = new User();
user.setId(1);
user.setName("zhangsan");
user.setAge(18);
//对象转字符串
String s1 = JSON.toJSONString(user);
String s2 = JSON.toJSONString(user, SerializerFeature.WriteClassName);
System.out.println(s1);
System.out.println(s2);
System.out.println("s1==========================s1");
//字符串转对象
Object o1 = JSON.parse(s1);
JSONObject jo1 = JSON.parseObject(s1);
User user1 = JSON.parseObject(s1, User.class);
System.out.println(o1);
System.out.println(jo1);
System.out.println(user1);
System.out.println("s2=========================s2");
Object o2 = JSON.parse(s2);
JSONObject jo2 = JSON.parseObject(s2);
User user2 = JSON.parseObject(s2, User.class);
System.out.println(o2);
System.out.println(jo2);
System.out.println(user2);
}
}
输出结果
{"age":18,"id":1,"name":"zhangsan"}
{"@type":"com.akkacloud.pojo.User","age":18,"id":1,"name":"zhangsan"}
s1==========================s1
{"name":"zhangsan","id":1,"age":18}
{"name":"zhangsan","id":1,"age":18}
User{id=1, name='zhangsan', age=18}
s2=========================s2
User{id=1, name='zhangsan', age=18}
{"name":"zhangsan","id":1,"age":18}
User{id=1, name='zhangsan', age=18}
我们对比使用SerializerFeature.WriteClassName的s2和不使用的s1,发现序列化时(对象转为字符串)多了一个字段@type,他指定了我们序列化的类,那么我们在反序列化时(字符串转对象)也会使用我们指定的@type字段所指定的类,进而调用set、get方法。这样我们就可以同在在@type指定我们的恶意类,造成代码执行,但是在序列化时不会调用我们的private修饰且没有get方法的属性。
我们修改User类的age为private属性并且删除其get方法试试,确实没有了age属性

为什么会执行set方法呢。
我们新建一个测试类看看
package com.fastjsontest.demo.pojo;
import java.io.IOException;
public class Evil {
private String cmd;
public Evil() {
System.out.println("Evil==constructor");
}
public Evil(String cmd) {
this.cmd = cmd;
System.out.println("Evilcmd==constructor");
}
public String getCmd() {
System.out.println("Evil==getter");
return cmd;
}
public void setCmd(String cmd) throws IOException {
System.out.println("Evil==setter");
this.cmd = cmd;
}
@Override
public String toString() {
return "Evil{" +
"cmd='" + cmd + '\'' +
'}';
}
}
调用输出来看看
package com.fastjsontest.demo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class test {
public static void main(String[] args) {
String cmdjson="{\"@type\":\"com.fastjsontest.demo.pojo.Evil\",\"cmd\":\"open /System/Applications/Calculator.app\"}";
Object parse = JSON.parse(cmdjson);
System.out.println("====================");
JSONObject jsonObject = JSON.parseObject(cmdjson);
System.out.println("====================");
Object o = JSON.parseObject(cmdjson, Object.class);
}
}
输出结果

可以看到只有jsonObject调用getter、setter方法和无参构造方法,其他两个未调用getter方法,具体分析看大佬的文章https://y4er.com/post/fastjson-learn/,这里不做分析。
1.3、恶意类实现执行代码
接下来我们尝试构造一个恶意的类Evil,再起set方法设置我们的恶意代码。
package com.fastjsontest.demo.pojo;
import java.io.IOException;
public class Evil {
private String cmd;
public Evil() {
}
public Evil(String cmd) {
this.cmd = cmd;
}
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) throws IOException {
Runtime.getRuntime().exec(cmd);
this.cmd = cmd;
}
@Override
public String toString() {
return "Evil{" +
"cmd='" + cmd + '\'' +
'}';
}
}
创建一个springboot项目
package com.fastjsontest.demo.controller;
import com.alibaba.fastjson.JSON;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class fastjsontest {
@RequestMapping("/fastjson")
@ResponseBody
public String cmd(@RequestParam(name="user") String user){
Object o = JSON.parseObject(user, Object.class);
System.out.println(o);
return o.getClass().getName();
}
}
访问http://127.0.0.1:8080/fastjson
post
user={"@type":"com.fastjsontest.demo.pojo.Evil","cmd":"open /System/Applications/Calculator.app"}

那么假设我们有一个可控的入口,如这里的fastjson的user参数,再找到一个利用链(这里是Evil的set方法)就可以造成远程代码执行了
1.4、结束
本章学习了Fastjson的基本用法,漏洞利用,下一章学习fastjson的利用链。
参考链接
https://y4er.com/post/fastjson-learn/
https://www.cnblogs.com/nice0e3/p/14601670.html#
Fastjsonfan反序列链学习前置知识的更多相关文章
- JDK7u21反序列链学习
JDK7u21 1.前置知识 jdk7u21是一条不依赖CommonsCollections库依赖的,看利用链所有知识其实跟CommonsCollections也有重复,我们来学习一下以前没学过的类或 ...
- CommonsCollection2反序列链学习
CommonsCollection2 1.前置知识 CmonnosCollection2需要用到Javassist和PriorityQueue 1.1.Javassist Javassist是一个开源 ...
- CommonsCollection6反序列化链学习
CommonsCollection6 1.前置知识 1.1.HashSet HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合.继承了序列化和集合 构造函数参数为空的话创建一 ...
- Java安全之Commons Collections1分析前置知识
Java安全之Commons Collections1分析前置知识 0x00 前言 Commons Collections的利用链也被称为cc链,在学习反序列化漏洞必不可少的一个部分.Apache C ...
- CommonsCollection4反序列化链学习
CommonsCollection4 1.前置知识 由于cc4没有新的知识点,主要是用cc2,然后稍微cc3结合了,所以我们可以看ysoserial源码,自己尝试构造一下,把cc2通过获取Invoke ...
- 学golang之前都需要哪些前置知识?
我学golang,感觉前面基础语法部分都很快能学会,但是到了goroutine,channel等后面的部分就看不懂了,是不是我学这个之前还得学习其他什么知识啊?(我有C语言基础,对于C语言里面的指针, ...
- CommonsCollection7反序列化链学习
CommonsCollections7 1.前置知识 Hashtable Hashtable实现了Map接口和Serializable接口,因此,Hashtable现在集成到了集合框架中.它和Hash ...
- GNU工具链学习笔记
GNU工具链学习笔记 1..so为动态链接库,.a为静态连接库.他们在Linux下按照ELF格式存储.ELF有四种文件类型.可重定位文件(Relocatable file,*.o,*.a),包含代码和 ...
- 欢迎关注我的微信公众账号:Linux技巧(微信号:irefactoring),一起学习Linux知识~~~
最近很少写博客了,一方面是近期工作比较繁忙,第二是把精力都放在GitHub和读源码去了. 申请了一个微信公众账号:Linux技巧 微信ID:irefactoring(意思是爱重构) ========= ...
随机推荐
- Spring——自动装配的三种实现方式
依赖注入的本质是装配,装配是依赖注入的具体行为 spring会在上下文中自动寻找,并自动给bean装配属性 自动装配的三种方式 (1).在xml中显式的装配 (2).在java中显式的装配 (3).隐 ...
- hdu5197 DZY Loves Orzing(FFT+分治)
hdu5197 DZY Loves Orzing(FFT+分治) hdu 题目描述:一个n*n的矩阵里填入1~n^2的数,要求每一排从前往后能看到a[i]个数(类似于身高阻挡视线那种),求方案数. 思 ...
- 网络编程-Python的netaddr库
In [1]: from netaddr import * In [2]: ip = IPAddress('172.16.100.39') ip.format()ip地址的格式化 '172.16. ...
- 什么是Spring MVC框架的控制器?
控制器提供一个访问应用程序的行为,此行为通常通过服务接口实现.控制器解析用户输入并将其转换为一个由视图呈现给用户的模型.Spring用一个非常抽象的方式实现了一个控制层,允许用户创建多种用途的控制器.
- 什么是 bean 装配?
装配,或 bean 装配是指在 Spring 容器中把 bean 组装到一起,前提是容器需要 知道 bean 的依赖关系,如何通过依赖注入来把它们装配到一起.
- 什么是通知(Advice)?
特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice.Spring AOP 使用一 个 Advice 作为拦截器,在 JoinPoint "周围"维护一系列 ...
- Qt的.pro文件格式解析
Qt的.pro文件格式解析 在Qt中用qmake生成makefile文件,它是由.pro文件生成而来的,.pro文件的具体格式语法如下: 1.注释 .pro文件中注释采用#号,从"#&quo ...
- asp.net 可视化操作(一)——asp.net安装与使用
目录 安装 创建网页 设计网页 运行 vs 2019安装asp.net 1.安装 打开vs,选择继续但无需代码 -->工具–>获取工具和功能 勾选如下选项后,点击关闭 点击更新等待安装完成 ...
- [C/C++基础知识] main函数的参数argc和argv
该篇文章主要是关于C++\C语言最基础的main函数的参数知识,是学习C++或C语言都必备的知识点.不知道你是否知道该知识?希望对大家有所帮助.一.main()函数参数通常我们在写主函数时都是void ...
- EDM响应式邮件框架:MJML
概述 新课题研究:响应式邮件框架MJML(MJML官网:https://mjml.io/)姐妹篇: EDM响应式邮件框架:Formerly Ink 介绍 MJML是一种标记语言,设计用于轻松实现一个响 ...