# 简介
这是一个最简单的链,原生JDK就存在。也就是说,不需要服务器存在任何特定的第三方组件。如果目标存在反序列化漏洞,那么我们就能够通过这个链来实现dnslog功能,从而验证漏洞的存在。
前面我们学习了反序列化的知识,我们也知道了,只需要服务器反序列化了我们传入的对象,我们就有机会进行反序列化漏洞的利用。接着我们来看看这条链的整个过程把。
PS:看了反序列化的基础但还是不太懂的,建议就先分析这条链。
分析
java.net.URL分析
我的分析不是从入口类开始分析,而是先找到存在漏洞的一个类,然后再往上寻找入口类。
分析java.net.URL这个原生API。
首先,这个类实现了Serializable接口,所以能够被序列化。

接着我们需要找这个类里面的方法,看看有没有能够利用的。这里可以看到它存在很多方法,但是这些方法的命名我们很难在其他类中找到同名的情况,所以利用起来不好利用(和php的pop链一样,通过入口类的同名函数来移花接木)。我们需要找一些通用命名的方法(其实就是找URL这个类中和入口类中的同名方法)

接着我们找到了hashCode这个方法,这个方法想必在大量的类中都存在。

跟进分析,发现这个hashCode方法中尝试了获取host的地址,也就是说存在一个域名解析的过程,那么就可能造成DNSlog。

寻找入口类(HashMap分析)
在找到存在问题的类后,我们就可以寻找一个入口类,看看能不能进行利用了。
我们回忆一下,反序列化的入口类需要什么?
入口类参数中包含可控类,并且这个类有危险方法(在这条链中,我们的危险方法指的就是dnslog),入口类在readObject时触发这个类的危险方法。
首先呢我们寻找的这个入口类要么类型是URL这个类的类型,要么它的参数能存URL这个类的类型(Object)。
这里我们自然而然就想到了Map,Map这个类它的key和Value可以是任意类型,自然满足了我们的第一个要求。我们这里以Map的实现类HashMap为例。
第二个要求就是这个HashMap类实现了序列化接口,存在readObject,并且readObject中触发了目标类的危险方法,也就是说hashcode方法。
我们跟进HashMap看看代码:
①能够被序列化

②存在readObject,我们可以看到它做了很多自定义的策略。

继续分析readObject,我们可以看到,它执行了key的hashcode方法。也就是说,它调用了key值的hashcode的方法。这就意味着,如果我们以HashMap为入口类,并且key的参数是URL类型,则实例化HashMap获取的对象在反序列化的时候就会执行URL类的hashcode方法,从而进行DNSlog。


梳理一下
到这里,其实整个利用链我们就分析的差不多了,但是我们还是需要梳理一下。
首先是HashMap这个对象在反序列化的时候会调用key键的hashcode方法。
其次就是调用URL中的hashcode方法就能实现DNSlog。
那么利用链就很清晰了,只要让HashMap的key键为URL对象,那么在反序列化HashMap<URL,xxxx>这个对象的时候就达成了DNSlog的目的。
利用反射去掉序列化时的噪点
但需要注意的是,我们在测试的时候,序列化也会触发这个DNSlog,这可能会干扰我们的分析。
比如这里,我们只是对其进行了序列化它也调用了hashCode这个方法,执行了DNSlog。
PS:其实这里去不去不重要,但通过这个例子可以让我们知道反射在反序列化中的地位。

因此为了避免造成干扰,我们需要让它在序列化的时候不要执行dnslog。这里我们就发现,URL这个类的hashcode方法只要让hashcode这个变量的值不等于-1就能够不执行dnslog(而默认情况下这个个值是为-1的,也就是说默认情况下必执行dnslog),因此我们可以利用反射,让它不等于-1,从而跳过hashcode方法的调用。

此时我们再对其进行序列化就不会有dnslog了。

反序列化获取DNSlog
此时再对其进行反序列化,就成功获取dnslog了。
