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反序列链学习前置知识的更多相关文章

  1. JDK7u21反序列链学习

    JDK7u21 1.前置知识 jdk7u21是一条不依赖CommonsCollections库依赖的,看利用链所有知识其实跟CommonsCollections也有重复,我们来学习一下以前没学过的类或 ...

  2. CommonsCollection2反序列链学习

    CommonsCollection2 1.前置知识 CmonnosCollection2需要用到Javassist和PriorityQueue 1.1.Javassist Javassist是一个开源 ...

  3. CommonsCollection6反序列化链学习

    CommonsCollection6 1.前置知识 1.1.HashSet HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合.继承了序列化和集合 构造函数参数为空的话创建一 ...

  4. Java安全之Commons Collections1分析前置知识

    Java安全之Commons Collections1分析前置知识 0x00 前言 Commons Collections的利用链也被称为cc链,在学习反序列化漏洞必不可少的一个部分.Apache C ...

  5. CommonsCollection4反序列化链学习

    CommonsCollection4 1.前置知识 由于cc4没有新的知识点,主要是用cc2,然后稍微cc3结合了,所以我们可以看ysoserial源码,自己尝试构造一下,把cc2通过获取Invoke ...

  6. 学golang之前都需要哪些前置知识?

    我学golang,感觉前面基础语法部分都很快能学会,但是到了goroutine,channel等后面的部分就看不懂了,是不是我学这个之前还得学习其他什么知识啊?(我有C语言基础,对于C语言里面的指针, ...

  7. CommonsCollection7反序列化链学习

    CommonsCollections7 1.前置知识 Hashtable Hashtable实现了Map接口和Serializable接口,因此,Hashtable现在集成到了集合框架中.它和Hash ...

  8. GNU工具链学习笔记

    GNU工具链学习笔记 1..so为动态链接库,.a为静态连接库.他们在Linux下按照ELF格式存储.ELF有四种文件类型.可重定位文件(Relocatable file,*.o,*.a),包含代码和 ...

  9. 欢迎关注我的微信公众账号:Linux技巧(微信号:irefactoring),一起学习Linux知识~~~

    最近很少写博客了,一方面是近期工作比较繁忙,第二是把精力都放在GitHub和读源码去了. 申请了一个微信公众账号:Linux技巧 微信ID:irefactoring(意思是爱重构) ========= ...

随机推荐

  1. kafka 第一次小整理(草稿篇)————分发的基本思路[三]

    前言 简单整理一下分发的基本思路. 正文 kafka 原本是做日志管理系统,主要是分发这块的. 那么如何做分发呢? 分发的是什么呢? 分发的其实是日志,日志是事件状态,kafka 内部就叫做Recor ...

  2. Docker——容器数据卷

    为什么需要容器数据卷 角度:遇到问题,尝试以朴素的道理解决问题.问题复杂化,解决的方式也变得复杂 问题的提出:docker将应用和环境打包成一个镜像,但是对于容器内的数据,如果不进行外部的保存,那么当 ...

  3. 论文解读(SUGRL)《Simple Unsupervised Graph Representation Learning》

    Paper Information Title:Simple Unsupervised Graph Representation LearningAuthors: Yujie Mo.Liang Pen ...

  4. 西门子S7-1200PLC不让下载一直报“模块具有激活的测试和调试功能,防止下载到设备”解决方法

    错误如图 这是因为PLC被强制了,导致下载会报这类错误.取消强制就可以下载. 或者将cpu重置为出厂设置,也能再次下载. 参考:https://www.ad.siemens.com.cn/servic ...

  5. iOS全埋点解决方案-应用退出和启动

    前言 ​ 通过应用程序退出事件,可以分析应用程序的平均使用时长:通过应用程序的启动事件,可以分析日活和新增.我们可以通过全埋点方式 SDK 实现应用程序的退出和启动事件. 一.全埋点的简介 ​ 目前. ...

  6. 半吊子菜鸟学Web开发3 --Html css学习1

    1创建一个html文件,用vscode打开 首先输入一个! 然后就可以开始编辑html文件了 2 整体结构 <!DOCTYPE HTML><html>    <head& ...

  7. class文件和java文件区别

  8. spring学习一:spring入门及相关概念介绍

      1:Spring的概念:(03年兴起) (1)   开源的轻量级的框架(无需复杂的环境,不依赖其他) (2)   一站式框架(Spring在javaee的三层结构中,对每一层都提供不同的解决技术: ...

  9. C# winform自己的窗体不抢夺其他窗体的光标

    在你的form里加入: protected override CreateParams CreateParams { get { var result = base.CreateParams; ; r ...

  10. C++面试问题汇总

    作者:勿忘心安~~链接:https://www.nowcoder.com/discuss/197611来源:牛客网 1 C++基础: (1)多态是怎么样的?写个样例? https://www.cnbl ...