单例模式的反射漏洞和反序列化漏洞代码实例

除了枚举式单例模式外,其余4种在单例模式提到的单例模式的实现方式都存在反射漏洞和反序列化漏洞。

package singleton;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;

/**
 * 用反射和反序列化的方法破解单例模式
 * @author weiyx15
 *
 */
public class SingletonCrack {
	public static void main(String[] args) throws Exception
	{
		// 正常创建单例对象
		SingletonLazy s1 = SingletonLazy.getInstance();
		SingletonLazy s2 = SingletonLazy.getInstance();
		System.out.println(s1);
		System.out.println(s2);

		// 用反射破解单例
		Class<SingletonLazy> cls = (Class<SingletonLazy>) Class.forName("singleton.SingletonLazy");		// 获取SingletonLazy类
		Constructor<SingletonLazy> cons = cls.getDeclaredConstructor(null);		// 获取SingletonLazy的构造方法
		cons.setAccessible(true);			// 跳过方法的可见性检查
		SingletonLazy s3 = cons.newInstance();	// 调用构造方法生成新对象
		SingletonLazy s4 = cons.newInstance();	// 调用构造方法生成新对象
		System.out.println(s3);
		System.out.println(s4);

		// 用反序列化破解单例
		FileOutputStream fos = new FileOutputStream("object.out");	// 文件输出流
		ObjectOutputStream oos = new ObjectOutputStream(fos);		// 对象输出流
		oos.writeObject(s1);										// 向文件序列化对象
		oos.close();												// 关闭对象输出流
		fos.close();												// 关闭文件输出流

		FileInputStream fis = new FileInputStream("object.out");	// 文件输入流
		ObjectInputStream ois = new ObjectInputStream(fis);			// 对象输入流
		SingletonLazy s5 = (SingletonLazy) ois.readObject();		// 从文件反序列化对象
		ois.close();												// 关闭对象输入流
		fis.close();												// 关闭文件输入流
		System.out.println(s5);
	}
}

运行结果

singleton.SingletonLazy@15db9742 // s1
singleton.SingletonLazy@15db9742// s2
singleton.SingletonLazy@6d06d69c// s3
singleton.SingletonLazy@7852e922// s4
singleton.SingletonLazy@3b07d329 // s5

从运行结果可以看到,通过反射可以得到私有构造方法,从而实例化两个不同的对象实例 codesingleton.SingletonLazy@6d06d69c}和{@code singleton.SingletonLazy@7852e922}. 通过反序列化,也可以得到新对象{@code singleton.SingletonLazy@3b07d329}.

以懒汉式单例模式的实现为例,解决反射漏洞和反序列化漏洞的方法如下:

package singleton;

import java.io.ObjectStreamException;
import java.io.Serializable;

/**
 * 排除了反射漏洞和反序列化漏洞的懒汉式单例模式
 * @author weiyx15
 *
 */
public class SingletonLazySafe implements Serializable{
	private static SingletonLazySafe instance;

	private SingletonLazySafe() {
		// 防止反射漏洞通过再次调用私有构造方法实例化新的instance
		if (instance != null)
		{
			throw new RuntimeException();	// 抛出运行时异常
		}
	}

	public static synchronized SingletonLazySafe getInstance() {
		if (instance == null)	// 如果未实例化,则先实例化
		{
			instance = new SingletonLazySafe();	// 调用getInstance方法后再实例化对象
		}
		return instance;
	}

	/**
	 * 从I/O流读取对象时会调用readResolve接口
	 * 在readResolve接口中直接返回instance对象
	 * 避免反序列化时重新实例化对象
	 * @return 单例对象
	 * @throws ObjectStreamException
	 */
	private Object readResolve() throws ObjectStreamException {
		return instance;
	}
}

