Skip to content

Conversation

@aquariuspj
Copy link
Contributor

目的

加固 关于CVE-2020-1948 的问题修复。

问题

通过简单的修改CVE-2020-1948的POC示例,我在dubbo-2.7.7中再次复现了该问题。

  1. 使用 https://github.com/apache/dubbo-spring-boot-project 最新的2.7.7的TAG分支。
  2. 其他poc内容参照:https://blog.csdn.net/caiqiiqi/article/details/106934770,但修改其中POC的部分代码:
    resp = client.send_request_and_return_response(
    service_name='org.apache.dubbo.spring.boot.demo.consumer.DemoService',
    method_name='rce',
    args=[toStringBean])

修改为

    resp = client.send_request_and_return_response(
    service_name='org.apache.dubbo.spring.boot.sample.consumer.DemoService',
    method_name='$invoke',
    service_version='1.0.0',
    args=[toStringBean])

注入的恶意代码ExploitMac.java依然会被执行。

提交内容

  1. DecodeableRpcInvocation解码时,对$invoke、$invokeAsync、$echo等特殊方法进行参数描述的校验,防止外部输入不合法的参数类型。
@haiyang1985
Copy link
Member

这个修复好像一点都拦不住恶意代码,看下面这个例子,藏在types和objects里的恶意代码,你根本识别不了,也无法判断到底是不是恶意代码。

String[] types = new String[]{"com.xxx.rome"};
Object[] objects = new Object[]{new RomeObject()};
service.$invoke("$invoke", types, objects);
@aquariuspj aquariuspj closed this Jun 30, 2020
@aquariuspj
Copy link
Contributor Author

这个修复好像一点都拦不住恶意代码,看下面这个例子,藏在types和objects里的恶意代码,你根本识别不了,也无法判断到底是不是恶意代码。

String[] types = new String[]{"com.xxx.rome"};
Object[] objects = new Object[]{new RomeObject()};
service.$invoke("$invoke", types, objects);

抱歉...github这块操作我还不太熟悉..不小心点了很多奇怪的操作。

  1. 假设service.$invoke(String, String[], Object[])方法的声明确实存在,那么由于入参类型正确,因此恶意对象RemoObject的反序列化过程也一定会是正确的,此时也不会触发toString这个注入点。
  2. 如果入参类型全都正确,那么就应该交给应用层对入参进行额外校验来保证调用的安全性。。
@aquariuspj aquariuspj reopened this Jun 30, 2020
@chickenlj
Copy link
Contributor

LGTM.

@chickenlj chickenlj added this to the 2.7.8 milestone Jun 30, 2020
@chickenlj
Copy link
Contributor

@aquariuspj Thanks for the enhancement. Next time when discussing a vulnerability issue, please send an email to security@dubbo.apache.org.

@haiyang1985
Copy link
Member

这个修复好像一点都拦不住恶意代码,看下面这个例子,藏在types和objects里的恶意代码,��根本识别不了,也无法判断到底是不是恶意代码。

String[] types = new String[]{"com.xxx.rome"};
Object[] objects = new Object[]{new RomeObject()};
service.$invoke("$invoke", types, objects);

抱歉...github这块操作我还不太熟悉..不小心点了很多奇怪的操作。

  1. 假设service.$invoke(String, String[], Object[])方法的声明确实存在,那么由于入参类型正确,因此恶意对象RemoObject的反序列化过程也一定会是正确的,此时也不会触发toString这个注入点。
  2. 如果入参类型全都正确,那么就应该交给应用层对入参进行额外校验来保证调用的安全性。。

你的规则应该只能挡住调用$invoke的入参也是错误的情况吧,只要参数是符合String,String[],Object[],即使包含了恶意代码,也防不住的吧?

  1. 如果请求的$invoke的入参是String,String[],Object[],而且objects包含了RomeObject恶意代码,这个请求的desc还是会符合Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;规则的。
  2. 参考下现在的反序列化过程,因为pts的length是3,也就会执行3次in.readObject(),其中就包括in.readObject(RemoObject),导致恶意代码被反序列化,只要恶意代码被反序列化了,不是就有可能会触发toString的注入点嘛。
args = new Object[pts.length];
for (int i = 0; i < args.length; i++) {
    try {
        args[i] = in.readObject(pts[i]);
    } catch (Exception e) {
        if (log.isWarnEnabled()) {
            log.warn("Decode argument failed: " + e.getMessage(), e);
        }
    }
}
@aquariuspj
Copy link
Contributor Author

aquariuspj commented Jun 30, 2020

这个修复好像一点都拦不住恶意代码,看下面这个例子,藏在types和objects里的恶意代码,你根本识别不了,也无法判断到底是不是恶意代码。

String[] types = new String[]{"com.xxx.rome"};
Object[] objects = new Object[]{new RomeObject()};
service.$invoke("$invoke", types, objects);

抱歉...github这块操作我还不太熟悉..不小心点了很多奇怪的操作。

  1. 假设service.$invoke(String, String[], Object[])方法的声明确实存在,那么由于入参类型正确,因此恶意对象RemoObject的反序列化过程也一定会是正确的,此时也不会触发toString这个注入点。
  2. 如果入参类型全都正确,那么就应该交给应用层对入参进行额外校验来保证调用的安全性。。

