Java反序列化:CommonsBeanutils无CC依赖下的反序列化调试分析

发布时间 2023-09-20 20:02:05作者: Icfh

基础知识

1. Apache Commons Beanutils

Apache Commons BeanUtils 是 Apache Commons 项目的一部分,它是一个用于简化 Java 对象的操作和属性访问的工具库。具体来说,它提供了一组用于操作 JavaBean 对象的工具和方法,使开发人员能够更容易地进行属性的复制、获取和设置等操作。

  • 本次涉及的相关类:Beancomparator
public class BeanComparator implements Comparator, Serializable {
    private String property;
    private Comparator comparator;

    public BeanComparator() {
        this((String)null);
    }

    public BeanComparator(String property) {
        this(property, ComparableComparator.getInstance());
    }

    public BeanComparator(String property, Comparator comparator) {
        this.setProperty(property);
        if (comparator != null) {
            this.comparator = comparator;
        } else {
            this.comparator = ComparableComparator.getInstance();
        }

    }

    public void setProperty(String property) {
        this.property = property;
    }

    public String getProperty() {
        return this.property;
    }

    public Comparator getComparator() {
        return this.comparator;
    }

    public int compare(Object o1, Object o2) {
        if (this.property == null) {
            return this.comparator.compare(o1, o2);
        } else {
            try {
                Object value1 = PropertyUtils.getProperty(o1, this.property);
                Object value2 = PropertyUtils.getProperty(o2, this.property);
                return this.comparator.compare(value1, value2);
            } catch (IllegalAccessException var5) {
                throw new RuntimeException("IllegalAccessException: " + var5.toString());
            } catch (InvocationTargetException var6) {
                throw new RuntimeException("InvocationTargetException: " + var6.toString());
            } catch (NoSuchMethodException var7) {
                throw new RuntimeException("NoSuchMethodException: " + var7.toString());
            }
        }
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        } else if (!(o instanceof BeanComparator)) {
            return false;
        } else {
            BeanComparator beanComparator = (BeanComparator)o;
            if (!this.comparator.equals(beanComparator.comparator)) {
                return false;
            } else if (this.property != null) {
                return this.property.equals(beanComparator.property);
            } else {
                return beanComparator.property == null;
            }
        }
    }

    public int hashCode() {
        int result = this.comparator.hashCode();
        return result;
    }
}
  • compare函数中涉及PropertyUtils,这是处理属性的一个相关类

image-20230920193952223

  • 关于compare函数的触发源自PriorityQueue在进行堆排序时,会自动调用compare函数

2. 关于JavaBean风格

在Java中,如果一个私有字段具有公开的读写方法,则称该class为JavaBean

(比如此例中的私有age参数,具有公开的getAge和setAge方法)

package JavaCode;
public class JavaBean {
    private int age;
    public int getAge(){
        return this.age;
    }
    public void setAge(int age){
        this.age = age;
    }  
}

读方法也被统一称为getter方法,写方法也被统一称为setter方法。

定义JavaBean风格方便了IDE的代码补全。

调试分析

Gadget Chain

/* Gadget Chain
	ObjectInputStream.readObject()
		PriorityQueue.readObject()
			PriorityQueue.heapify()
				BeanComparator.compare()
					PropertyUtils.getProperty()
						PropertyUtilsBean.getProperty()
							PropertyUtilsBean.getNestedProperty()
								PropertyUtilsBean.getrSimpleProperty()
									PropertyUtilsBean.invokeMethod()
										...
										TemplatesImpl动态加载恶意字节码
*/

调试过程

在进行PriorityQueue的readObject反序列化时,会进行一次堆排序,此时必然会触发compare函数。

  • 老惯例,先看下调用栈

image-20230920154430891

在PropertyUtilsBean中的getSimpleProperty中进行调用

image-20230920154830194

  • 首先进入compare函数,需要使用getter方法获取属性

image-20230920155151153

注意在TemplatesImpl中有这个私有字段

image-20230920155426519

  • 在调用getter方法后,首先创建对象实例,然后调用getter方法获取bean对象的name属性的值进行返回

image-20230920192112391

  • 然后进入后需要继续调用getNestedProperty()

image-20230920192231758

  • 经过种种判断之后进入了getSimpleProperty

image-20230920192910552

  • 最后调用了invokeMethod实现了TemplatesImpl的恶意字节码加载完成了CB1链的攻击

image-20230920192943445