以上所述是小编给大家介绍的单例模式的反射漏洞和反序列化漏洞详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • java 单例的五种实现方式及其性能分析

    java 单例的五种实现方式及其性能分析 序言 在23种设计模式中,单例是最简单的设计模式,但是也是很常用的设计模式.从单例的五种实现方式中我们可以看到程序员对性能的不懈追求.下面我将分析单例的五种实现方式的优缺点,并对其在多线程环境下的性能进行测试. 实现 单例模式适用于资源占用较多的类,保证一个类只有一个实例即单例.通用的做法就是构造器私有化,提供一个全局的访问点,返回类的实例. uml图: 1.饿汉式 代码实现: package com.zgh.gof23.singleton; /** *

  • JAVA多线程并发下的单例模式应用

    单例模式应该是设计模式中比较简单的一个,也是非常常见的,但是在多线程并发的环境下使用却是不那么简单了,今天给大家分享一个我在开发过程中遇到的单例模式的应用. 首先我们先来看一下单例模式的定义: 一个类有且仅有一个实例,并且自行实例化向整个系统提供. 单例模式的要素: 1.私有的静态的实例对象 2.私有的构造函数(保证在该类外部,无法通过new的方式来创建对象实例) 3.公有的.静态的.访问该实例对象的方法 单例模式分为懒汉形和饿汉式 懒汉式: 应用刚启动的时候,并不创建实例,当外部调用该类的实例

  • Java实现单例模式之饿汉式、懒汉式、枚举式

    单例模式的实现(5种) 常用: 饿汉式(线程安全,调用效率高,但是不能延时加载) 懒汉式(线程安全,调用效率不高,可以延时加载) 其他: 双重检测锁式(由于jvm底层内部模型原因,偶尔会出问题,不建立使用) 静态内部类式(线程安全,调用效率高,但是可以延时加载) 枚举单例(线程安全,调用效率高,不能延时加载) 饿汉式单例具体代码如下: package com.lcx.mode; /** * * 饿汉式单例,不管以后用不用这个对象,我们一开始就创建这个对象的实例, * 需要的时候就返回已创建好的实

  • java 单例模式(饿汉模式与懒汉模式)

    java 单例模式 饿汉式单例 对于饿汉模式,我们可这样理解:该单例类非常饿,迫切需要吃东西,所以它在类加载的时候就立即创建对象. 懒汉式单例类 对于懒汉模式,我们可以这样理解:该单例类非常懒,只有在自身需要的时候才会行动,从来不知道及早做好准备.它在需要对象的时候,才判断是否已有对象,如果没有就立即创建一个对象,然后返回,如果已有对象就不再创建,立即返回. 单例设计模式常用于JDBC链接数据库 注意: 1 我们常用的是第一种饿汉式,因为: (1)既然采用了单例设计模式,就是为了使用单例类的对象

  • 浅析Java设计模式编程中的单例模式和简单工厂模式

    单例模式 动机 有时候只有一个类的实例是很重要的.比如,一个系统应该只有一个窗口管理实例. 单例模式是最简单设计模式:类负责实例化自己,确保只有一个实例,并且提供一个访问这个实例的入口. 目的 1. 确保只有一个实例被创建. 2. 提供访问这个实例的入口. 使用final确保被创建一次,private的构造函数确保不被实例化.public的getInstance方法确保外部能够访问.下面是饿汉模式: public class Singleton { private static final Si

  • java单例模式使用及注意事项

    1. 说明 1)单例模式:确保一个类只有一个实例,自行实例化并向系统提供这个实例 2)单例模式分类:饿单例模式(类加载时实例化一个对象给自己的引用),懒单例模式(调用取得实例的方法如getInstance时才会实例化对象)(java中饿单例模式性能优于懒单例模式,c++中一般使用懒单例模式) 3)单例模式要素: a)私有构造方法b)私有静态引用指向自己实例c)以自己实例为返回值的公有静态方法 2.实例 饿单例模式: 复制代码 代码如下: package com.wish.modedesign;

  • JAVA实现单例模式的四种方法和一些特点

    一.饿汉式单例类 复制代码 代码如下: public class Singleton  {      private Singleton(){ } private static Singleton instance = new Singleton(); private static Singleton getInstance(){          return instance;      }  } 特点:饿汉式提前实例化,没有懒汉式中多线程问题,但不管我们是不是调用getInstance()

  • java 单例模式和工厂模式实例详解

    单例模式根据实例化对象时机的不同分为两种:一种是饿汉式单例,一种是懒汉式单例. 私有的构造方法 指向自己实例的私有静态引用 以自己实例为返回值的静态的公有的方法 饿汉式单例 public class Singleton { private static Singleton singleton = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return singleton; } } 懒

  • Java单例模式的应用示例

    单例模式用于保证在程序的运行期间某个类有且仅有一个实例.其优势在于尽可能解决系统资源.通过修改构造方法的访问权限就可以实现单例模式. 代码如下: 复制代码 代码如下: public class Emperor {    private static Emperor emperor = null;// 声明一个Emperor类的引用 private Emperor() {// 将构造方法私有    } public static Emperor getInstance() {// 实例化引用   

  • 单例模式的反射漏洞和反序列化漏洞代码实例

    除了枚举式单例模式外,其余4种在单例模式提到的单例模式的实现方式都存在反射漏洞和反序列化漏洞. package singleton; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Constructor; /** * 用反射和反

  • 深入浅析PHP的session反序列化漏洞问题

    在php.ini中存在三项配置项: session.save_path="" --设置session的存储路径 session.save_handler="" --设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式) session.auto_start boolen --指定会话模块是否在请求开始时启动一个会话,默认为0不启动 session.serialize_handler string --定义用来序列化/反序列化的处

  • 网络安全渗透测试反序列化漏洞分析与复现工作

    目录 0x00概述 0x01服务分析 0x02漏洞分析 0x03POC构造 0x04总结 0x00 概述 GENESIS64软件的多个版本存在反序列化漏洞,影响多个组件,例如: 根据CVE漏洞相关描述,下载对应GENESIS软件版本搭建环境,进行漏洞分析与复现工作. 0x01 服务分析 安装完成后对整个系统进行熟悉,发现Web程序接口使用Silverlight进行数据交互,因此需要找到相关功能文件进行分析.经过一些时间查找,找到系统服务开启的配置文件,在配置文件中定义了访问接口信息以及调用的相关

  • 详解PHP反序列化漏洞的原理及示例

    目录 PHP反序列化 序列化与反序列化 PHP魔法函数 反序列化漏洞 简介 原理 触发条件 示例 PHP反序列化 序列化与反序列化 序列化说通俗点就是把一个对象变成可以传输的字符串.序列化过程中还会对不同属性的变量进行不同方式的变化 public的属性在序列化时,直接显示属性名 protected的属性在序列化时,会在属性名前增加0x00*0x00,其长度会增加3 private的属性在序列化时,会在属性名前增加0x00classname0x00,其长度会增加类名长度+2 反序列化就是把被序列化

  • PHP反序列化漏洞实例深入解析

    目录 引文 简介 基础知识 序列化 反序列化 属性 魔术方法 POP链 [MRCTF2020]Ezpop PHP字符串逃逸 结语 引文 上一篇给大家带来了XSS跨站脚本攻击漏洞不知道大家学的咋样了,今天给大家带来另一个漏洞,PHP的反序列化漏洞,这也是我在CTF比赛中遇到过最多的也是比较考察逻辑思维的一种漏洞. 简介 PHP反序列化是一个非常常见的漏洞,利用难度相比于文件上传等漏洞相对较困难,漏洞的形成的根本原因是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造

  • 详解PHP反序列化漏洞示例与原理

    目录 预备知识 PHP序列化与反序列化 序列化字符串格式 PHP魔术方法 示例 反序列化漏洞 构造函数&析构函数 CVE-2016-7124 预备知识 PHP序列化与反序列化 序列化:将一个复杂的数据类型(如对象.数组.变量等)转换为字符串表示,以便于在网络中传输和在数据库中存储.在PHP语言中使用serialize()函数实现. 反序列化:将一个序列化的字符串重新转换为一个具体的数据类型.在PHP语言中使用unserialize()函数实现. PHP对象中只有数据会被序列化,方法不会被序列化.

  • Springboot实现XSS漏洞过滤的示例代码

    背景 前阵子做了几个项目,终于开发完毕,进入了测试阶段,信心满满将项目部署到测试环境,然后做了安全测评之后..... ​(什么!你竟然说我代码不安全???) 然后测出了 Xss漏洞 安全的问题 解决方案 场景:可以在页面输入框输入JS脚本, 攻击者可以利用此漏洞执行恶意的代码 ! 问题演示 ​ ​ 所以我们要对于前端传输的参数做处理,做统一全局过滤处理 既然要过滤处理,我们首先需要实现一个自定义过滤器 总共包含以下四部分 XssUtil XssFilterAutoConfig XssHttpSe

  • Spring Framework远程代码执行漏洞分析(最新漏洞)

    目录 1.漏洞描述 2.漏洞影响排查方法 2.1.JDK 版本号排查 2.2.Spring 框架使用情况排査 3.解决方案 3.1.版本升级 3.2.缓解措施 Spring Framework远程代码执行漏洞 发布时间 2022-03-31 漏洞等级 High CVE编号 CVE-2022-22965 影响范围:同时满足以下三个条件可确定受此漏洞影响: JDK 版本 >= 9 使用了 Spring 框架或衍生框架 项目中 Controller 参数接收实体类对象并存在代码调用 1.漏洞描述 Sp

  • Java实现线程安全单例模式的五种方式的示例代码

    目录 饿汉式 枚举单例 懒汉式 DCL 懒汉式 静态内部类懒汉单例 饿汉式 饿汉式:类加载就会导致该单实例对象被创建 // 问题1:为什么加 final // 问题2:如果实现了序列化接口, 还要做什么来防止反序列化破坏单例 public final class Singleton_hungry implements Serializable { // 问题3:为什么设置为私有? 是否能防止反射创建新的实例? private Singleton_hungry(){} // 问题4:这样初始化是否

  • Java反射之通过反射获取一个对象的方法信息(实例代码)

    以下代码为一个工具类 package com.imooc.reflect; import java.lang.reflect.Method; public class ClassUtil { public static void printClassMessage(Object obj){ //要获取类的信息,首先要获取类的类类型 Class c = obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型 //获取类的名称 System.out.println("类的名称

随机推荐