• JAVA 反序列化漏洞入门学习笔记(一)--反序列化简介


    JAVA 真的令人头大

    参考文章

    Java反序列化漏洞从入门到深入

    JAVA 序列化与反序列化

    简介

    同 PHP/Python 类似,java 序列化的目的是将程序中对象状态转换成以数据流形式,反序列化是将数据流恢复为对象。
    此举可以有效地实现多平台之间的通信、对象持久化存储。

    序列化实例

    import java.io.*;
    
    //定义一个可序列化的类,该类必须实现 java.io.Serializable 接口
    class Giao implements java.io.Serializable
    {
        public String name;
        public String motto;
        public void saygiao()
        {
            System.out.println(this.motto);
        }
        // 自定义 readObject 方法
        private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException{
            //执行默认的readObject()方法
            in.defaultReadObject();
            
            //执行命令
            Runtime.getRuntime().exec("calc.exe");
        }
    }
    
    
    //序列化/反序列化
    public class SerializeGiao
    {
        public static void main(String [] args) throws IOException, ClassNotFoundException{
            //实例化一个可序列化对象
            Giao testClass = new Giao();
            testClass.name = "说唱带师";
            testClass.motto = "一给我哩 giao giao!";
            
            //序列化
            //将序列化后的对象写入到文件
            FileOutputStream fos = new FileOutputStream("test.ser");
            ObjectOutputStream os = new ObjectOutputStream(fos);
            os.writeObject(testClass);
            os.close();
            fos.close();
            
            //反序列化
            Giao obj = null;
            //从文件读取序列化的结果后进行反序列化
            FileInputStream fis = new FileInputStream("test.ser");
            ObjectInputStream ois = new ObjectInputStream(fis);
            obj = (Giao)ois.readObject();
            ois.close();
            fis.close();
        
    
            System.out.println(obj.name);
            System.out.println(obj.motto);
        }
    }
    
    
    
    //由此可见:人生苦短,我用 Python
    

    序列化结果:

    反序列化结果:

    序列化条件

    一个类的对象要想序列化成功,必须满足两个条件:

    • 该类必须实现 java.io.Serializable 或 java.io.Externalizable 接口。
      Externalizable 接口继承自 Serializable 接口,实现Externalizable 接口的类完全由自身来控制序列化的行为,而仅实现 Serializable 接口的类可以采用默认的序列化方式 。
      class Giao implements java.io.Serializable{}

    • 该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂的。

    实现序列化/反序列化的方法

    其中实现序列化与反序列化的两个类为:

    • java.io.ObjectOutputStream
      序列化:首先给该类传入一个文件对象(用于写入序列化结果),然后通过调用该类的 writeObject(目标对象) 方法将目标对象写入到文件

    • java.io.ObjectInputStream
      反序列化:首先给该类传入一个文件对象(用于读取文件中的序列化结果),然后通过调用该类的 readObject() 方法将其反序列化为目标对象

    看到下面代码的执行结果:

    输出了 1ndex,说明反序列化时调用了用户类 Giao 中的 readObject 方法,并且当我注释 in.defaultReadObject(); 代码,实际会输出 null
    因此,实际上完成反序列化的操作的具体步骤是用户类 Giao 中的 readObject 方法,也就是继承自 Serializable 接口的 readObject 方法

    为什么会出现反序列化漏洞

    当被反序列化的数据流用户可控时,那么攻击者即可通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码
    关键点在于用户自定义类中的 readObject() 方法形成了不安全的类,导致了反序列化安全问题

    简单的 demo

    漏洞代码:

    class RCE implements java.io.Serializable {
        public String cmd;
    
        private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
            in.defaultReadObject();
            Runtime.getRuntime().exec(cmd);
        }
    
    public class ToRCE{
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            RCE testClass = new RCE();
            testClass.cmd = "calc";
            
            FileOutputStream fileoutputstream = new FileOutputStream("RCE.ser");
            ObjectOutputStream outputstream = new ObjectOutputStream(fileoutputstream);
            outputstream.writeObject(testClass);
            outputstream.close();
            
            
            FileInputStream fileinputstream = new FileInputStream("RCE.ser");
            ObjectInputStream inputstream = new ObjectInputStream(fileinputstream);
            RCE obj = (RCE)inputstream.readObject();
            inputstream.close();
        }
    }
    
    

    看完上面的代码,是不是觉得 JAVA 反序列化漏洞跟 PHP 反序列化漏洞有些相似
    但是怎么会有人写这么愚蠢的代码呢?JAVA 反序列化的高端操作还得看 构造反序列化链

    JAVA 反序列化漏洞入门学习笔记(二):JAVA 反射

  • 相关阅读:
    [转载]美国名校的与机器视觉相关的研发中心网址
    图像匹配方法浅谈
    Debug FFMpeg with CodeBlock
    zircobrowser 源代码学习 一个Android平台的浏览器,适合用在学UI
    iPhone addSubview sameview 是否会产生内存泄漏
    Android 游戏demo
    C# 多线程 注意问题 总结
    Builld with gloox
    论坛专用
    VMware vSphere Client(4.1/5.0/5.1/5.5/6.0) 客户端下载地址
  • 原文地址:https://www.cnblogs.com/wjrblogs/p/14057785.html
Copyright © 2020-2023  润新知