ShokaX

Java反序列化(3)-URLDNS链

发布于 字数统计 3.1k 字 阅读时长 11 分钟

Java反序列化(3)-URLDNS链

发布于 字数统计 3,065 阅读时长 16 分钟

# 简介

这是一个最简单的链,原生JDK就存在。也就是说,不需要服务器存在任何特定的第三方组件。如果目标存在反序列化漏洞,那么我们就能够通过这个链来实现dnslog功能,从而验证漏洞的存在。

前面我们学习了反序列化的知识,我们也知道了,只需要服务器反序列化了我们传入的对象,我们就有机会进行反序列化漏洞的利用。接着我们来看看这条链的整个过程把。

PS:看了反序列化的基础但还是不太懂的,建议就先分析这条链。

分析

java.net.URL分析

我的分析不是从入口类开始分析,而是先找到存在漏洞的一个类,然后再往上寻找入口类。

分析java.net.URL这个原生API。

首先,这个类实现了Serializable接口,所以能够被序列化。

image-20220918152511443

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

image-20220918152525657

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

image-20220918152535996

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

image-20220918152605835

寻找入口类(HashMap分析)

在找到存在问题的类后,我们就可以寻找一个入口类,看看能不能进行利用了。

我们回忆一下,反序列化的入口类需要什么?

入口类参数中包含可控类,并且这个类有危险方法(在这条链中,我们的危险方法指的就是dnslog),入口类在readObject时触发这个类的危险方法。

首先呢我们寻找的这个入口类要么类型是URL这个类的类型,要么它的参数能存URL这个类的类型(Object)。

这里我们自然而然就想到了Map,Map这个类它的key和Value可以是任意类型,自然满足了我们的第一个要求。我们这里以Map的实现类HashMap为例。

第二个要求就是这个HashMap类实现了序列化接口,存在readObject,并且readObject中触发了目标类的危险方法,也就是说hashcode方法。

我们跟进HashMap看看代码:

①能够被序列化

image-20220918152624258

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

image-20220918152630355

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

image-20220918152641329

image-20220918152644494

梳理一下

到这里,其实整个利用链我们就分析的差不多了,但是我们还是需要梳理一下。

首先是HashMap这个对象在反序列化的时候会调用key键的hashcode方法。

其次就是调用URL中的hashcode方法就能实现DNSlog。

那么利用链就很清晰了,只要让HashMap的key键为URL对象,那么在反序列化HashMap<URL,xxxx>这个对象的时候就达成了DNSlog的目的。

利用反射去掉序列化时的噪点

但需要注意的是,我们在测试的时候,序列化也会触发这个DNSlog,这可能会干扰我们的分析。

比如这里,我们只是对其进行了序列化它也调用了hashCode这个方法,执行了DNSlog。

PS:其实这里去不去不重要,但通过这个例子可以让我们知道反射在反序列化中的地位。

image-20220918152753029

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

image-20220918152800348

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

image-20220918152805416

反序列化获取DNSlog

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

image-20220918152824833