java反序列化原理演示(一)
0 x00什么是java序列化和反序列?
Java序列化是指把Java对象转换为字节序列的过程便于保存在内存,文件,数据库中,ObjectOutputStream类的writeObject()方法可以实现序列化。
Java反序列化是指把字节序列恢复为Java对象的过程,ObjectInputStream类的readObject()方法用于反序列化。
0 x01 java反序列漏洞原理分析
首先先定义一个用户类需继承可序列化的
<代码>包测试; 进口java.io.IOException; 进口java.io.Serializable; 公开课用户实现了Serializable { 私人字符串名称; 公共字符串getName () { 返回名称; } 公共空间setName(字符串名称){ this.name=名称; } }代码>
编写一个测试类,生成一个用户对象,将其序列化后的字节保存在硬盘上,然后再读取被序列化后的字节,将其反序列化后输入用户的名称属性
<代码>包测试; 进口java.io.FileInputStream; 进口java.io.FileNotFoundException; 进口java.io.FileOutputStream; 进口java.io.IOException; 进口java.io.ObjectInputStream; 进口java.io.ObjectOutputStream; 公开课test1 { 公共静态void main (String [] args) { 尝试{ FileOutputStream=新FileOutputStream (“d:/1.本”); ObjectOutputStream obj_out=new ObjectOutputStream(出); 用户u=新用户(); u.setName(“测试”); obj_out.writeObject (u);//利用readobject方法还原用户对象 FileInputStream=新FileInputStream (“d:/1.本”); ObjectInputStream ins=new ObjectInputStream(的); 用户u1=(用户)ins.readObject (); System.err.println (u1.getName ()); }捕捉(FileNotFoundException e) {//TODO自动生成的catch块 e.printStackTrace (); }捕捉(IOException e) {//TODO自动生成的catch块 e.printStackTrace (); }捕捉(ClassNotFoundException e) {//TODO自动生成的catch块 e.printStackTrace (); } } } 代码>
运行后输出名字属性:测试
为了构造一个反序列化漏洞,需要重写用户的readObjec方法,在改方法中弹出计算器:
重写readObjec后的用户类:
<代码>包测试; 进口java.io.IOException; 进口java.io.Serializable; 公开课用户实现了Serializable { 私人字符串名称; 公共字符串getName () { 返回名称; } 公共空间setName(字符串名称){ this.name=名称; } 私人空间readObject (io。ObjectInputStream)抛出ClassNotFoundException, IOException { in.defaultReadObject (); Runtime.getRuntime () .exec (“calc.exe”); } } 代码>
再次运行测试类,发现计算器已经弹出:
只需要修改Runtime.getRuntime () .exec (“calc.exe");中的calc.exe即可执行任意命令
0 x02总结
产生反序列化漏洞的前提是必须重写继承了可序列化的类的readObjec方法
<强>参考连接:http://www.freebuf.com/vuls/170344.html
强>