一文掌握Java反序列化漏洞,从零基础到精通,收藏这篇就够了!

温馨提示: 本文仅供网络安全技术交流,请勿用于非法用途。所有操作需获得授权,否则后果自负,与本文作者及平台无关。请务必遵守法律法规!

各位老铁,今天咱们来聊聊一个让无数Java程序员夜不能寐的话题——反序列化漏洞。这玩意儿就像潜伏在代码里的幽灵,一不小心就可能给你带来灭顶之灾。不过别慌,看完这篇文章,保证你也能玩转反序列化,成为安全界的弄潮儿!

开胃小菜:啥是反序列化?

简单来说,序列化就是把Java对象变成一串字节,方便存储和传输;反序列化就是把这串字节还原成Java对象。 就像把变形金刚折叠成一个盒子,需要的时候再展开变回去。

序列化/反序列化:程序员的左右手

  • 序列化 (Serialization): 把Java对象转化为可传输的字节序列,就像把你的想法压缩成一个文件,方便发送给别人。
  • 反序列化 (Deserialization): 把字节序列还原为Java对象,相当于别人收到了你的文件,解压缩后理解了你的想法。

为啥要搞序列化?

想象一下,你的程序运行了一段时间,产生了一些重要的数据,比如用户登录信息、购物车内容等等。这些数据都存在内存里,一旦程序关闭或者服务器重启,数据就全没了!这可咋整?

这时候,序列化就派上用场了。它可以把内存中的数据保存到硬盘上,或者通过网络传输到其他地方。这样,即使程序重启,数据也不会丢失,是不是很神奇?

序列化的三大妙用:

  1. 持久化内存数据:让数据“永生”

    • 场景: 比如网站保持登录状态。
    • 原理: 客户端用Cookie记住你的身份,服务端用Session保存你的登录信息。如果Session数据只存在内存里,服务器一重启就GG了。所以,需要把Session数据序列化到硬盘上,让你的登录状态“永生”。
      2. 网络传输对象:跨系统的数据交流

    • 场景: 两个不同的系统需要交换Java对象。

    • 原理: 把Java对象序列化成二进制字节流,通过网络发送给对方。对方收到后,再反序列化成Java对象,就可以直接使用了。
      3. 远程方法调用(RMI):像调用本地方法一样简单

    • 这个比较高级,涉及到分布式系统,以后有机会再详细介绍。

序列化后的数据是啥样的?字符串还是二进制?

这个问题问得好!其实,两者都可以!

在PHP里,序列化后的数据通常是人类可读的字符串。那么,Java可以吗?

当然可以!

早些年,Java程序员喜欢用JSON格式来传输数据。

数据格式进化史:

  • 定长报文格式: 浪费空间,直接Pass。
  • 变长报文格式: 比定长好点,但还是不够灵活。
  • XML格式: 曾经的王者,各种标签看着就头大。

    • 优点: 可以用DTD进行格式校验,提前发现错误。
    • 缺点: 太笨重,代码冗余。
    • JSON格式: 现在的当红炸子鸡,轻巧灵活,人见人爱。

Java序列化实战:

1. JSON序列化 (Fastjson):

*   **步骤:**
    1.  引入Fastjson库(在`pom.xml`中添加依赖)。
    2.  定义一个`Person`类,包含`name`和`age`属性。
public class Person {
    private String name;
    private int age;

    // 省略构造方法、getter和setter
}
    3.  创建`Person`对象,并用`Fastjson.toJSONString()`方法进行序列化。
    4.  反序列化:用`Fastjson.parseObject()`方法将JSON字符串转换回`Person`对象。
Person person = new Person("fast", 999);
String jsonString = JSON.toJSONString(person);
Person parsedPerson = JSON.parseObject(jsonString, Person.class);
System.out.println(parsedPerson.getName()); // 输出: fast
*   **代码示例:**
// 引入Fastjson库
import com.alibaba.fastjson.JSON;

public class Main {
    public static void main(String[] args) {
        // 创建Person对象
        Person person = new Person();
        person.setName("fast");
        person.setAge(999);

        // 序列化
        String jsonString = JSON.toJSONString(person);
        System.out.println("序列化结果:" + jsonString);

        // 反序列化
        Person parsedPerson = JSON.parseObject(jsonString, Person.class);
        System.out.println("反序列化结果:" + parsedPerson.getName() + ", " + parsedPerson.getAge());
    }
}
*   **效果展示:**

