首页 > 编程语言 >Java序列化、反序列化、反序列化漏洞

Java序列化、反序列化、反序列化漏洞

时间:2024-09-25 09:52:02浏览次数:7  
标签:Java name Person age readObject 漏洞 序列化

目录

1 序列化和反序列化

1.1 概念

Java 中序列化的意思是将运行时的对象转成可网络传输或者存储的字节流的过程。而反序列化正相反,是把字节流恢复成对象的过程。

1.2 序列化可以做什么?

  1. 持久化存储:将对象状态保存到存储设备(如硬盘)中,以便于后续读取使用。
  2. 网络传输:将对象转换成字节流,通过网络发送给另一个 JVM 实例,接收方再将字节流转回对象。
  3. 深度复制:通过序列化与反序列化可以实现对象的深复制,即创建一个新的对象,并且新对象的数据与原对象相同,但是它们在内存中的地址不同。

3 实现方式

3.1 Java 原生方式

step1:实现 Serializable 接口

要使一个类的对象能够被序列化,只需要让这个类实现 Serializable 接口即可。Serializable 是一个标记接口,它没有定义任何方法。例如:

public class Person implements Serializable {
    // 可选,用于版本控制
    private static final long serialVersionUID = 1L; 
    private String name;
    private int age;

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

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

}

step2:使用 ObjectOutputStream#writeObject() 方法序列化。例如:

public static void main(String[] args) throws IOException {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\test.bin"));
    oos.writeObject(new Person("zhangsan",18));
}

step3:使用 ObjectInputStream#readObject() 方法反序列化。例如:

public static void main(String[] args) throws IOException, ClassNotFoundException {
    ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(Paths.get("D:\test.bin")));
    Person p = (Person) ois.readObject();
    System.out.println(p);
}
// 打印 Person{name='zhangsan', age=18}

3.2 第三方方式

使用 Java 原生序列化方式序列化的对象只能被 Java 读取(反序列化),所以可以考虑先把对象转成一种通用的格式——如 JSON 字符串,然后把 JSON 字符串转成字节流进行网络传输,从而实现跨平台或者跨语言。

这个时候就可以使用市面上开源的序列化工具了,比如 JSON、Xml、hessian等。

4 反序列化漏洞

反序列化是把数据流转成对象,那么万一数据流被人恶意加工过呢?

拿 Java 原生的反序列化举例,反序列化需要调用 ObjectInputStream#readObject() 方法,但是如果数据流的对象自己重写了 readObject(),那 Java 便会调用自己的这个 readObject() 方法,这就给了攻击者可乘之机,他们就能在自己的 readObject() 方法里写攻击代码。

我们改造一下上面例子里的 Person 类:

@Data
public class Person implements Serializable {
    // 可选,用于版本控制
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;

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

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

    // 重写了 readObject 方法,反序列化时便会调用此处
    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        ois.defaultReadObject(); //这一步是先让反序列化读取的时候按照默认的方法执行
        Runtime.getRuntime().exec("calc"); //这一步是攻击代码,作用是打开windows系统计算器
    }
}

此时再去执行反序列化便会打开系统的计算器,如果把打开计算器改成别的攻击代码,攻击者便能实现对系统的攻击。

为什么 Java 会允许我们重写 readObject,并让服务端调用我们的 readObject 呢?其实这么做的原因是为了方便定制化某些类的序列化方法,比如 HashMap 类就重写了 readObject 方法,原因是由于 HashMap 内部使用了一些特定的数据结构(如数组和链表/红黑树),直接反序列化可能无法正确地恢复这些内部结构。因此,readObject 方法会负责根据序列化的数据正确地重建这些内部结构。

标签:Java,name,Person,age,readObject,漏洞,序列化
From: https://www.cnblogs.com/GilbertDu/p/18430691

