Java反序列化-基础(一)
OXO1 序列化介绍
序列化(Serializable)是将数据对象转换成有序的字节流,便于保存在内存、文件、数据库中。而当需要使用数据时通过反序列化(Deserializable)的操作将字节流对象重建。
在Java中序列化使用 ObjectiOutputStream
类的writerObject()
方法实现,反序列化使用ObjectInputStream
类的readObjetion()
方法实现。
- ObjectiOutputStream 对象序列化流
- writerObject() 序列化
- ObjectInputStream 对象反序列化流
- readObjetion() 反序列化
- Serializable、Externalizable
- 标记接口,没有方法或字段,一旦实现该接口,标志该类的对象是可序列化
而序列化的目的是为了让java对象脱离java运行环境的一种手段,可以实现网络传输(RMI RPC)
,对象持久化存储
。
0x02 序列化漏洞原理
测试代码:通过下面的小栗子来了解序列化
package com.time.Serializable; |
可以看见测试代码中,通过ObjectOutputStream
类中的writeObject
方法实现字符串的序列化,并写入了Object文件中。
使用xxd来读取Object文件的序列化内容
文件标识头:aced 0005 是java反序列化内容的特征
又通过ObjectInputStream
类中的readObject
方法实现字符串的反序列化,恢复对象内容,并输出。
运行结果
0x03 反序列化漏洞之命令执行
在上述小栗子中,我们简单的了解了序列化和反序列化的过程,下面我们通过另外一个小栗子来执行系统命令。
测试代码:
TestDemo.java
package com.time.Serializable; |
TestDemo文件中的代码和之前的没什么区别,只是修改了字符串,而重点在MyOjbect文件中
MyOjbect.java
package com.time.Serializable; |
可以看见MyOjbect类继承了Serializable
接口,标识是可以序列化的,而文件中重写了readObject
方法,添加了命令执行代码,在我们调用readObject的
的时候,会执行这段代码,执行结果如下。
本地搭建了一个服务器来获取访问信息,可以看见是成功执行了。
通过上述小栗子可以看出反序列化漏洞的危害,后续会更深入的学习反序列的漏洞及,以及反序列化漏洞利用工具-ysoserial中的利用链。
0x04 参考链接
https://mp.weixin.qq.com/s/CbMhYuYafHzglIQ_gogZPg
https://www.freebuf.com/articles/web/266523.html