Apache ShardingSphereUI远程代码执行漏洞CVE 2020 1947的示例分析
更新时间:2023-10-13Apache ShardingSphere&UI远程代码执行漏洞CVE 2020 1947
Apache ShardingSphere是一款基于JDBC的开源分布式数据库中间件,它能够支持多种数据库,可以对数据进行分片、分库、读写分离等操作。近日,Apache ShardingSphere被曝存在一个远程代码执行漏洞CVE 2020 1947,攻击者可以利用该漏洞构造特定的Payload,获取目标服务器的权限,甚至是控制整个服务器,造成严重后果。
漏洞分析
漏洞触发后,攻击者可以利用漏洞执行任意命令,从而获取服务器的权限。漏洞出现的根本原因是,ShardingSphere使用了基于Velocity模板引擎的远程Server运行代码。攻击者可以通过构造特定的Payload,将自己的代码注入到模板中,从而执行任意命令。具体的细节可以参考下面的代码:
public Object merge(Map params) throws Exception { String sql = (String) params.get("sql"); MaprealSqlMap = new HashMap<>(); Object shardingContext = params.get("shardingContext"); Collection dataSourceNames = shardingContext instanceof ShardingContext ? ((ShardingContext) shardingContext).getShardingRule().getDataSourceGroups().keySet() : ((ParsingResult) shardingContext).getRouteContext().getDataSourceNames(); for (String each : dataSourceNames) { realSqlMap.put(each, SQLPlaceholderUtil.replaceStatement(sql)); } return VelocityTemplateUtil.evaluate("classpath:META-INF/shardingjdbc/mybatis/merge.vm", realSqlMap); }
攻击Payload
攻击者构造Payload的基本方法是利用$!{...}标记在模板中执行恶意代码。$!{...}是Velocity中的一个高阶Directive指令,可以用于对任意一个Velocity的表达式进行求值,并在输出上下文对象时忽略输出为空的结果。攻击者可以在这里注入自己的代码,从而达到任意代码执行的目的。下面是一个典型的攻击Payload样例:
${{"freemarker.template.utility.Execute"?new()}}("curl http://localhost:8000/user/password_reset.php");
漏洞修复
修复该漏洞的方法较为简单,主要是通过更新ShardingSphere的版本来解决。目前,ShardingSphere的最新版本已经修复了此漏洞。同时,建议开发者主要注意一下两点:一个是尽量避免使用模板引擎在后端服务器上渲染用户输入,尤其是对包含变量值的字符串进行合并和拼接;另一个是应该避免在可视化或者HTTP接口等前台操作页面上使用如JSF的重度框架,因为这些页面可以直接获取后端服务器上的服务。
总结
Apache ShardingSphere&UI远程代码执行漏洞CVE 2020 1947是一种较为严重的安全漏洞,攻击者可以利用该漏洞在目标服务器上执行任意命令。该漏洞是由于ShardingSphere基于Velocity模板引擎的远程Server运行代码,攻击者可以通过构造特定的Payload执行任意命令。为了修复该漏洞,开发者需要尽快升级版本,并且避免在后端服务器上渲染用户输入。另外,应该尽量避免在可视化或者HTTP接口等前台操作页面上使用重度框架。