java序列化漏洞搭建怎么弄?

在现有很多的应用当中,需要对某些对象进行序列化,让它们离开内存空间,入驻物理硬盘,以便可以长期保存,那么java序列化漏洞搭建怎么弄?今天我们就来讲解一下。

Java序列化是Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。

漏洞基本原理

简单的反序列化Demo

首先定义对象类Persion,包含两个参数

public class implements java.io.Serializable
{
    public String name;
    public int age;
    public void info()
    {
        System.out.println("Name:" + this.name + ";nAge:" + this.age);
    }
}

在主类中声明对象,并且将对象序列化为二进制文件,将其存储到硬盘中

import java.io.*;
public class Main
{
    public static void main(String[] args)
        {

将对象序列化为二进制文件

Persion p = new Persion();
p.name = "Joner";
p.age = 18;
try
{
    //打开一个文件输入流
    FileOutputStream fileOut = new FileOutputStream("D:\test\test.db");
    //建立对象输入流
    ObjectOutputStream out = new ObjectOutputStream(fileOut);
    //输出反序列化对象
    out.writeObject(p);
    out.close();
    fileOut.close();
    System.out.printf("保存成功");
}
catch (IOException i)
{
    i.printStackTrace();
}
}

进行反序列化

import java.io.*;
public class Main
{
    public static void main(String[] args)
    {
        /*从二进制文件中提取对象*/
        Persion persion = null;
        try
        {
            FileInputStream fileInputStream = new FileInputStream("D:\test\test.db");
            //建立对象输入流
            ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
            persion = (Persion) inputStream.readObject();
            inputStream.close();
            fileInputStream.close();
        }
        catch (ClassNotFoundException c)
        {
            System.out.println("对象未找到");
            c.printStackTrace();
            return;
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
            return;
        }
        catch (IOException e)
        {
            e.printStackTrace();
            return;
        }
        System.out.println("反序列化对象.......");
        System.out.println("Name:" + persion.name);
        System.out.println("Age:" + persion.age);
    }
}

查看test.db文件的内容可以看见如下内容

其中 AC ED 00 05 是java 序列化内容的特征,其中00 05 是版本信息,base64编码后为ro0AB

反序列化漏洞Demo

在上面的Demo中可以看到,进行反序列化时会调用readObject()方法,如果readObject方法书写不当就会引发漏洞。

import java.io.*;
public class Main
{
    public static void main(String[] args) throws Exception
    {
        Unsafeclass unsafeclass = new Unsafeclass();
        unsafeclass.name = "hhhhh";
        FileOutputStream fileOutputStream = new FileOutputStream("object");
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        //将对象写入object文件
        objectOutputStream.writeObject(unsafeclass);
        objectOutputStream.close();
        //从文件中反序列化对象
        FileInputStream fileInputStream = new FileInputStream("object");
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        //恢复对象
        Unsafeclass objectFormDisk = (Unsafeclass) objectInputStream.readObject();
        System.out.println(objectFormDisk.name);
        objectOutputStream.close();
    }
}
class Unsafeclass implements Serializable
{
    public String name;
    //重写readObject()方法
    private void readObject(java.io.ObjectInputStream inputStream) throws IOException, ClassNotFoundException
    {
        //执行默认的readObdect()方法
        inputStream.defaultReadObject();
        //执行打开计算器命令
        Runtime.getRuntime()
            .exec("calc.exe");
    }
}

程序运行过程为:

UnsafeClass类背序列化进入object文件;

从object文件中恢复对象;

调用被恢复对象的readObject()方法;

命令被执行;

这样看感觉并不会有人会这样写readobject()这个方法,而且一些成熟的框架都会有防范反序列化的方法,但仍有很大比例的反序列化漏洞,这主要是使用了不安全的库造成的。

java序列化的知识在实际工作中是一个重点,作为java人员要将这方面的知识熟悉运用,才能在实际工作中合理的解决问题!最后大家如果想要了解更多java初识知识,敬请关注奇Q工具网。

推荐阅读:

java开发有哪些课程?java开发课程介绍

json文件是干什么的?JSON文件是什么格式?

eclipse怎么使用?eclipse使用教程