![](https://enjoy-learning.oss-cn-shanghai.aliyuncs.com/creation/image_1744104996_7483.jpg)

2. JDK自带的序列化:

*   **步骤:**
    1.  让`Person`类实现`Serializable`接口(这是一个标记接口,告诉JVM这个类可以被序列化)。
    2.  使用`ObjectOutputStream`和`ObjectInputStream`进行序列化和反序列化。
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 创建Person对象
        Person person = new Person();
        person.setName("wuya");
        person.setAge(666);

        // 序列化
        FileOutputStream fileOutputStream = new FileOutputStream("person.bin");
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        objectOutputStream.writeObject(person);
        objectOutputStream.close();
        fileOutputStream.close();

        // 反序列化
        FileInputStream fileInputStream = new FileInputStream("person.bin");
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        Person parsedPerson = (Person) objectInputStream.readObject();
        objectInputStream.close();
        fileInputStream.close();

        System.out.println("反序列化结果:" + parsedPerson.getName() + ", " + parsedPerson.getAge());
    }
}
*   **代码示例:**
import java.io.*;

public class Person implements Serializable {
    private String name;
    private int age;

    // 省略构造方法、getter和setter
}
*   **效果展示:**

![](https://enjoy-learning.oss-cn-shanghai.aliyuncs.com/creation/image_1744104996_1956.jpg)

打开序列化后的二进制文件,你会看到一些神秘的代码,比如`AC ED ...`。这些代码代表着Java序列化的规范,感兴趣的同学可以去Java官网查阅。

![](https://enjoy-learning.oss-cn-shanghai.aliyuncs.com/creation/image_1744104996_8637.jpg)

重头戏:JDK反序列化漏洞

前面说了这么多,终于要进入正题了!

漏洞成因:

用JDK进行反序列化时,需要实现Serializable接口,并且会调用readObject()方法。

关键就在这里:readObject()方法是可以自定义的!

如果你自定义了一个readObject()方法,并且在里面执行了一些恶意代码(比如打开计算器),那么在反序列化时,就会执行你自定义的恶意代码,从而导致漏洞。

代码示例:

import java.io.*;

public class Person implements Serializable {
    private String name;
    private int age;

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
        // 执行恶意代码
        Runtime.getRuntime().exec("calc");
        in.defaultReadObject();
    }

    // 省略构造方法、getter和setter
}

执行效果:

漏洞利用:

如果有一个接口允许你上传序列化后的二进制文件(或者JSON格式的字符串),那么你就可以构造一个包含恶意readObject()方法的类,上传到服务器,让服务器进行反序列化,从而执行你的恶意代码。

等等!事情并没有这么简单!

你构造的类不一定存在于目标服务器的项目中。你需要找到目标项目中已经存在的,并且满足以下两个条件的类:

  1. 可以重写readObject()方法。
  2. readObject()方法中的参数可以被你控制,也就是说,你可以让它执行你想要的命令。

幸运的是,还真有这样的类! 比如AnnotationInvocationHandler类和BadAttributeValueExpException类。

经典案例:Apache Commons Collections反序列化漏洞

这个漏洞曾经轰动一时,利用了Apache Commons Collections库中的一些类,构造了一个精妙的利用链,可以在目标服务器上执行任意代码。

由于篇幅限制,这里就不展开讲解了,感兴趣的同学可以自行搜索学习。

总结:

Java反序列化漏洞是一个非常危险的漏洞,攻击者可以利用它在目标服务器上执行任意代码。

防御方法:

  • 不要轻易相信任何外部数据,对所有反序列化的数据进行严格的校验。
  • 尽量避免使用JDK自带的序列化机制,可以考虑使用JSON等更安全的序列化方式。
  • 及时更新第三方库,修复已知的反序列化漏洞。

希望这篇文章能让你对Java反序列化漏洞有一个更深入的了解。记住,安全无小事,时刻保持警惕,才能保护你的系统免受攻击!

黑客/网络安全学习包

资料目录

  1. 成长路线图&学习规划

  2. 配套视频教程

  3. SRC&黑客文籍

  4. 护网行动资料

  5. 黑客必读书单

  6. 面试题合集

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

1.成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图方向不对,努力白费

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

2.视频教程

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

3.SRC&黑客文籍

大家最喜欢也是最关心的SRC技术文籍&黑客技术也有收录

SRC技术文籍:

黑客资料由于是敏感资源,这里不能直接展示哦!

4.护网行动资料

其中关于HW护网行动,也准备了对应的资料,这些内容可相当于比赛的金手指!

5.黑客必读书单

**

**

6.面试题合集

当你自学到这里,你就要开始思考找工作的事情了,而工作绕不开的就是真题和面试题。

更多内容为防止和谐,可以扫描获取~

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*********************************

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值