ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java反序列化之原生

2022-09-14 17:04:02  阅读:179  来源: 互联网

标签:原生 java readObject import Java 序列化 public


早就想学java安全,但一直无从下手,今天下定决心好好学习,当然以下内容可能会有些许错误,小白的烦恼。

序列化与反序列化

Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。

序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例。

为什么需要序列化与反序列化

我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等, 而这些数据都会以二进制序列的形式在网络上传送。那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的。如何做到呢?这就需要Java序列化与反序列化了。换句话说,一方面,发送方需要把这个Java对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出Java对象。

当我们明晰了为什么需要Java序列化和反序列化后,我们很自然地会想Java序列化的好处。其好处一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),二是,利用序列化实现远程通信,即在网络上传送对象的字节序列。

① 想把内存中的对象保存到一个文件中或者数据库中时候;② 想用套接字在网络上传送对象的时候;③ 想通过RMI传输对象的时候

为什么会产生安全问题?

只要服务端反序列化数据,客户端传递类的readObject中代码会自动执行,给予攻击者在服务器上运行代码的能力。

几种常见的序列化和反序列化协议

XML&SOAP

JSON

Protobuf

理解

类比快递、打包和拆包

有些快递打包和拆包时有独特需求、比如易碎朝上,类比重写writeObject和readObject

【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】

 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)

实例

Java反序列化的操作,很多是需要开发者深入参与的,所以你会发现大量的库会实现readObject 、writeObject 方法,这和PHP中__wakeup 、__sleep 很少使用是存在鲜明对比的。我在《Java安全漫谈 - 06.RMI篇(3)》的最后一部分,讲到了classAnnotations ,这次再来说说objectAnnotation 。Java在序列化时一个对象,将会调用这个对象中的writeObject 方法,参数类型是ObjectOutputStream ,开发者可以将任何内容写入这个stream中;反序列化时,会调用readObject ,开发者也可以从中读取出前面写入的内容,并进行处理。

创建一个person类

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
​
public class Person implements Serializable {
    private String name;
    private int age;
    public Person(){}
    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }
​
    @Override
    public String toString() {
        return "Person{"+
        "name='" + name + "\'" +
                ",'age=" + age +
                '}';
    }
}

 

创建一个序列化类

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
​
public class SerializationTest {
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static void main(String[] args) throws Exception{
        Person person=new Person("xinyuan",22);
        serialize(person);
        System.out.println(person);
    }
}

 

创建一个反序列化类

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
​
public class UnserializationTest {
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("ser.bin"));
        Object obj = ois.readObject();
        return obj;
    }
    public static void main(String[] args) throws Exception{
        Person person=(Person) unserialize("ser.bin");
        System.out.println(person);
    }
}

可能的形式

1.入口类的readObject直接调用危险方法

img点击并拖拽以移动

在person类,重写readObject方法,序列化后,反序列化

img

2.入口类参数中包含可控类,该类有危险方法,readObject时调用。

3.入口类参数包含可控类,该类又调用其他有危险方法的类,readObject时调用

条件

共同条件 继承Serializable

入口类 source(重写readObject 参数类型宽泛 最好jdk自带) Map<Object ,Object>

调用链 gadget chain 相同名称,相同类型

执行类 sink(rce ssrf 写文件等等)

https://github.com/frohoff/ysoserial/

更多靶场实验练习、网安学习资料,请点击这里>>

搜索

复制

标签:原生,java,readObject,import,Java,序列化,public
来源: https://www.cnblogs.com/hetianlab/p/16693663.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有