热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

漏洞修复_补个漏洞不容易—Dubbo远程命令执行漏洞修复始末

本文由编程笔记#小编为大家整理,主要介绍了补个漏洞不容易—Dubbo远程命令执行漏洞修复始末相关的知识,希望对你有一定的参考价值。
本文由编程笔记#小编为大家整理,主要介绍了补个漏洞不容易—Dubbo远程命令执行漏洞修复始末相关的知识,希望对你有一定的参考价值。





   


“纵观中国开源历史,你真的没法找到第二个像Dubbo一样自带争议和讨论热度的开源项目。”Dubbo的开发人员如是评论自己的“孩子”:Dubbo是一个优秀的RPC框架,是Java项目中卓越的框架之一。同所有的优秀服务提供框架一样,Dubbo也面临的安全问题。从本文从Dubbo今年6月遭遇的远程代码执行漏洞的入手,介绍Dubbo发现漏洞、修复漏洞、被绕过、继续修复的过程,期间涵盖了Dubbo漏洞原理和漏洞利用方式,希望可以借助Dubbo修复漏洞事件为例,来提供企业对重用应用框架安全的关注和重视程度。




补个漏洞不容易—Dubbo远程命令执行漏洞修复始末







01




技术背景

















什么是dubbo?







Dubbo是一个优秀的RPC框架,是Java项目中卓越的框架之一。
2011年,它的开源填补了当时生产环境使用的RPC框架的空白,一发布就被广泛采用;
另一方面,它经历了停止维护、重启维护后捐献给Apache基金会、接着又以顶级项目的身份毕业。


如果说最开始重新激活是以阿里巴巴为主导的项目维护投入,那自 Dubbo 加入 Apache 起,它就已经开始成为一个社区主导、社区贡献为主的完全开放的基金会项目。包括阿里巴巴、携程、工商银行、瓜子二手车、网联清算、中通等在内的互联网、传统企业公司,在 Dubbo的使用与社区代码贡献上都有投入。Dubbo社区正变得非常活跃和多样化。


Dubbo的运行过程如图所示:









补个漏洞不容易—Dubbo远程命令执行漏洞修复始末


Dubbo的运行过程:








1.服务提供者Provider启动时会向注册中心把自己的元数据注册上去,如服务IP、端口及需要注册的接口定义等信息;


2.服务消费方Consumer在启动时会从注册中心订阅服务提供方的元数据;


3.而当注册中心数据发生变更时,例如Provider某个节点Down掉,又或者服务提供方进行了扩容、增加了节点,会推送给订阅的Consumer;


4.在Consumer获取到元数据后,Consumer可以发起RPC调用;


5.RPC调用前后会向监控中心上报统计信息。










02




遭遇漏洞














1.Dubbo远程命令执行漏洞




2020年6月22日Apache官方发布了Dubbo 2.7.7版本,其中修复了一个严重的远程代码执行漏洞(CVE-2020-1948),该漏洞允许攻击者使用任意的服务名和方法名发送RPC请求,同时将恶意序列化参数作为Payload,当恶意序列化的参数被反序列化时将执行恶意代码。该漏洞与CVE-2017-3241RMI反序列化漏洞有点类似,都是在远程调用过程中通过方法参数传入恶意序列化对象,服务端在解析参数进反序列化时触发。




补个漏洞不容易—Dubbo远程命令执行漏洞修复始末




2.漏洞原理




CVE-2020-1948远程代码执行漏洞原理是远程方法被动态调用导致的代码执行。从程序报错异常中分析中找到奔溃点,然后跟进到源码中可以发现atorg.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:79)[dubbo-2.7.6.jar:2.7.6]开始分析,找到 readobject,再定位到comalibabacomcauchohessianioHessian2Input.java,经过后续的多次循环,comalibabacomcauchohessianioClassDeserializer.java与comalibabacomcauchohessianioClassDeserial。得到是hessian问题造成漏洞原因。




补个漏洞不容易—Dubbo远程命令执行漏洞修复始末




