前言

近年来反序列化漏洞可谓被大家熟知,尤其是的在JAVA 程序中发现了大量的反序列化漏洞,这种漏洞危害极大,可以直接造成RCE,获取到权限,本人之前对于这个漏洞一致认识很浅薄,甚至对于利用方式和工具都不太清楚,本文是对java语言基础的序列化与反序列化进行学习。

序列化与反序列化

Java 序列化是指把 Java 对象转换为字节序列的过程,序列化后的字节数据可以保存在文件、数据库中;而Java 反序列化是指把字节序列恢复为 Java 对象的过程。

所有在网络上面传输的对象,必须是可以序列化的。比如RMI(remote method invoke 远程方法调用),传入的参数和返回的结构都是可序列化的。所有需要保存到磁盘的对象都要实现序列化。通常建议创建的javaBean类都实现Serializable接口。

当然在实际场景中,直接使用JDK序列化的场景是很少的,一般都是使用其他方式,这是因为其本身有很多缺陷,如:无法跨语言、易被攻击、序列化后的流太大、序列化性能太差等。

但是我们通过学习他来了解基础原理,其他方式思路上应该也是大差不差。

java序列化

java中想要实现序列化与反序列化,主要是通过Serializable和Externalizable接口实现的。

Serializable与Externalizable的不同

  1. Serializable接口是不需要提供无参构造器的,因为直接由虚拟机来创建对象的,不通过构造方法。Externalizable是通过反射来创建对象的,需要类中有无参构造器。

  2. 采用Externalizable无需产生serialVersionUID,而Serializable接口需要。

  3. Externalizable 接口继承自 Serializable 接口,实现 Externalizable 接口的类完全由自身来控制反序列化的行为,而实现 Serializable 接口的类既可以采用默认的反序列化方式,也可以自定义反序列化方式。

Serializable接口

Serializable接口并没有要实现的方法,只是类似于一个标识符,表示这个类是可以被序列化的,不实现这个接口,序列化时程序会报错。

首先,我们创建一个User 类,这个类一定要实现Serializable接口

class User implements Serializable{private int age;private String name;public User(){};public User(String name,int age){this.age = age;this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

然后,我们使用ObjectOutStream 和FileOutStream 将序列化后的内容输入到文件中,然后再使用ObjectInputStram 和FileInputStream 读取文件,将值反序列化为对象。

public class Test {public static void main(String[] args) throws IOException, ClassNotFoundException {User peter = new User("peter",18);FileOutputStream file = new FileOutputStream("1");ObjectOutputStream io = new ObjectOutputStream(file);io.writeObject(peter);io.flush();io.close();file.close();FileInputStream file1 = new FileInputStream("1");ObjectInputStream input = new ObjectInputStream(file1);User pople = (User) input.readObject();System.out.println(pople.getName());}
}

Externalizable接口

实现Externalizable接口,必须实现writeExternal、readExternal方法。除此之外,实现该接口的类必须提供无参构造器,这是因为在反序列化时,是通过反射来创建对象的。

这里和Serializable接口不一样,

public interface Externalizable extends java.io.Serializable {void writeExternal(ObjectOutput out) throws IOException;void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}

序列化版本号

反序列化必须拥有class文件,但随着项目的升级,class文件也会升级,序列化怎么保证升级前后的兼容性呢?

java序列化提供了一个private static final long serialVersionUID 的序列化版本号,这个值可以自由指定,也可由JVM根据类信息计算出一个值;由JVM计算的出的值会导致问题,如在程序移植后,JVM的计算方法可能存在差异,导致值不相同。

只有版本号相同,即使更改了序列化属性,对象也可以正确被反序列化回来。如果反序列化使用的class的版本号与序列化时使用的不一致,程序会报InvalidClassException异常。

下面是类被修改后的几种情况。

  • 如果修改了非瞬态变量,则可能导致反序列化失败。如新类中实例变量的类型
  • 序列化时类的类型不一致,则会反序列化失败,这时候需要更改serialVersionUID
  • 如果只是新增了实例变量,则反序列化回来新增的是默认值;如果减少了实例变量,反序列化时会忽略掉减少的实例变量。

反序列化漏洞

Java反序列化了被恶意修改的序列化对象(须是服务器中存在的对象或者依赖包中的对象)。

根据Java官方说明,任何实现Serializable接口的Class都可以定义自己的readObject()方法,只要在重写方法的同时执行了defaultReadObject()方法即可。这样在反序列化的时候会自动invoke该Class下自己定义的readObject()方法。如果该方法书写不当的话就有可能引发恶意代码的执行,如

package evilSerialize;import java.io.*;public class Evil implements Serializable{public String cmd;private void readObject(java.io.ObjectInputStream stream) throws Exception {stream.defaultReadObject();Runtime.getRuntime().exec(cmd);}
}

但肯定不会有程序员写出这样的代码,所以往往实际中反序列化漏洞的构造比较复杂,而且需要借助Java的一些特性如Java的反射来进行漏洞利用。

参考

https://www.jianshu.com/p/c25c3eea9276
https://zhuanlan.zhihu.com/p/474825041
https://www.jianshu.com/p/729941f4e00c
https://zhuanlan.zhihu.com/p/474825041
https://www.huaweicloud.com/zhishi/vss-002.html
https://leihehe.top/2021/07/28/Java反序列化漏洞之Java反序列化流程与分析-3/
https://xz.aliyun.com/t/6787

java反序列化漏洞基础相关推荐

