java虽然看了语法 但是好多都没看过 最近总被问到序列化与反序列化漏洞的问题 很尴尬 特找个时间看了下实现
java序列化是为了实现减少内存开销,将一部分暂时不需要的通过序列化成文件流的形势存储到硬盘上,以减小内存的压力,之后需要用到的时候再通过反序列化读取到内存之中
java本着一切皆为对象的原则,理论上什么都可以序列化的,但是序列化需要implements java.io.Serializable的接口
Serializable无任何意义 只用于标识可序列化的语义 也就是说只有实现Serializable接口的对象才可以被序列化
package test;
import java.io.*;
public class Objectest {
public static final File FILE = new File("test.ser");
public static void main(String[] args) throws Exception {
ser(new Person("test",20));
dser();
}
public static void ser(Object obj) throws FileNotFoundException, IOException{ //序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE));
oos.writeObject(obj);
oos.close();
}
public static void dser() throws FileNotFoundException, IOException, ClassNotFoundException { //反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE));
System.out.println(ois.readObject());
ois.close();
}
}
class Person implements Serializable{
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
那么反序列化漏洞就能大概知道 是在数据流反序列化成对象的时候产生的漏洞,而造成的代码执行
接下来看反射机制
反就是正的反义词 反射即通过对象来查找类名称
那么获取类有三种方法
一种是通过类名称.class获取
一种是通过getClass()方法获取
最后是 Class.forName()
上面例子即为
Class<?> cls = new Person().getClass();
Class<?> cls2 = Person.class;
Class<?> cls3 = Class.forName("test.Person");
System.out.println(cls);
System.out.println(cls2);
System.out.println(cls3);
然后可以通过Instance()实例化对象
java执行命令是通过Runtime.getruntime().exec()来执行命令的
那么怎么通过反射机制调用类的方法呢
这里需要用的 getMethod()的invoke方法来反射调用对应的对象
那么可以这么写
Class.forName("java.lang.Runtime")
.getMethod("exec", String.class)
.invoke(Class.forName("java.lang.Runtime").getMethod("getRuntime",new Class[]{}).invoke(null),"calc.exe");
卧槽这么烂的写法以后要看不懂了
简单写。。。。
Class<?> clrun = Class.forName("java.lang.Runtime");
Method runt = clrun.getMethod("getRuntime",new Class[]{});
Object runa = runt.invoke(null);
Method execu = clrun.getMethod("exec", String.class);
execu.invoke(runa, "calc.exe");
呼 核心搞完了
接下来找个公开的问题练下手