【反序列化】java代码的反序列化漏洞

序列化与反序列化:

序列化与反序列化对于 Java 程序员来说,应该不算陌生了,序列化与反序列化简单来说就是 Java 对象与数据之间的相互转化。

那么对于完全面向对象的 Java 语言来说为什么要有序列化机制?

实质上,序列化机制并不只局限于 Java 语言,序列化的本质是内存对象到数据流的一种转换,我们知道内存中的东西不具备持久性,但有些场景却需要将对象持久化保存或传输。例如缓存系统中存储了用户的 Session,如果缓存系统直接下线,带系统重启后用户就需要重新登陆,为了使缓存系统内存中的 Session 对象一直有效,就需要有一种机制将对象从内存中保存入磁盘,并且待系统重启后还能将 Session 对象恢复到内存中,这个过程就是对象序列化与反序列化的过程,从而避免了用户会话的有效性受系统故障的影响。

反序列化方法的对比

Java的反序列化和PHP的反序列化有点类似,它们都是将一个对象中的属性按照某种特定的格式生成一段数据流,在反序列化的时候再按照这个格式将属性拿回来,再赋值给新的对象。
但Java相对PHP序列化更深入的地方在于,其提供了更加高级、灵活地方法writeObject,允许开发者将序列化数据流中插入一些自定义数据,进而在反序列化的时候能够使用使用readObject进行提取。

当然,PHP也提供了一个魔术方法__wakeup,在反序列化的时候进行触发。很多人会认为JavareadObjectPHP__wakeup类似,但其实不全对,虽然都是在反序列化的时候触发,但他们解决的问题稍微有些差异。

Java设计readObject的思路和PHP的__wakeup不同点在于:readObject倾向于解决反序列化时如何还原一个完整的对象,而PHP的__wakeup更倾向于解决反序列化后如何初始化这个对象

PHP的反序列化

PHP的序列化是开发者不能参与的,开发者调用serialize函数后,序列化的数据就已经完成了,得到的是一个完整的对象,并不能在序列化数据流里新增某一个内容,如果想插入新的内容,只有将其保存在一个属性中,也就是说PHP的序列化,、反序列化是一个纯内部的过程,而其__sleep、__wakeup魔术方法的目的就是在序列化、反序列化的前后执行一些操作。

java的反序列化

Java反序列化的操作,很多是需要开发者深入参与的,大量的库都会实现readObjectwriteObject方法,这和PHP中的__wakeup__sleep很少使用是存在鲜明对比的。 

JAVA反序列化漏洞:

反序列化漏洞是一种发生在应用程序中的安全性漏洞。当一个程序接收到未经验证或不安全的数据时,它可能会尝试使用反序列化技术将数据转换回其原始格式,可以通过创建一个特殊的字节流来控制对象在被反序列化时的行为。 这种漏洞可以通过发送恶意构造的数据来利用,这可能导致执行任意代码、绕过访问控制机制或泄露敏感信息等问题。要修复此漏洞,需要确保所有接收的数据都经过适当的验证和清理,以防止此类攻击。

举个例子,考虑一个简单的Java类,如下所示:

public class TestObject implements Serializable {  
    private String name;  
  
    public TestObject(String name) {  
        this.name = name;  
    }  
  
    public String getName() {  
        return name;  
    }  
}

 这是一个简单的可序列化对象,只有一个名字字段。现在,假设我们有一个恶意攻击者,他们创建了一个包含特殊字节流的文件,然后尝试将其反序列化为TestObject对象。这可能看起来像这样:

try {  
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("恶意文件路径"));  
    TestObject testObj = (TestObject) ois.readObject();  
    ois.close();  
    System.out.println(testObj.getName());  
} catch (IOException | ClassNotFoundException e) {  
    e.printStackTrace();  
}

如果攻击者创建的文件包含能够改变TestObject的name字段的特殊字节流,那么在反序列化时,我们的TestObject对象可能会被恶意控制。这就是反序列化漏洞的基本原理。 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值