markdown
这里直接拿java序列化和反序列化当例子
序列化:把一个 Java 对象 → 转成字符串或字节流(比如 JSON、二进制),方便存储或传输。
反序列化:把字符串或字节流 → 还原成 Java 对象。(把已经序列化的数据,再恢复成程序中的对象。)
反序列化漏洞
问题出在:
程序把"不可信的数据"拿来反序列化了。
因为反序列化并不只是"读数据"这么简单。
在某些语言或框架里,反序列化过程中可能会自动触发:
- 对象创建
- 特殊方法执行
- 类加载
- 魔术方法调用
- 链式调用
如果攻击者能控制反序列化的数据内容,
就可能构造恶意对象,
在反序列化时触发危险行为。
反序列化怎么利用
反序列化第一步就是要找到利用链的入口
最好拆成两个东西:
- 先找"入口点"
也就是:
哪里会把外部可控数据送进反序列化流程。
比如:
- Shiro 的 rememberMe
- 某个接收对象流的接口
- 某个反序列化 Session / Cookie / 缓存的地方
这一步找的是:
攻击数据从哪里进来
markdown
Java 原生反序列化:入口常是 ObjectInputStream.readObject()
Shiro:入口常是 rememberMe 这类外部数据恢复流程
Fastjson:入口常是 JSON 解析函数和类型绑定流程
- 再看"利用链"
也就是:
数据进来以后,反序列化过程中能不能触发危险类链。
这一步找的是:
进来之后能不能打出效果
这里反序列化有分为三个大类:java 反序列化,shiro 反序列化,fastjson 反序列化
java 反序列化
本质:程序对攻击者可控的字节流调用了原生反序列化接口,结果在对象恢复过程中触发了类链调用,最终导致危险行为。
核心:
攻击者构造一段恶意序列化数据,里面不是普通对象,而是一组精心安排的对象关系。程序反序列化时,这些对象在自动调用链中触发危险方法,最终造成执行。
这个"精心安排的对象关系"通常就叫:
gadget chain(利用链)
你可以把它理解成:
- 单个类本身未必是漏洞
- 但多个类串起来,可能在反序列化过程中一路调用
- 最后走到危险操作
所以 Java 反序列化经常不是"某一个类有问题",而是:
类库里存在可被拼接利用的调用链。
shiro 反序列化
Shiro 在某些场景下,把用户身份信息以序列化形式放进 Cookie,再在服务端解密后进行反序列化。
所以 Shiro 反序列化的原理其实是:
Shiro 这个框架把外部输入带回到了 Java 原生反序列化流程里。
这里我自己总结的超级好理解版本
markdown
Shiro 反序列化本质上就是 rememberMe 提供了一个入口。攻击者把恶意序列化数据伪装成 rememberMe Cookie 传给服务端,如果服务端把它当成正常的 rememberMe 数据继续解析并反序列化,就可能触发漏洞。
反序列化利用通常要先找到"反序列化入口",而这个入口会决定攻击者可控数据能不能进入对象恢复流程。
所以在 Shiro 这个场景里:
- 入口:rememberMe
tips:Shiro 反序列化漏洞分类有两个:Shiro-550和Shiro-721
fastjson 反序列化
Fastjson 本来是个 JSON 解析库,作用是把 JSON 转成 Java 对象。官方仓库也明确说它可以把 JSON 字符串转换成对应的 Java 对象。
这里的反序列化:JSON -> Java 对象
这里我自己总结的超级好理解版本
markdown
Fastjson 反序列化漏洞的原理,是程序在解析攻击者可控的 JSON 数据时,因开启或允许 AutoType 等自动类型机制,根据输入中的 @type 信息去实例化指定 Java 类;如果该类在对象创建、属性注入或后续处理过程中存在副作用,就可能触发安全问题。(本质还是一个java的反序列化漏洞)
解读一下后半段的如果该类在对象创建、属性注入或后续处理过程中存在副作用,就可能触发安全问题。因为 Java 里的很多类,并不是"纯数据类"。
有些类在被创建或赋值时,可能会:
- 访问外部资源
- 触发方法调用
- 加载远程内容
- 执行复杂逻辑
所以风险并不一定来自 Fastjson 自己,而可能来自:
Fastjson + 某个可被实例化的危险类
也就是说:
- Fastjson 提供"解析并实例化"的能力(AutoType 等自动类型机制)
- 危险类提供"副作用" (java自带的类)
- 两者一结合,就可能形成漏洞