你的规则应该只能挡住调用$invoke的入参也是错误的情况吧,只要参数是符合String,String[],Object[],即使包含了恶意代码,也防不住的吧?

  1. 如果请求的$invoke的入参是String,String[],Object[],而且objects包含了RomeObject恶意代码,这个请求的desc还是会符合Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;规则的。
  2. 参考下现在的反序列化过程,因为pts的length是3,也就会执行3次in.readObject(),其中就包括in.readObject(RemoObject),导致恶意代码被反序列化,只要恶意代码被反序列化了,不是就有可能会触发toString的注入点嘛。
args = new Object[pts.length];
for (int i = 0; i < args.length; i++) {
    try {
        args[i] = in.readObject(pts[i]);
    } catch (Exception e) {
        if (log.isWarnEnabled()) {
            log.warn("Decode argument failed: " + e.getMessage(), e);
        }
    }
}

只要参数是符合String,String[],Object[],即使包含了恶意代码,也防不住的吧?

是的,入参类型正确,反序列化一定会被执行。
不过在方法调用入参完全符合接口声明的情况下,现有的逻辑不会执行到DubboProtocol中抛出异常时的toString注入点。

  1. 现有的反序列化过程我觉得其实是没问题的,反序列化只是还原对象本身的信息,它也无法校验对象所携带的信息是否是恶意的。
  2. DubboProtocol中抛出异常那部分逻辑如何修改我觉得可能还需要再做一些讨论,不过在那之前先对入参类型进行校验应该是一个比较好的选择。
@haiyang1985
Copy link
Member

haiyang1985 commented Jul 1, 2020

这个修复好像一点都拦不住恶意代码,看下面这个例子,藏在types和objects里的恶意代码,你根本识别不了,也无法判断到底是不是恶意代码。

String[] types = new String[]{"com.xxx.rome"};
Object[] objects = new Object[]{new RomeObject()};
service.$invoke("$invoke", types, objects);

抱歉...github这块操作我还不太熟悉..不小心点了很多奇怪的操作。

  1. 假设service.$invoke(String, String[], Object[])方法的声明确实存在,那么由于入参类型正确,因此恶意对象RemoObject的反序列化过程也一定会是正确的,此时也不会触发toString这个注入点。
  2. 如果入参类型全都正确,那么就应该交给应用层对入参进行额外校验来保证调用的安全性。。

你的规则应该只能挡住调用$invoke的入参也是错误的情况吧,只要参数是符合String,String[],Object[],即使包含了恶意代码,也防不住的吧?

  1. 如果请求的$invoke的入参是String,String[],Object[],而且objects包含了RomeObject恶意代码,这个请求的desc还是会符合Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;规则的。
  2. 参考下现在的反序列化过程,因为pts的length是3,也就会执行3次in.readObject(),其中就包括in.readObject(RemoObject),导致恶意代码被反序列化,只要恶意代码被反序列化了,不是就有可能会触发toString的注入点嘛。
args = new Object[pts.length];
for (int i = 0; i < args.length; i++) {
    try {
        args[i] = in.readObject(pts[i]);
    } catch (Exception e) {
        if (log.isWarnEnabled()) {
            log.warn("Decode argument failed: " + e.getMessage(), e);
        }
    }
}

只要参数是符合String,String[],Object[],即使包含了恶意代码,也防不住的吧?

是的,入参类型正确,反序列化一定会被执行。
不过在方法调用入参完全符合接口声明的情况下,现有的逻辑不会执行到DubboProtocol中抛出异常时的toString注入点。

  1. 现有的反序列化过程我觉得其实是没问题的,反序列化只是还原对象本身的信息,它也无法校验对象所携带的信息是否是恶意的。
  2. DubboProtocol中抛出异常那部分逻辑如何修改我觉得可能还需要再做一些讨论,不过在那之前先对入参类型进行校验应该是一个比较好的选择。

没太理解,要么加个钉钉详聊一下?钉钉:haiyang198542

@chickenlj chickenlj merged commit 5ad186f into apache:master Jul 1, 2020
mercyblitz added a commit that referenced this pull request Jul 2, 2020
* Polish #6296 : Adding the new methods into MetadataReport to manipulate the exported URLs for service introspection

* Polish #6296 : Adding the new methods into MetadataReport to manipulate the exported URLs for service introspection

* Polish #6171 : [Feature] Introducing the composite implementation of MetadataService

* Revert "fix wrong check of InvokerListener when export a service (fix issue_6269) (#6271)"

This reverts commit 91989ca.

* Revert "fix wrong check of InvokerListener when export a service (fix issue_6269) (#6271)"

This reverts commit 91989ca.

* Revert the MetadataReport

* Polish #6305 : [Refactor] ServiceConfig and ReferenceConfig publish the ServiceDefinition based on the Dubbo Event

* Polish #6198 : [Issue] Fixing NacosDynamicConfiguration#publishConfig bug

