当前位置: 首页 > news >正文

Java安全—原生反序列化重写方法链条分析触发类

前言

在Java安全中反序列化是一个非常重要点,有原生态的反序列化,还有一些特定漏洞情况下的。今天主要讲一下原生态的反序列化,这部分内容对于没Java基础的来说可能有点难,包括我。

序列化与反序列化

序列化:将内存中的对象压缩成字节流
反序列化:将字节流转化成内存中的对象

简单来说就是把对象转换为字节流,方便存储在文件、数据库等。

Java里面常见的序列化与反序列化协议。

JAVA内置的writeObject()/readObject()
JAVA内置的XMLDecoder()/XMLEncoder
XStream
SnakeYaml
FastJson
Jackson

假如我要传输这一串代码,直接复制的话肯定不行,因为里面有大量的空格和换行,直接复制会出错的。所以就要用到序列化,把它加密成一串字节流进行传输,然后再反序列化解密还原成代码即可。

原生反序列化

Java新建一个项目,叫serialization。

随便选个版本即可。

创建一个user类,并写入代码。

再创建一个类叫serialization_demo,用来实现序列化操作的。简单来说代码就是把我们的user类里面的对象进行序列化操作,并且把结果写入ser.txt里面。

package com.sf.maven.serialization;public class serialization_demo {public static void main(String[] args) throws IOException {// 创建一个用户对象,引用UserDemouser u = new user("wlw", "gay", 30);// 调用方法进行序列化SerializableTest(u);// ser.txt 就是对象u序列化的字节流数据}public static void SerializableTest(Object obj) throws IOException {// 使用 ObjectOutputStream 将对象 obj 序列化后输出到文件 ser.txtObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.txt"));//序列化操作oos.writeObject(obj);// 关闭流oos.close();}
}

直接运行可以看到输入了我们的对象。

在旁边的目录下可以看到一个ser.txt文件,打开发现里面是字节流,这个ser.txt就是user对象序列化的结果。

我们再来试试反序列化,看看能不能把字节流还原。先创建一个类叫Unserialization_demo,写入以下代码,就是从ser.txt读取字节流,再反序列还原输出。

package com.sf.maven.serialization;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;public class Unserialization_demo {public static void main(String[] args) throws IOException, ClassNotFoundException {// 调用下面的方法,传输 ser.txt,解析还原反序列化Object obj = UnserializableTest("ser.txt");// 对 obj 对象进行输出,默认调用原始对象的 toString 方法System.out.println(obj);}// 反序列化方法public static Object UnserializableTest(String Filename) throws IOException, ClassNotFoundException {// 读取 Filename 文件进行反序列化还原ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));Object o = ois.readObject();// 返回反序列化后的对象return o;}}

直接运行好吧,可以看到输出了对象数据。

这就是原生的序列化和反序列化操作,就是把数据转换成字节流然后再封装成一个文件,然后再还原。

重写方法

OK,那么现在我们来讲一下怎么利用这个玩意,我们可以看到readObject()这个方法是来自ObjectinputStream.java这个文件。

而这个Java文件是来自src.zip里面,是我们JDK自带的东西。

现在我们来重写这个readObject这个方法,什么意思呢,就是当我们进行反序列化的时候不是会调用JDK自带的readObject()吗,那现在我们自己写一个readObject方法,让它在进行反序列的时候去调用我们自己写的readObject,而不是调用JDK自带的readObject。

在我们的user类里面加入重写readObject的代码,就是命令执行计算机。

重新对user进行序列化,生成新的ser.txt文件。

再对ser.txt进行反序列化,成功弹出了计算机!!!说明我们重写的方法有用,在反序列化的时候它执行的是user里面我们自己写的readObject,而不是JDK自带的。

我们来步入跟进一下代码,为了直观我们在readObject添加一行代码。

设置一个断点进行调试。

点击步入可以看到此时的Filename等于我们的ser.txt。

继续步入,执行到我们的ObjectInputStream读取文件这里。

接着步入跳到了ObjectInputStream.java类这里。

此时我们步出回到了这里。

接着步入,让它调用readObject。

关键的来了,此时我们再步入的话,跳转到了我们的user.java里面的readObject,而不是ObjectinputStream里面的readObject。

toString

上面我们说的方法是属于入口类的readObject危险方法直接调用(我也没搞懂为啥叫这个名字),还有方法就是—构造函数/静态代码块等类加载时隐式执行,说实话好绕口啊。其实我感觉两个都差不多,我们先在user里面重写一下toString。

把我们上面重写的readObject注释掉,重新序列化生成一个ser.txt。

再执行反序列化代码,对ser.txt还原,此时也弹出了计算机。

这是为啥,原来当我们用System.out.println()进行输出的时候,会默认调用toString方法,而toString我们上面添加了启动计算机的命令代码。

HashMap

还有就是如果我们使用的类里面自带readObject方法会不会触发呢,HashMap这个类里面就自带readObject,我们用它试一下。先创建一个类叫HashMap_demo,写入以下代码,就是对hash这个对象进行序列化并输出到url.txt,然后再反序列化。

package com.sf.maven.serialization;
import java.io.*;
import java.net.URL;
import java.util.HashMap;public class HashMap_demo implements Serializable {public static void main(String[] args) throws IOException, ClassNotFoundException{HashMap<URL, Integer> hash = new HashMap<>();URL u = new URL("dnslog地址");hash.put(u, 1);//序列化SerializableTest(hash);//反序列化//UnserializableTest("url.txt");}public static void SerializableTest(Object obj) throws IOException {// 使用 ObjectOutputStream 将对象 obj 序列化后输出到文件 url.txtObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("url.txt"));//序列化操作oos.writeObject(obj);oos.close();}public static Object UnserializableTest(String Filename) throws IOException, ClassNotFoundException {// 读取 Filename 文件进行反序列化还原ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));Object o = ois.readObject();return o;}
}

直接运行代码先序列化生成一个url.txt。

接着对url.txt进行反序列,可以看到dnslog有回显,说明代码对dnslog进行了解析。

这是咋回事呢,直接来看一下这个利用链。我们引用了HashMap —> readObject本来在ObjectInputStream里面 —> 但是HashMap里面也有readObject —> 所以在反序列化的时候调用的是HashMap的readObject,而不是ObjectInputStream的readObject—>触发HashMap.putVal() —> 触发HashMap.hash() —> 最终触发URL.hashCode()去访问我们dnslog地址。

如果把dnslog地址换成命令,不就是RCE漏洞了吗,这种就是入口参数包含可控类,改类有危险方法,readObject时调用。

总结

虽然今天的内容看起来有点复杂,但总结起来就一件事,想办法调用其它的readObject,而不是去调用原本的readObject。

最后还是要声明一下,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。

相关文章:

Java安全—原生反序列化重写方法链条分析触发类

前言 在Java安全中反序列化是一个非常重要点&#xff0c;有原生态的反序列化&#xff0c;还有一些特定漏洞情况下的。今天主要讲一下原生态的反序列化&#xff0c;这部分内容对于没Java基础的来说可能有点难&#xff0c;包括我。 序列化与反序列化 序列化&#xff1a;将内存…...

2023考研王道计算机408数据结构+操作系统+计算机组成原理+计算机网络

from: https://blog.csdn.net/weixin_46118419/article/details/125611299 写得很好&#xff01; 轻重缓急 2023考研计算机408【王-道计算机408】数据结构操作系统计算机组成原理计算机网络 网盘-链接&#xff1a;https://pan.baidu.com/s/13JraxUYwNVPeupdzprx5hA?pwd5h3d 提…...

YOLOv8-ultralytics-8.2.103部分代码阅读笔记-files.py

files.py ultralytics\utils\files.py 目录 files.py 1.所需的库和模块 2.class WorkingDirectory(contextlib.ContextDecorator): 3.def spaces_in_path(path): 4.def increment_path(path, exist_okFalse, sep"", mkdirFalse): 5.def file_age(path__fi…...

「Mac畅玩鸿蒙与硬件34」UI互动应用篇11 - 颜色选择器

本篇将带你实现一个颜色选择器应用。用户可以从预设颜色中选择&#xff0c;或者通过输入颜色代码自定义颜色来动态更改界面背景。该应用展示了如何结合用户输入、状态管理和界面动态更新的功能。 关键词 UI互动应用颜色选择器状态管理用户输入界面动态更新 一、功能说明 颜色…...

ELK(Elasticsearch + logstash + kibana + Filebeat + Kafka + Zookeeper)日志分析系统

文章目录 前言架构软件包下载 一、准备工作1. Linux 网络设置2. 配置hosts文件3. 配置免密登录4. 设置 NTP 时钟同步5. 关闭防火墙6. 关闭交换分区7. 调整内存映射区域数限制8. 调整文件、进程、内存资源限制 二、JDK 安装1. 解压软件2. 配置环境变量3. 验证软件 三、安装 Elas…...

07.ES11 08.ES12

7.1、Promise.allSettled 调用 allsettled 方法&#xff0c;返回的结果始终是成功的&#xff0c;返回的是promise结果值 <script>//声明两个promise对象const p1 new Promise((resolve, reject) > {setTimeout(() > {resolve("商品数据 - 1");}, 1000)…...

linux一键部署apache脚本

分享一下自己制作的一键部署apache脚本&#xff1a; 脚本已和当前文章绑定&#xff0c;请移步下载&#xff08;免费&#xff01;免费&#xff01;免费&#xff01;&#xff09; &#xff08;单纯的分享&#xff01;&#xff09; 步骤&#xff1a; 将文件/内容上传到终端中 …...

2022 年 6 月青少年软编等考 C 语言三级真题解析

目录 T1. 制作蛋糕思路分析T2. 找和最接近但不超过K的两个元素思路分析T3. 数根思路分析T4. 迷信的病人思路分析T5. 算 24思路分析T1. 制作蛋糕 小 A 擅长制作香蕉蛋糕和巧克力蛋糕。制作一个香蕉蛋糕需要 2 2 2 个单位的香蕉, 250 250 250 个单位的面粉, 75 75 75 个单位的…...

MySQL - Why Do We Need a Thread Pool? - mysql8.0

MySQL - Why Do We Need a Thread Pool? - mysql8.0 本文主要由于上次写的感觉又长又臭&#xff0c; 感觉学习方法有问题&#xff0c; 我们这次直接找来了 thread pool 的原文&#xff0c;一起来看看官方的开发者给出的blog – 感觉是个大神 但是好像不是最官方的 &#xff0c…...

Linux互斥量读写锁

一、互斥量 1.临界资源 同一时刻只允许一个进程/线程访问的共享资源&#xff08;比如文件、外设打印机&#xff09; 2.临界区 访问临界资源的代码 3.互斥机制 mutex互斥锁&#xff0c;用来避免临界资源的访问冲突&#xff0c;访问临界资源前申请互斥锁&#xff0c;访问完释放…...

网络安全之IP伪造

眼下非常多站点的涉及存在一些安全漏洞&#xff0c;黑客easy使用ip伪造、session劫持、xss攻击、session注入等手段危害站点安全。在纪录片《互联网之子》&#xff08;建议搞IT的都要看下&#xff09;中。亚伦斯沃茨&#xff08;真实人物&#xff0c;神一般的存在&#xff09;涉…...

ARM CCA机密计算安全模型之硬件强制安全

安全之安全(security)博客目录导读 [要求 R0004] Arm 强烈建议所有 CCA 实现都使用硬件强制的安全(CCA HES)。本文件其余部分假设系统启用了 CCA HES。 CCA HES 是一个可信子系统的租户——一个 CCA HES 主机(Host),见下图所示。它将以下监控安全域服务从应用处理元件(P…...

【论文笔记】A Token-level Contrastive Framework for Sign Language Translation

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: A Token-level Contrastiv…...

C#窗体简单登录

创建一个Windows登录程序&#xff0c;创建两个窗体&#xff0c;一个用来登录&#xff0c;一个为欢迎窗体&#xff0c;要求输入用户名和密码&#xff08;以个人的姓名和学号分别作为用户名和密码&#xff09;&#xff0c;点击【登录】按钮登录&#xff0c;登录成功后显示欢迎窗体…...

基于ZYNQ-7000系列的FPGA学习笔记3——开发环境搭建点亮一个LED

基于ZYNQ-7000系列的FPGA学习笔记3——开发环境搭建&点亮一个LED 1. 搭建开发环境2. FPGA的开发流程3. 点亮一个LED3.1 实验要求3.2 新建工程3.3 原理图3.4 绘制系统框图3.5 绘制波形图3.6 编写RTL代码3.7 软件仿真3.8 Vivado软件创建工程3.9 分析与综合3.10 设计实现 在上…...

队列-链式描述(C++)

定义 使用链表描述队列时&#xff0c;通常包含以下几个基本要素&#xff1a; 队头指针&#xff08;Front Pointer&#xff09;&#xff1a;指向队列中第一个&#xff08;即最早进入队列的&#xff09;元素的节点。队尾指针&#xff08;Rear Pointer&#xff09;&#xff1a;指…...

Kali Linux使用Netdiscover工具的详细教程

Kali Linux使用Netdiscover工具的详细教程 引言 在网络安全和渗透测试的过程中&#xff0c;网络发现是一个至关重要的步骤。Netdiscover是Kali Linux中一个非常实用的网络发现工具&#xff0c;它可以帮助用户快速识别局域网中的活动设备。本文将详细介绍如何使用Netdiscover工…...

arkTS:使用ArkUI实现用户信息的持久化管理与自动填充(PersistentStorage)

arkUI&#xff1a;使用ArkUI实现用户信息的持久化管理与自动填充&#xff08;PersistentStorage&#xff09; 1 主要内容说明2 例子2.1 登录页2.1.1登陆页的相关说明2.1.1.1 持久化存储的初始化2.1.1.2 输入框2.1.1.3 记住密码选项2.1.1.4 登录按钮的逻辑2.1.1.5 注册跳转 2.1.…...

IntelliJ+SpringBoot项目实战(二十)--基于SpringSecurity实现Oauth2服务端和客户端

在前面的帖子中介绍了SpringSecurityJWT实现了认证和授权的功能。因为基于Oauth2的统一认证在项目需求中越来越多&#xff0c;所以有必要将OAuth2的解决方案也整合进来&#xff0c;这样我们的产品既可以作为一个业务系统&#xff0c;也可以作为一个独立的统一认证服务器。下面详…...

如何实现剪裁功能

文章目录 1 概念介绍2 使用方法2.1 ClipOval2.2 ClipRRect3 示例代码我们在上一章回中介绍了AspectRatio Widget相关的内容,本章回中将介绍剪裁类组件(Clip).闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的剪裁类组件主要是指对子组件进行剪裁操作,常用的…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...