freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Java安全学习—C3P0链
H3rmesk1t 2022-03-21 22:06:11 98051
所属地 海外

C3P0 简介

c3p0is an easy-to-use library for making traditional JDBC drivers "enterprise-ready" by augmenting them with functionality defined by the jdbc3 spec and the optional extensions to jdbc2. As of version 0.9.5, c3p0 fully supports the jdbc4 spec.

In particular, c3p0 provides several useful services:

  • A class whichs adapt traditional DriverManager-based JDBC drivers to the newer javax.sql.DataSource scheme for acquiring database Connections.

  • Transparent pooling of Connection and PreparedStatements behind DataSources which can "wrap" around traditional drivers or arbitrary unpooled DataSources.

The library tries hard to get the details right:

  • c3p0 DataSources are both Referenceable and Serializable, and are thus suitable for binding to a wide-variety of JNDI-based naming services.

  • Statement and ResultSets are carefully cleaned up when pooled Connections and Statements are checked in, to prevent resource- exhaustion when clients use the lazy but common resource-management strategy of only cleaning up their Connections. (Don't be naughty.)

  • The library adopts the approach defined by the JDBC 2 and 3 specification (even where these conflict with the library author's preferences). DataSources are written in the JavaBean style, offering all the required and most of the optional properties (as well as some non-standard ones), and no-arg constructors. All JDBC-defined internal interfaces are implemented (ConnectionPoolDataSource, PooledConnection, ConnectionEvent-generating Connections, etc.) You can mix c3p0 classes with compliant third-party implementations (although not all c3p0 features will work with external implementations of ConnectionPoolDataSource).

环境搭建

<dependencies>
    <dependency>
        <groupId>com.mchange</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.5.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-catalina</artifactId>
        <version>8.5.27</version>
    </dependency>
</dependencies>

URLCLassLoader

过程分析

com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase本质上也是一个封装对象, 其中储存了PropertyChangeSupportVetoableChangeSupport对象, 用于支持监听器的功能.

这个类在序列化和反序列化时, 要保存内部的ConnectionPoolDataSource成员变量, 如果connectionPoolDataSource本身是不可序列化的对象, 则使用ReferenceIndirector对其进行引用的封装, 返回一个可以被序列化的IndirectlySerialized实例对象.

image

跟进ReferenceIndirector#indirectForm, 其中会调用ConnectionPoolDataSourcegetReference方法返回一个Reference对象, 并使用ReferenceSerialized对象对其封装.

image

在反序列化时, 会调用其IndirectlySerialized#getObject方法重新生成ConnectionPoolDataSource对象.

image

ReferenceSerialized#getObject调用InitialContext#lookup方法尝试使用JNDI来获取相应的对象, 在contextNameenv均为空的情况下, 调用ReferenceableUtils#referenceToObject使用Reference中的信息来获取.

image

这里跟进ReferenceableUtils#referenceToObject方法, 可以看到其使用了URLClassLoaderURL中加载了类并实例化, 于是可以通过插入恶意URL来触发漏洞.

image

根据上文的分析, 构造一个不可序列化的并且实现了ReferenceableConnectionPoolDataSource对象, 其getReference方法返回带有恶意类位置的Reference对象即可. 反序列化PoolBackedDataSourceBase时会处理其中的ConnectionPoolDataSource, 从而URLClassLoader加载指定的恶意类.image

BeanFactory

过程分析

URLCLassLoader-Gadget中利用的加载远程的恶意类, 当目标环境无法出网时, 则无法使用该方法. 在ReferenceableUtils#referenceToObject中注意到, 当var0.getFactoryClassLocation()值为null时, 会默认加载而不是远程加载, 接着在调用getObjectInstance方法, 这里可以参考JNDI在高版本JDK中的利用姿势, 参考Exploiting JNDI Injections in Java. 通过TomcatgetObjectInstance方法调用ELProcessoreval方法实现表达式注入, 当目标环境是Tomcat8理论上是可以实现无网利用的.

JNDI

过程分析

有两个类对ConnectionPoolDataSource进行了实现, 跟进其中的JndiRefConnectionPoolDataSource, 其中会调用JndiRefDataSourceBase#setJndiName方法(JndiRefForwardingDataSource继承JndiRefDataSourceBase中的setJndiName方法)来获取jndiName的值.

image

image

image

其次,JndiRefConnectionPoolDataSource类中有LoginTimeout属性及其setter方法,
setter方法会调用内部WrapperConnectionPoolDataSource对象的setLoginTimeout方法, 追踪后会发现来到JndiRefForwardingDataSource#setLoginTimeout.

image

image

image

跟进JndiRefForwardingDataSource#inner, 其会调用JndiRefForwardingDataSource#dereference, 再度跟进
此方法中会根据JndiRefForwardingDataSource#jndiName属性进行lookup问询, 而jndiName属性从上文看是可以被JndiRefConnectionPoolDataSource#setter方法控制的.

image

image

于是, 在FastjsonJackson等环境下, 调用JndiRefConnectionPoolDataSource类的jndinamelogintimeout属性的setter方法, 向jndiname传入恶意RMI服务器地址, 然后调用logintimeout#setter方法使受害机去lookup设置好的jndiname中的恶意地址, 造成JNDI注入.image

Hex 序列化字节加载器

过程分析

JNDI-Gadget中是对ConnectionPoolDataSource的实现类JndiRefConnectionPoolDataSource进行的利用, 而这条Gadget利用的则是WrapperConnectionPoolDataSource.WrapperConnectionPoolDataSource继承于WrapperConnectionPoolDataSourceBase, 在WrapperConnectionPoolDataSourceBase中存在属性userOverridesAsString及其setter方法setUserOverridesAsString, 触发fireVetoableChange事件处理.

image

WrapperConnectionPoolDataSource中存在方法setUpPropertyListeners, 其中有一个判断语句, 当其属性为userOverridesAsString时, 将调用parseUserOverridesAsString方法.

image

跟进parseUserOverridesAsString方法, 先对userOverridesAsString进行截取操作, 然后完成十六进制解码, 然后调用fromByteArray函数, 最终触发反序列化操作.

image

image

image

image

FastjsonJackson环境, 此Gadget更适合在不出网环境下利用.image

参考

c3p0的三个gadget

Exploiting JNDI Injections in Java

# java反序列化 # Java代码审计 # JAVA安全
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 H3rmesk1t 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
Java安全学习
H3rmesk1t LV.4
这家伙太懒了,还未填写个人描述!
  • 9 文章数
  • 6 关注者
Java安全学习—URLDNS链
2022-04-06
Java安全学习—JDK7u21链
2022-04-06
Java安全学习—表达式注入
2022-03-21
文章目录