web渗透序列化与反序列化
xiu概念
Serialization(序列化):将java对象以一连串的字节保存在磁盘文件中的过程,也可以说是保存java对象状态的过程。序列化可以将数据永久保存在磁盘上(通常保存在文件中)。
deserialization(反序列化):将保存在磁盘文件中的java字节码重新转换成java对象称为反序列化
优点
说一个跟我们网安息息相关的,利用序列化实现远程通信,在网络上传输字节序列
相关api
JDK类库提供的序列化API:
1 2 3 4 5
| java.io.ObjectOutputStream 表示对象输出流,其中writeObject(Object obj)方法可以将给定参数的obj对象进行序列化,将转换的一连串的字节序列写到指定的目标输出流中。 java.io.ObjectInputStream 该类表示对象输入流,该类下的readObject(Object obj)方法会从源输入流中读取字节序列,并将它反序列化为一个java对象并返回。
|
序列化与反序列化
创建一个可以被序列化的类,实现序列化的类对象必须实现了Serializable类或Externalizable类才能被序列化,否则会抛出异常,我们熟知的java执行命令的Runtime是不可以被序列化的

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import java.io.Serializable;
public class Student implements Serializable { private String name; private char sex; private int year;
public Student() { }
public Student(String name, char sex, int year) { this.name = name; this.sex = sex; this.year = year; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public char getSex() { return sex; }
public void setSex(char sex) { this.sex = sex; }
public int getYear() { return year; }
public void setYear(int year) { this.year = year; }
}
|
实现序列化与反序列化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| import java.io.*; import java.io.Externalizable;
public class UserStudent { public static void main(String[] args) throws IOException, ClassNotFoundException {
Student st = new Student("xiu", 'M', 18); File file=new File("C:\\\\Java\\\\Student\\\\Student1.txt"); if (file.exists()){ System.out.println("文件存在"); }else{ file.createNewFile(); }
try{ FileOutputStream fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(st);
fos.close(); oos.close();
FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis); Student st1 = (Student) ois.readObject();
System.out.println("name = " + st1.getName()); System.out.println("sex = " + st1.getSex()); System.out.println("year = " + st1.getYear()); ois.close(); fis.close();
}catch (ClassNotFoundException e){ e.printStackTrace(); } } }
|
漏洞所在
在实际开发过程中往往会重写readObject()方法,当readObject()方法中存在代码块时反序列化的属狗会直接调用执行,这种情况很少,往往出现的是该readObject()方法存在一个无害的的类,但是这个类调用了危险的类,最终实现代码执行