相关文章

  • Java 初学 day04
    Java041、funaction方法1、定义:语句定义格式:修饰符返回值类型方法名(参数类型参数名,...){方法实现逻辑代码;return返回值;}2、名词解释:修饰符:publicstatic前几天只需要记住这一个固定写法就行,后面的学习过程中会改变这个修饰符返回值......
  • Java中关于继承的题目3
    3.某公司要开发新游戏,请用面向对象的思想,设计游戏中的蛇怪和蜈蚣精设定1)蛇怪类:属性包括:怪物名字,生命值,攻击力方法包括:攻击,移动(曲线移动),补血(当生命值<10时,可以补加20生命值)2)蜈蚣精类:属性包括:怪物名字,生命值,攻击力方法包括:攻击,移动(飞行移动)要求1)分析蛇怪和蜈蚣精的......
  • JavaScript (JS)与TypeScript (TS)------讲清楚二者的区别与联系 + 市场主流趋势
    在前端开发中,JavaScript(JS)和TypeScript(TS)都是非常流行的编程语言,它们各自有其优势和适用场景。下面是关于两者的一些对比以及当前的主流趋势:JavaScript(JS)简介:JavaScript是一种广泛使用的脚本语言,主要用于网页上的交互效果。它是一种动态类型、弱类型的语言,语......
  • JAVA基础:IO流,转换流,数据流,数组流
    1IO分类IO流就是一组流动的数据,可以实现数据从一个地方移动到另一个地方IO表示的InputStream和OutputStream,称为输入,输出流。可以实现文件的读写。IO随着关注的特点不同,有不同的分类按照数据流向分类,分为输入流和输出流输入和输出都是以Java程序为基准按......
  • 2.Javaweb-JSP实现数据传递和保存
    Javaweb-JSP实现数据传递和保存文章目录Javaweb-JSP实现数据传递和保存一、get与post区别二、equest对象常用方法三、内置对象--out对象JSP已经准备好的,可以直接使用的对象四、中文乱码JSP中默认使用的字符编码方式:iso-8859-1,不支持中文解决中文乱码参数传递在请求中保......
  • 1.Javaweb-搭建Web环境、初识JSP
    Javaweb-搭建Web环境、初识JSP文章目录Javaweb-搭建Web环境、初识JSP一、pc端程序架构分类:二、web服务器Tomcat三、JSP页面四、脚本语言五、Web程序常见错误六、错误替换JSP九大内置对象(包括JSP四大作用域)JSP四大作用域一、pc端程序架构分类:B/S:浏览器—服务......
  • java中关于继承题目2
    2.请使用面向对象的思想,设计自定义类,描述出租车和家用轿车的信息。设定1)出租车类:属性包括:车型,车牌,所属出租公司;方法包括:启动,停止2)家用轿车类:属性包括:车型,车牌,车主姓名;方法包括:启动,停止要求1)分析出租车和家用轿车的公共成员,提取出父类—汽车类2)利用继承机制,实现出租......
  • 关于我学习java的小结09
    一、知识点线程。二、目标理解进程和线程。掌握创建多线程的方式。理解线程的生命周期。掌握死锁。三、内容分析重点多线程的创建方式。线程的生命周期。死锁的形成条件。难点多线程的的理解。死锁。四、内容1、线程1.1什么是进程进程(Proce......
  • java中关于继承的题目1
    编写一个圆类Circle,该类拥有:1)一个成员变量,radius(私有,浮点型);//存放圆的半径;2)两个构造方法Circle() //将半径设为0Circle(double r) //创建Circle对象时将半径初始化为r3)三个成员方法doublegetArea() //获取圆的面积doublegetPerimeter() //获取圆的周长voidshow() //将......
  • javaweb学习2 -2024/9/24
    今天学习了数据库中约束的概念数据库-约束约束的概念约束是作用于表中列上的规则,用于限制加入表的数据约束的存在保证了数据库中数据的正确性,有效性和完整性约束的分类#约束createtableemp2(#自动增长auto_increment当列时数据类型并且唯一约束id......