8u20链浅析
目录
在7u21链中,我提到过它的修复方法是判断this.type是否为AnnotationType,不是则直接抛出异常。
8u20链就是对其的绕过。
java 反序列流生成机制
public class A{
public int Aage = 100;
protected String Aname = "String in A";
private boolean Aflag = true;
}
import java.io.Serializable;
public class B extends A implements Serializable {
public int age = 50;
protected String name = "String in B";
private boolean flag = false;
}
import java.io.*;
public class test {
public static void main(String[] args) throws Exception{
B b = new B();
serialize(b,"b.ser");
}
public static void serialize(Object object, String file) throws IOException {
File f = new File(file);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(object);
out.flush();
out.close();
}
}
上图是上面代码运行后得到的序列化流,我们通过调试来一窥序列化的过程。
标识符和流版本号
首先对以下代码进行跟进
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
跟进后会发现这里会向序列流中先写入两个常量STREAM_MAGIC(0xaced),STREAM_VERSION(5),可以理解为先写入一个标识符以及这个流的版本号
两个常量
随后向下跟进
out.writeObject(object)
此处又写入了一个常量TC_OBJECT(0x73)
跟进1427行的writeClassDesc后会来到 writeNonProxyDesc,又写入一个常量 TC_CLASSDESC(0x72)
类名与serialVersionUID
跟进1280行的writeNonProxy