基于此,Apache官方在2020年6月22日Apache官方发布了Dubbo 2.7.7版本,在此版本中,对invoke的method的进行了限制,在DecodeableRpcInvocation.java文件133-135行增加了对Method方法进行验证,如果验证不通过则抛出非法参数异常终止程序运行,用来修复此漏洞。











03




亡羊补牢














1.惨遭绕过




2020年7月1日,腾讯安全云鼎实验室就给出了Dubbo2.7.7反序列化漏洞绕过的方法。从官方发布的补丁对比文件来看,Dubbo在DecodeableRpcInvocation.java文件133-135行增加了对Method方法进行验证,如果验证不通过则抛出非法参数异常终止程序运行。通过对历史版本的回溯,发现在2019.10.31日的一次提交中DubboProtocol类的getInvoker函数的RemotingException代码块中增加了getInvocationWithoutData方法,对inv对象的arguments参数进行置空操作,用来缓解后反序列化攻击,此处正是CVE-2020-1948漏洞后反序列化利用的触发点。千里之堤溃于蚁穴,为了应对反序列化的漏洞而推出的Dubbo2.7.7,还是再一次走上了因为反序列化而引发远程命令执行的老路。


 其中MITRE Caldera执行的动作由计划系统结合预配置的ATT&CK模型生成。这样的好处在于能够更好更灵活地对攻击者的操作进行模拟,而不是遵循规定的工作序列。自动模拟攻击者进行攻击演练,安全地重现发生过的攻击行为,不会对资产造成损害,并且能够重复执行以对防御能力和检测能力进行测试和验证。




2.绕过原理




绕过选用的反射链是com.sun.rowset.JdbcRowSetImpl。此次dubbo的利用方式虽然也是在connect()方法中被使用jndi的方式加载恶意类,但是dubbo是动态调用了JdbcRowSetImpl的getDatabaseMetaData方法,造成了connect方法被执行。对提交修复的commit代码分析发现在DecodeableRpcInvocation中增加了输入参数类型的校验。点开查看代码,在原有的基础上增加了参数类型的校验,补丁代码如下图所示:




补个漏洞不容易—Dubbo远程命令执行漏洞修复始末




这里的parameterTypes是限制Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;,如下图所示:




补个漏洞不容易—Dubbo远程命令执行漏洞修复始末




绕过2.7.7版本更新的传入的参数类型为Class类型。类路径为Classclass com.rometools.rome.feed.impl.ToStringBean类,如果对参数检查是可以有效阻止漏洞的利用,然而修复错了地方。从git的commit记录来看,官方的修复思路推测是想在异常抛出前利用参数类型的校验并拦截,防止引用的toString()方法造成代码执行。但是拦截错了地方,通过对源码的单步调试发现,此处抛出的异常并不在漏洞触发的调用链上。


DecodeableRpcInvocation.java文件133-135行增加了对Method方法进行验证,如果验证不通过则抛出非法参数异常终止程序运行,核心代码代码如下:




补个漏洞不容易—Dubbo远程命令执行漏洞修复始末




跟进isGenericCall和isEcho方法,发现验证逻辑十分简单,如果method等于$invoke、$invokeAsync或者$echo则返回true。不得不说此处站在开发角度思考是没问题的,非Dubbo自带service中的$invoke、$invokeAsync、$echo方法以外,其他函数名全部抛出异常,但是万万没想到RPC调用过程中方法名是用户可控的,所以攻击者可轻易的将method设置为其中任意一个方法来绕过此处限制。




补个漏洞不容易—Dubbo远程命令执行漏洞修复始末




知道了method的验证逻辑,修改CVE-2020-1948 Poc中的的service_name和method_name参数的值,分别为:org.apache.dubbo.rpc.service.GenericService和$invoke。就可以验证通过,最后进入hession反序列化流程,成功执行了代码。






3.姗姗来迟




7月28日,ApacheDubbo终于发布了2.7.8的版本用来解决绕过问题。




补个漏洞不容易—Dubbo远程命令执行漏洞修复始末




时隔1个月发布的Dubbo2.7.8版本堵上了2.7.7解决反序列化的问题,在2.7.8版本发布的后的1个多月,还没有被爆出利用绕过的案例,至此,Dubbo的反序列漏洞的修补终于告一段落。











