反序列化底层学习

反序列化底层学习

前言

以前也是懒得学,觉得没有必要,学到现在发现好多东西都需要学习java的底层,而且很多漏洞都是通过反序列化底层挖出来的,比如weblogic的一些绕过,我这里也主要是为了学习weblogic来学习的,所以一些细节不关注

DEMO

import java.io.*;
public class Main {public static class Demo implements Serializable {transient String name;public Demo(String name) {this.name = name;}public static void main(String[] args) throws IOException, ClassNotFoundException {Demo demo = new Demo("nn0nkey");ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("panda.out"));outputStream.writeObject(demo);outputStream.close();ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("panda.out"));inputStream.readObject();}}
}

反序列化分析

一般我们就知道反序列化会调用readobject方法,现在就好好分析一下readobject干了啥

首先判断是不是重载类型的,如果不是调用Object obj = readObject0(false);去恢复对象

image-20240625165822881

readObject0方法会对不同的类型进行不同的处理,我这里是object类型的

image-20240625170446323

readOrdinaryObject(unshared)我们继续看看是怎么处理的

内部调用ObjectStreamClass desc = readClassDesc(false);去读取我们的序列化流的描述信息,跟进

可以看到也是按照不同的类型去处理,有null,引用类型,代理类型,class类型

image-20240625170657019

我们进入到class类型

return readNonProxyDesc(unshared);

先进行一个检查是不是class类型,然后实例化一个desc对象,desc的信息是通过readClassDescriptor读取的

image-20240625170852928

跟进readClassDescriptor

image-20240625171409862

跟进readNonProxy

这个方法是真正意义上的操作

系统会先从字节流中读取类名信息name = in.readUTF();,其次从字节流中读取serialVersionUID的信息,然后再从字节流中读取各种SC_*标记信息,通过该标记信息设置对应的成员属性,最后从字节流中读取每一个字段的信息这些字段信息包括:TypeCodefieldNamefieldType

这里对应的方法是在序列化时使用的writeNonProxy方法,在writeNonProxy中写入的TypeCodefieldNamefieldType在这里被读取。

然后回到我们的readNonProxyDesc,封装好我的信息之后使用resolveClass(readDesc)处理为class

image-20240625171853201

resolveClass就是使用class.forname去加载

image-20240625171912221

image-20240625172542804

然后调用initNonProxy处理读取到的信息初始化

最后返回desc对象

image-20240625172627608

回到readOrdinaryObject方法

关键在

image-20240625172436903

做了一个判断desc.isExternalizable,如果序列化的接口是Externalizable类型,就进入readExternalData,否则进入readSerialData

如果我们的demo对象接口类型是Serializable,所以进入了readSerialData方法

readSerialData方法中用了反射进行调用反序列化对象的readObject方法

image-20210811104910320

然后回到readSerialData,会反射调用readResolve方法

image-20210811105200717

20201027155537-cca7961c-1829-1

总结

那么多read方法,我们总结一下

readobject:单纯的入口点

readobject0:可以说是我们的readobject方法的具体逻辑点,会跟进不同的字节流选择不同的方法去处理

readOrdinaryObject:用来处理我们的object对象类型的,它用于调用序列化类中,readObject、readResolve、readExternal的方法会有一些选择

readClassDesc :分发用于处理字节流中TC_CLASSDESC的方法,用switch来选择需要处理的方法

readNonProxyDesc :真正用来处理字节流中的TC_CLASSDESC方法,会调用resolveClass进行创建反序列化的对象

resolveClass:是用Class.forName来创建对象的地方,在这里可以做一个检查校验,用于反序列化拦截。

readNonProxy:真正读取我们描述信息的方法

参考

https://www.cnblogs.com/yyhuni/p/15127416.html

https://www.cnblogs.com/yyhuni/p/15127416.html

eadNonProxy:真正读取我们描述信息的方法

参考

https://www.cnblogs.com/yyhuni/p/15127416.html

https://www.cnblogs.com/yyhuni/p/15127416.html

https://www.cnblogs.com/yyhuni/p/15127416.html

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

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

相关文章

Linux CentOS 环境 MySQL 主从复制集群搭建

环境说明 MySQL版本8.4.0 操作系统 Linux CentOS 7.9 官网文档 https://dev.mysql.com/doc/refman/8.4/en/replication-configuration.html 以下代码片段中带分号都是在MySQL命令行( mysql -uroot -p)中执行 1. 首先在两个节点上安装数据库 参考 Linux CentOS安装MySQL8.0 …

【09】持久化-区块链的遍历

1. 区块链的遍历 1.1 创建区块链迭代器类型 区块链迭代器struct包含了当前区块的hash,数据库对象。 // 定义迭代器类型 type BlockchainIterator struct {currentHash []byte // 当前区块的hashdb *bolt.DB // 区块链数据库地址 } 1.2 为迭代器添…

Nginx调度器

Nginx反向代理 反向代理架构 部署后端Web1服务器 部署后端Web2服务器 配置Nginx服务器,添加服务器池,实现反向代理功能 proxy主机安装nginx 修改/usr/local/nginx/conf/nginx.conf配置文件 重新加载配置 客户端使用火狐浏览器或curl多次访问p…

【C++进阶学习】第四弹——多态——迈向C++更深处的关键一步

前言: 在前面我们已经学习了C中继承的相关知识,已经体会到C在与C语言的对比中的便捷性,但是有一些问题并没有被解决,比如继承中如何使不同的派生类公用基类的一个函数,这就需要多态的知识,而且,…

boost asio异步服务器(4)处理粘包问题tlv

