技术分享前尘—数据连接池下的至暗之处

Posted 安全客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了技术分享前尘—数据连接池下的至暗之处相关的知识,希望对你有一定的参考价值。

 




前言

【技术分享】前尘—数据连接池下的至暗之处

这是分析Java反序列化系列的第四篇文章,内容的填充度已经过半。此系列的每一篇文章 都会对漏洞产生的原因进行剖析,理解事物的原理往往在攻击时发挥奇效。
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。

 




序列化与反序列化

【技术分享】前尘—数据连接池下的至暗之处

既然是反序列化漏洞必然要提起的就是序列化与反序列化,如果还有读者对这个概念不清楚请参考文章《前尘——与君再忆CC链》,在Java反序列化漏洞中,序列化和反序列化是理解这些漏洞的基本条件。

 




导入Maven依赖

【技术分享】前尘—数据连接池下的至暗之处
 
   
   
 
<dependencies> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.5</version> </dependency> </dependencies>

此依赖为c3p0最新版本依赖,更新于2019年12月
【技术分享】前尘—数据连接池下的至暗之处

最新版本没有修复此问题

 




漏洞跟踪

【技术分享】前尘—数据连接池下的至暗之处

直接进入网上公开的链条类打开就是一顿分析com/mchange/v2/c3p0/impl/PoolBackedDataSourceBase

【技术分享】前尘—数据连接池下的至暗之处

分析了这么多的漏洞链条,其实道理很简单。将网上纰漏的漏洞类打开直接往下翻往下翻找到readObject()方法对其内容进行跟进就可以,三板斧直接一顿怼。

 
   
   
 
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { short version = ois.readShort(); switch(version) { case 1: Object o = ois.readObject(); if (o instanceof IndirectlySerialized) { o = ((IndirectlySerialized)o).getObject(); } this.connectionPoolDataSource = (ConnectionPoolDataSource)o; this.dataSourceName = (String)ois.readObject(); o = ois.readObject(); if (o instanceof IndirectlySerialized) { o = ((IndirectlySerialized)o).getObject(); } this.extensions = (Map)o; this.factoryClassLocation = (String)ois.readObject(); this.identityToken = (String)ois.readObject(); this.numHelperThreads = ois.readInt(); this.pcs = new PropertyChangeSupport(this); this.vcs = new VetoableChangeSupport(this); return; default: throw new IOException("Unsupported Serialized Version: " + version); } }
获取版本,使用switch case关键字做分支处理。这里拿到的version是1,所有走case1.
Object o = ois.readObject();
此语句反序列化出一个referenceSerialized对象,instanceof关键字用来测试一个对象是否为一个类的实例。com.mchange.v2.naming.ReferenceIndirector类中存在内部类ReferenceSerialized实现了IndirectlySerialized接口,所以类型比对通过。
【技术分享】前尘—数据连接池下的至暗之处
然后调用IndirectlySerialized类的getObject方法,但是ReferenceSerialized实现了IndirectlySerialized接口。所以实际使用多态的方式调用的是ReferenceSerialized的getObject方法
【技术分享】前尘—数据连接池下的至暗之处
 
   
   
 
ReferenceSerialized( Reference reference, Name name, Name contextName, Hashtable env ) { this.reference = reference; this.name = name; this.contextName = contextName; this.env = env; }
在ReferenceSerialized构造函数中传入四个值进行赋值
 
   
   
 
public Object getObject() throws ClassNotFoundException, IOException{ try { Context initialContext; if ( env == null ) initialContext = new InitialContext(); else initialContext = new InitialContext( env );
Context nameContext = null; if ( contextName != null ) nameContext = (Context) initialContext.lookup( contextName );
return ReferenceableUtils.referenceToObject方法将( reference, name, nameContext, env ); } catch (NamingException e) { //e.printStackTrace(); if ( logger.isLoggable( MLevel.WARNING ) ) logger.log( MLevel.WARNING, "Failed to acquire the Context necessary to lookup an Object.", e ); throw new InvalidObjectException( "Failed to acquire the Context necessary to lookup an Object: " + e.toString() ); } }
如果contextName不为空则使用lookup,进行rmi触发远程调用,但是这里的contextName为空只能向下分析
return中调用了ReferenceableUtils类的referenceToObject方法将构造函数中传入的四个值当作参数传入继续跟进。
【技术分享】前尘—数据连接池下的至暗之处
reFerenceToObject根据Reference对象来获取工厂类的名字,以及工厂类的地址,接着拿到类加载器,拿到appClassLoader(一般程序中类加载都用这个,它的上面还有jre核心类运行的加载(rt.jar)bootstrap classloader和扩展类加载ext classloader)
接着就判断工厂类地址是否为空,不为空则去远程地址加载工厂类,这里用到了urlclassLoader,然后通过class.forname生成一个class 类型的实例,就加载到了工厂类,即我们的恶意字节码类




总结

【技术分享】前尘—数据连接池下的至暗之处
个人认为此个序列化漏洞大致了解即可,因为此依赖新的架构项目已经不被广泛使用了,并且maven可以的看到最后一次更新在2019年。
Java反序列化一直是一个老生常谈的问题,理解这些原理性的知识可以更好的帮助我们找到执行链,你我终有一天也会发现理解事物的本质是如此重要。

(点击“阅读原文”查看链接)

 
   
   
 
 
   
   
 

- End -

精彩推荐



    
      
      
    

       
         
         
       
          
            
            
          
             
               
               
             
戳“阅读原文”查看更多内容

以上是关于技术分享前尘—数据连接池下的至暗之处的主要内容,如果未能解决你的问题,请参考以下文章

转:蒙田:如何度过人生的至暗时刻?

MVC设计模式((javaWEB)在数据库连接池下,实现对数据库中的数据增删改查操作)

前尘篇-函数调用的背后

7 行代码搞崩溃 B 站,原因令人唏嘘!

7 行代码搞崩溃 B 站,原因令人唏嘘!

前尘——权限控制下暗藏的杀机