内容简介:越来越懒了,这次复现一下上月爆出的c3p0数据库连接池XXE的漏洞,跟了一下,主要还是对用户自定义的XML文件没进行任何检查。还是有点鸡肋的漏洞,但是怎么使用还是要看各位操作吧。受影响版本:<=0.9.5.2用过c3p0数据库连接池的朋友们都知道,c3p0这个库读的默认配置文件是
00×0 前言
越来越懒了,这次复现一下上月爆出的c3p0数据库连接池XXE的漏洞,跟了一下,主要还是对用户自定义的XML文件没进行任何检查。还是有点鸡肋的漏洞,但是怎么使用还是要看各位操作吧。
00×1 复现
受影响版本:<=0.9.5.2
用过c3p0数据库连接池的朋友们都知道,c3p0这个库读的默认配置文件是 c3p0-config.xml, 由于开发者可以任意编辑c3p0-config.xml,且c3p0源码中直接解析了xml文档导致了这个漏洞的产生。
构造一下环境:
dbUtil.java:
package com.test.util; import com.mchange.v2.c3p0.ComboPooledDataSource; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; public class dbUtils { private static DataSource dataSource = null; static { dataSource = new ComboPooledDataSource("mysql"); } /** * 返回连接 * @return */ public static Connection getConnection(){ Connection conn=null; try { conn = dataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return conn; } public static void closeConn(Connection conn){ try { if(conn!=null && conn.isClosed()){ conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } }
test.java
package com.test.junit; import com.test.util.dbUtils; import org.junit.Test; import org.junit.runner.RunWith; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import static org.junit.Assert.*; public class c3p0Test { @Test public void test(){ Connection conn = dbUtils.getConnection(); try { PreparedStatement stmt= conn.prepareStatement("select user() "); ResultSet rs=stmt.executeQuery(); while(rs.next()){ System.out.println(rs.getString(1)); } } catch (SQLException e) { e.printStackTrace(); } } }
c3p0-config.xml
在c3p0-config声明之前插入poc.
然后测试test.java
00×2 分析
我们根据cve的提示找到漏洞触发点
c3p0 0.9.5.2 allows XXE in extractXmlConfigFromInputStream in com/mchange/v2/c3p0/cfg/C3P0ConfigXmlUtils.java during initialization.
学习过 Java 的朋友都知道,Java解析xml常用的有四种方法:DOM,SAX,JDOM,DOM4J,而C3P0数据库连接池采用的DOM,而且在源码中也能看到
默认读取的配置文件是c3p0-config.xml
知道了产生的地方,现在我们一步一步来跟进漏洞产生的步骤,在初始化数据库连接池库打下断点。
进入Debug模式。
跟到 AbstractComboPooledDataSource 方法中
再跟进,此处调用了AbstractPoolBackedDataSource类中的构造器
跟进,调用了 PoolBackedDataSourceBase 类中的 PoolBackedDataSourceBase方法
但是值得注意的是,在执行这个方法之前,PoolBackedDataSourceBase类会初始化一些东西
我们需要关注的是dataSourceName这个变量,跟进initializeStringPropertyVar这个方法看下详细内容。
发现并不重要,但是往上看,会发现 C3P0Config这个类,有个静态代码块,初始化的时候加载了一些东西
继续跟进一下findLibraryC3P0Config方法
从代码中可以看到cfgFinder是调用了 C3P0ConfigFinder接口的findConfig方法
搜索一下,我们可以看到C3P0ConfigFinder接口只有一个实现类 DefaultC3P0ConfigFinder
跟进方法,可以看到XML的调用趋势了
调用了开头说的C3P0ConfigXmlUtils类中的另外一个方法中,跟进extractXmlConfigFromDefaultResource方法。
这里们可以看到此处调用了最终存在缺陷的函数,我们可以从代码中看到
is = C3P0ConfigUtils.class.getResourceAsStream(XML_CONFIG_RSRC_PATH);
我们可以在此类的头部看到XML_CONFIG_RSRC_PATH的初始化变量为c3p0-config.xml
代码中将is复制后,将is作为实参传入了 extractXmlConfigFromInputStream 方法中
is = C3P0ConfigUtils.class.getResourceAsStream(XML_CONFIG_RSRC_PATH); if ( is == null ) { warnCommonXmlConfigResourceMisspellings(); return null; } else return extractXmlConfigFromInputStream( is ); }
再跟进extractXmlConfigFromInputStream方法,也就是最先说的缺陷函数模块
这样,这个漏洞产生的流程就完整的呈现了出来。
00×3 修复方法
修改 extractXmlConfigFromInputStream函数内容,如下
public static C3P0Config extractXmlConfigFromInputStream(InputStream is) throws Exception { DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); DocumentBuilder db = fact.newDocumentBuilder(); fact.setExpandEntityReferences(false); Document doc = db.parse( is ); return extractConfigFromXmlDoc(doc); }
将setExpandEntityReferences设置为false
即不允许dom扩展出xml中的实体引用节点。
00×4 写在后面的话
漏洞确实有点鸡肋,但是思路猥琐点会有大用处,怎么操作看各位发挥。
拨开云雾见天日 守得云开见月明~
以上所述就是小编给大家介绍的《[CVE-2018-20433]c3p0XXE分析以及复现记录》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 【漏洞复现】WordPress插件Quizlord 2.0 XSS漏洞复现与分析
- Ghost Tunnel复现
- Paxos与“幽灵复现”
- CVE-2010-3333漏洞复现
- CVE-2017-12149漏洞复现
- CSAW 2018 复现writeup
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。