粘包的产生 当客户端发送多个数据包给服务器时,服务器底层的tcp接收缓冲区收到的数据为粘连在一起的。这种情况的产生通常是服务器端处理数据的速率不如客户端的发送速率的情况。比如:客户端1s内连续发送了两个hello world!,服务器过了2s才接…

正版软件 | Copywhiz 6:革新您的文件复制、备份与管理体验

在数字化时代,文件管理的效率直接影响到我们的生产力。Copywhiz 6 最新版本,带来了前所未有的文件处理能力,让复制、备份和组织文件变得轻而易举。 智能选择,只复制更新内容 Copywhiz 6 的智能选择功能,让您只需几次点…

学习js带有返回值的函数笔记

今天在写一个带有返回值的函数时遇到一个执行顺序的问题,查了半天资料才发现问题 js代码 function myFunction(a, b) {return a * b; }document.getElementById("myFunction").innerHTML myFunction(4, 4);html代码(这是能正确运行出结果的…

【PA交易】BackTrader: 讨论下分析器和评测指标

前言 BackTrader的分析器主要使用的是analyzers模块,我们可以从Analyzers - Backtrader找到一个非常简单的示例。这个示例中使用方式很简单,其他分析器也可以通过如此简单封装方式进行装载。如果仅是复制粘贴官方教程,完全是制造互联网垃圾…

Netty学习(一)——基础组件

根据黑马程序员netty视频教程学习所做笔记。 笔记demo:https://gitee.com/jobim/netty_learn_demo.git 参考博客:https://blog.csdn.net/cl939974883/article/details/122550345 一、概述 1.1 什么是Netty Netty is an asynchronous event-driven netw…

Redis-哨兵模式-主机宕机-推选新主机的过程

文章目录 1、为哨兵模式准备配置文件2、启动哨兵3、主机6379宕机3.4、查看sentinel控制台日志3.5、查看6380主从信息 4、复活63794.1、再次查看sentinel控制台日志 1、为哨兵模式准备配置文件 [rootlocalhost redis]# ll 总用量 244 drwxr-xr-x. 2 root root 150 12月 6 2…

label studio数据标注平台的自动化标注使用

(作者:陈玓玏) 开源项目,欢迎star哦,https://github.com/tencentmusic/cube-studio 做图文音项目过程中,我们通常会需要进行数据标注。label studio是一个比较好上手的标注平台,可以直接搜…

如何关闭win10音量调节时 左上角出现的黑框

目录 1.谷歌浏览器: 2.edge浏览器: 3.没得办法的办法: 4.官方回复: 1.谷歌浏览器: 把这行地址chrome://flags/#hardware-media-key-handling 输入到chrome的地址栏里,回车,把黄色里的Hardwa…

突出显示列,重点内容一目了然!

老师在发布查询时,希望学生家长一眼就能看到重要的信息,应该如何设置? 易查分的新功能:突出显示列,就可以轻松实现!老师可以个性化设置突出显示列的样式,包括颜色、字体大小、隐藏标题等&#x…

P2实验室装修标准都有哪些

P2实验室(也称为生物安全二级实验室,BSL-2实验室)的装修标准需要满足一系列的设计和施工要求,以确保实验室的安全性和功能性。因此,P2实验室装修标准不仅要满足一般实验室的要求,还需符合生物安全的特殊规定…

项目实战—OFD文件转换成图片

引言&#xff1a;项目需要预览OFD文件&#xff0c;但前端对OFD文件支持太差&#xff0c;因此将OFD文件直接转换成PNG格式、Base64编码的数据并返回给前端 依赖 <dependency><groupId>org.ofdrw</groupId><artifactId>ofdrw-converter</artifactId&…

餐厅点餐系统JAVA全栈开发(SSM框架+MYSQL)

代码仓库 GitHub - JJLi0427/Online_Order_SystemContribute to JJLi0427/Online_Order_System development by creating an account on GitHub.https://github.com/JJLi0427/Online_Order_System 项目介绍 餐厅点餐系统包含用户使用界面和功能实现&#xff0c;后台店员和管…

微信公众号错误码对应解决方案

微信公众号错误码对应解决方案 错误码&#xff1a; 40164 在获取 AccessToken 时报错&#xff1a; API 调用发生错误&#xff1a;{“errcode”:40164,“ErrorCodeValue”:40164,“errmsg”:“invalid ip 106.214.46.33, not in whitelist hint: [jPUF_08441512]”,“P2PData”…

C++初学者指南-2.输入和输出---文件输入和输出

C初学者指南-2.输入和输出—文件输入和输出 文章目录 C初学者指南-2.输入和输出---文件输入和输出1.写文本文件2.读文本文件3.打开关闭文件4.文件打开的模式 1.写文本文件 使用&#xff1a; std::ofstream&#xff08;输出文件流&#xff09; #include <fstream> // 文…

Scala 中的匿名函数

Scala 中的匿名函数 Scala 中的匿名函数是指没有指定函数名称的函数&#xff0c;通常用于简单的功能实现或者作为参数传递给其他函数。使用匿名函数可以简洁地表达代码逻辑&#xff0c;提高代码的可读性和简洁性。 在 Scala 中&#xff0c;可以使用 > 符号来定义匿名函数。下…

面试题--Zookeeper

1. Zookeeper 是什么(了解) Zookeeper 是一个 分布式协调服务 的开源框架, 主要用来解决分布式集群中应用系统 的一致性问题, 例如怎样避免同时操作同一数据造成脏读的问题. ZooKeeper 本质上是 一个分布式的小文件存储系统 . 提供基于类似于文件系统的目录 树方式的数据存…