  1. java反序列化漏洞-基础

    基础: 要想了解java反序列化,首先要了解什么是序列化和什么是反序列化: 序列化:作用是将对象变为字符串 调用功能:ObjectOutputStream类的 writeObject() 反序列化:作 ...

  2. java反序列化漏洞的一些gadget

    目录 0x00 URLDNS 0x01 Commons Collections 0x02 RMI的codebase任意代码执行 0x03 JNDI 0x04 LDAP 0x05 JDK7u21 首先说 ...

  3. java序列化_技术干货 | JAVA反序列化漏洞

    目录 反序列化漏洞 序列化和反序列化 JAVA WEB中的序列化和反序列化 对象序列化和反序列范例 JAVA中执行系统命令 重写readObject()方法 Apache Commons Collec ...

  4. 修而未复:说说WebLogic那修不完的Java反序列化漏洞

    编者说明:这篇文章初稿写在Oracle CPU补丁发布之后,考虑到文章内容的影响,并未在当时发布,WebLogic 的 Java 反序列化漏洞,已经修复了多次,最终的修复仍然未彻底解决问题. 背景 当 ...

  5. 带你掌握java反序列化漏洞及其检测

    摘要:在本文中将先介绍java反序列化漏洞的原理,然后在此基础上介绍安全工具如何检测.扫描此类漏洞. 本文分享自华为云社区<java反序列化漏洞及其检测>,作者: alpha1e0. 1 ...

  6. Java反序列化漏洞通用利用分析

    2015年11月6日,FoxGlove Security安全团队的@breenmachine 发布的一篇博客[3]中介绍了如何利用Java反序列化漏洞,来攻击最新版的WebLogic.WebSpher ...

  7. 山东大学软件学院项目实训-创新实训-山大软院网络攻防靶场实验平台(十)-Java反序列化漏洞(2)

    目录 前言: 2.项目配置 3.编写"java 反序列化漏洞"后端代码 4.编写"java 反序列化漏洞"前端代码 5.运行测试 前言: 本篇文章在上一篇文章基 ...

  8. Lib之过?Java反序列化漏洞通用利用分析

    1 背景 2015年11月6日,FoxGlove Security安全团队的@breenmachine 发布的一篇博客[3]中介绍了如何利用Java反序列化漏洞,来***最新版的WebLogic.We ...

  9. JAVA反序列化漏洞简单理解

    反序列化原理 关于反序列化的原理不在多说,和php类似,序列化的数据是方便存储的,而存储的状态信息想要再次调用就需要反序列化 Java反序列化的API实现 实现方法 Java.io.ObjectOut ...

最新文章

  1. 前端Vue学习之路(一)-初识Vue
  2. 【算法总结】数学问题-最大公约数和最小公倍数
  3. 将多窗体应用程序改造为仿Chrome形式的简易方法
  4. cxf生成客户端代码
  5. SY-SUBRC 的含义
  6. json for java
  7. My SQL数据库引擎快速指导-1
  8. cesium加载KML、KMZ数据
  9. 新书上市 | 学校没有教的科学写作指南
  10. win7系统和银行驱动安装
  11. python 按比例缩小图片
  12. Bugzilla 下载和安装
  13. [Java Framework] SpringBoot几种启动后自动初始化的几种方式
  14. Basic认证方式的配置
  15. 场景一:刮刮卡,大转盘等抽奖算法
  16. 移动端APP设计趋势
  17. 黄油刀 Butterknife的使用准备工作
  18. 华为eNsp 配置ospf协议
  19. Java练习——输入n个数,存入数组,进行排序输出
  20. “美亚杯”第三届中国电子数据取证大赛答案解析(个人赛)

热门文章

  1. C++常用机器学习库
  2. 戴森球计划 超级计算机,更新详情 - 科幻游戏 戴森球计划 - 摩点
  3. CornerNet 论文阅读笔记
  4. 开博尔Q50要采用XMOS解码芯片与双时钟晶振的意义何在?
  5. 文献阅读:深度学习模型利用生物医学文本上下文关系进行命名实体识别
  6. K8S 生态周报| KIND v0.8 正式发布
  7. jqueyr开发实现公众号上传永久视频页面--微信开发素材管理4
  8. 【职业人生】如何有效的在职场当中避免工作失误和提高个人发展
  9. 高效职业经理人的八个习惯
  10. 惯导1-哥氏定理理解