* Polish #6310 : Refactoring MetadataReport's methods

* Polish #6198 : [Issue] Fixing NacosDynamicConfiguration#publishConfig bug

* Polish #6198 : [Issue] Fixing NacosDynamicConfiguration#publishConfig bug

* Polish #6315 : [Refactor] Refactoring the implementation of MetadataReport based on The Config-Center infrastructure

Deprecated List :

- NacosMetadataReport
- ZookeeperMetadataReport

* Polish #6315 : Refactoring by TreePathDynamicConfiguration

* Polish #6315 : Refactoring ConsulDynamicConfiguration by TreePathDynamicConfiguration

* Polish #6315 : Reset the config base path to be "metadata" for ConfigCenterBasedMetadataReportFactory

* Polish #6315 : Bugfix

* Polish #6315 : Bugfix

* Polish #6315 : Correct words

* sync wait netty server to finish shutdown (#6281)

* Polish #6333 : [Refactor] Using mandatory implementation of Service Instance registration instead of the event

* maybe we can remove null judge in this case (#6321)

* update

* update

* Polish #6336 : [Refactor] org.apache.dubbo.metadata.ServiceNameMapping

* Polish #6170 : [Feature] Introducing the externalized configuration for ServiceNameMapping

* Polish #6342 : [Enhancement] Introducing the composite ServiceNameMapping

* Refactor

* fix method name typo in JValidator.java (#6344)

* [Dubbo-6340]fix application cannot exit when use consul registry (#6341)

* fix application cannot exit when use consul registry

* make consul registry suppor ACL (#6313)

* make consul registry suppor ACL

* Polish #6172 : [Feature] Adding the "services" attribute methods into @DubboReference

* Polish #6173 : [Feature] Adding the "services" attribute into <dubbo:reference> element

* Polish #6346 : [Issue] Merging all subscribied URLs from the multiple services

* Polish #6346 : [Issue] Merging all subscribied URLs from the multiple services

* fix publish null value when use consul config center (#6351)

* fix publish null value when use consul config center

* Polish #6252

* Polish #6356 & #6171

* Polish #6356 & #6171

* Polish #6224 : Filter chain was not invoked with local calls since v2.7.6

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* Polish #6322 : Adding META-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter

* fix the priority of ListenableRouter were not effective (#6148)

fixes #4822

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* when the url is generic, the log level should be info (#6363)

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* fix NPE when check=false is set and provider is empty. (#6376)

fixes #6228

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* fix #6306.  support TypeBuilder sort (#6365)

* fix #6306. support TypeBuilder sort

* fix #6306. support TypeBuilder sort

* fix #6306. support TypeBuilder sort

* remove unused import

* add license for test file

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* enhance ClusterInvoker & ExtensionLoader (#6343)

- Introduce ClusterInvoker to better support multiple registries subscription
- Wrapper sort and enable/disable
- some small fixes

* Polish #6322 : [Enhancement] Fix the issues of test-cases after refactoring

* Fixed the test-cases

* Enhancement, support Map auto recognize in PojoUtils (#6106)

Fix #5939

* Polish #6389 : [Issue] Resolving the issues with ConsulServiceDiscovery

* fix typo in CommonConstants (#6373)

* Fix export provider error, change to catch throwable, handle NoClassDefFoundError (#6380)

* check parameterTypesDesc of Generic and Echo  (#6374)

* add tps filter to SPI list (#6282)

* Do not clear all configurator  instances when override is empty (#6395)

* Service callback throws "Not found exported service" when 'bind.port' is set (#6223)

* Removing RpcContext after test finishes. (#6314)

* Introduce ClusterInvoker to better support multiple registries subscription (#6343)

* return same reference invokers as much as possible (#6083)

fixes #6082

* fix ut

* Fixes the test-cases

* Fixes the test-cases

* Fixes the test-cases

Co-authored-by: tswstarplanet <tswstarplanet@apache.org>
Co-authored-by: Nine <nine.yang.coding@gmail.com>
Co-authored-by: 陈哈哈 <chenyongjia365@outlook.com>
Co-authored-by: luoning810 <18311333766@163.com>
Co-authored-by: cvictory <shenglicao2@gmail.com>
Co-authored-by: ken.lj <ken.lj.hz@gmail.com>
Co-authored-by: Siqu Chen <32302975+DIscord010@users.noreply.github.com>
Co-authored-by: D-H-T <dht925nerd@126.com>
Co-authored-by: skyguard1 <qhdxssm@qq.com>
Co-authored-by: Jeff Lu <278400368@qq.com>
Co-authored-by: Christophe·liwei <2484713618@qq.com>
Co-authored-by: Joe Zou <joezou@apache.org>
Co-authored-by: 李黄河 <jameslover121@gmail.com>
Co-authored-by: OrDTesters <44483852+OrDTesters@users.noreply.github.com>
Co-authored-by: zjseu2009 <zjseu2009@163.com>
@jiangyunpeng
Copy link

不好意思,请问下 2.6.x 版本不修复这个漏洞吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

4 participants