04




后记














梅须逊雪三分白,雪却输梅一段香。关于Dubbo反序列化漏洞的攻与防之争从来没有停止过,Dubbo如此,其他的服务框架亦如此。没有绝对的安全,只有动态的攻与防的平衡。作为安全从业者,我们要敬畏攻击,更要感谢攻击,他山之石,可以攻玉。以攻促防、以攻带防,了解对手、了解敌人,攻防一体、攻防兼备才可以推动企业的安全的新发展。







中国光大银行 信息科技部安全管理处


安小灰









END








推荐阅读
  • 本文介绍了如何利用Apache POI库高效读取Excel文件中的数据。通过实际测试,除了分数被转换为小数存储外,其他数据均能正确读取。若在使用过程中发现任何问题,请及时留言反馈,以便我们进行更新和改进。 ... [详细]
  • SQLite数据库CRUD操作实例分析与应用
    本文通过分析和实例演示了SQLite数据库中的CRUD(创建、读取、更新和删除)操作,详细介绍了如何在Java环境中使用Person实体类进行数据库操作。文章首先阐述了SQLite数据库的基本概念及其在移动应用开发中的重要性,然后通过具体的代码示例,逐步展示了如何实现对Person实体类的增删改查功能。此外,还讨论了常见错误及其解决方法,为开发者提供了实用的参考和指导。 ... [详细]
  • 如何使用 `org.apache.poi.openxml4j.opc.PackagePart` 类中的 `loadRelationships()` 方法及其代码示例详解 ... [详细]
  • 本文介绍了如何利用Struts1框架构建一个简易的四则运算计算器。通过采用DispatchAction来处理不同类型的计算请求,并使用动态Form来优化开发流程,确保代码的简洁性和可维护性。同时,系统提供了用户友好的错误提示,以增强用户体验。 ... [详细]
  • 在本文中,我们将探讨如何在Docker环境中高效地管理和利用数据库。首先,需要安装Docker Desktop以确保本地环境准备就绪。接下来,可以从Docker Hub中选择合适的数据库镜像,并通过简单的命令将其拉取到本地。此外,我们还将介绍如何配置和优化这些数据库容器,以实现最佳性能和安全性。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 本文深入解析了 jQuery 中用于扩展功能的三个关键方法:`$.extend()`、`$.fn` 和 `$.fn.extend()`。其中,`$.extend()` 用于扩展 jQuery 对象本身,而 `$.fn.extend()` 则用于扩展 jQuery 的原型对象,使自定义方法能够作为 jQuery 实例的方法使用。通过这些方法,开发者可以轻松地创建和集成自定义插件,增强 jQuery 的功能。文章详细介绍了每个方法的用法、参数及实际应用场景,帮助读者更好地理解和运用这些强大的工具。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • 在本地环境中部署了两个不同版本的 Flink 集群,分别为 1.9.1 和 1.9.2。近期在尝试启动 1.9.1 版本的 Flink 任务时,遇到了 TaskExecutor 启动失败的问题。尽管 TaskManager 日志显示正常,但任务仍无法成功启动。经过详细分析,发现该问题是由 Kafka 版本不兼容引起的。通过调整 Kafka 客户端配置并升级相关依赖,最终成功解决了这一故障。 ... [详细]
  • Apache Hadoop HDFS QJournalProtocol 中 getJournalCTime 方法的应用与代码实例分析 ... [详细]
  • Java能否直接通过HTTP将字节流绕过HEAP写入SD卡? ... [详细]
  • 如何精通编程语言:全面指南与实用技巧
    如何精通编程语言:全面指南与实用技巧 ... [详细]
  • 本文探讨了 Java 中 Pair 类的历史与现状。虽然 Java 标准库中没有内置的 Pair 类,但社区和第三方库提供了多种实现方式,如 Apache Commons 的 Pair 类和 JavaFX 的 javafx.util.Pair 类。这些实现为需要处理成对数据的开发者提供了便利。此外,文章还讨论了为何标准库未包含 Pair 类的原因,以及在现代 Java 开发中使用 Pair 类的最佳实践。 ... [详细]
author-avatar
csc1520075
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有