memshell-party-cli 0.1.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/index.js ADDED
@@ -0,0 +1,487 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/api/client.ts
4
+ var ApiError = class extends Error {
5
+ constructor(message, status, url) {
6
+ super(message);
7
+ this.status = status;
8
+ this.url = url;
9
+ this.name = "ApiError";
10
+ }
11
+ status;
12
+ url;
13
+ };
14
+ var MemPartyClient = class {
15
+ baseUrl;
16
+ fetchImpl;
17
+ timeoutMs;
18
+ constructor(options) {
19
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
20
+ this.fetchImpl = options.fetch ?? globalThis.fetch;
21
+ this.timeoutMs = options.timeoutMs ?? 3e4;
22
+ if (typeof this.fetchImpl !== "function") {
23
+ throw new Error(
24
+ "No fetch implementation available. Use Node.js >= 18 or pass a custom fetch."
25
+ );
26
+ }
27
+ }
28
+ // ---------- config ----------
29
+ getServers() {
30
+ return this.request("GET", "/api/config/servers");
31
+ }
32
+ getConfig() {
33
+ return this.request("GET", "/api/config");
34
+ }
35
+ getPackerTree() {
36
+ return this.request("GET", "/api/config/packers/tree");
37
+ }
38
+ getPackers() {
39
+ return this.request("GET", "/api/config/packers");
40
+ }
41
+ getCommandConfigs() {
42
+ return this.request("GET", "/api/config/command/configs");
43
+ }
44
+ getVersion() {
45
+ return this.request("GET", "/api/version");
46
+ }
47
+ // ---------- generation ----------
48
+ generateMemShell(req) {
49
+ return this.request("POST", "/api/memshell/generate", {
50
+ json: req
51
+ });
52
+ }
53
+ generateProbe(req) {
54
+ return this.request("POST", "/api/probe/generate", {
55
+ json: req
56
+ });
57
+ }
58
+ /** Parse a fully-qualified class name from a base64-encoded .class file. */
59
+ parseClassName(classBase64) {
60
+ return this.request("POST", "/api/className", {
61
+ text: classBase64,
62
+ raw: true
63
+ });
64
+ }
65
+ // ---------- transport ----------
66
+ async request(method, path, opts = {}) {
67
+ const url = `${this.baseUrl}${path}`;
68
+ const headers = {};
69
+ let body;
70
+ if (opts.json !== void 0) {
71
+ headers["Content-Type"] = "application/json";
72
+ body = JSON.stringify(opts.json);
73
+ } else if (opts.text !== void 0) {
74
+ headers["Content-Type"] = "text/plain";
75
+ body = opts.text;
76
+ }
77
+ const controller = new AbortController();
78
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
79
+ let response;
80
+ try {
81
+ response = await this.fetchImpl(url, {
82
+ method,
83
+ headers,
84
+ body,
85
+ signal: controller.signal
86
+ });
87
+ } catch (err) {
88
+ if (err instanceof Error && err.name === "AbortError") {
89
+ throw new ApiError(`Request timed out after ${this.timeoutMs}ms`, 0, url);
90
+ }
91
+ throw new ApiError(
92
+ `Failed to reach ${url}: ${err.message}`,
93
+ 0,
94
+ url
95
+ );
96
+ } finally {
97
+ clearTimeout(timer);
98
+ }
99
+ const rawText = await response.text();
100
+ if (!response.ok) {
101
+ let message = rawText || response.statusText;
102
+ try {
103
+ const parsed = JSON.parse(rawText);
104
+ if (parsed?.error) message = parsed.error;
105
+ } catch {
106
+ }
107
+ throw new ApiError(message, response.status, url);
108
+ }
109
+ if (opts.raw) {
110
+ return rawText;
111
+ }
112
+ if (rawText === "") {
113
+ return void 0;
114
+ }
115
+ return JSON.parse(rawText);
116
+ }
117
+ };
118
+
119
+ // src/core/request-builder.ts
120
+ import { randomInt } from "crypto";
121
+
122
+ // src/core/jdk.ts
123
+ var JDK_VERSIONS = {
124
+ java6: 50,
125
+ java8: 52,
126
+ java9: 53,
127
+ java11: 55,
128
+ java17: 61,
129
+ java21: 65
130
+ };
131
+ function resolveJreVersion(input) {
132
+ if (input === void 0 || input === "") return void 0;
133
+ if (typeof input === "number") return input;
134
+ const normalized = input.trim().toLowerCase();
135
+ if (normalized in JDK_VERSIONS) return JDK_VERSIONS[normalized];
136
+ const withPrefix = `java${normalized}`;
137
+ if (withPrefix in JDK_VERSIONS) return JDK_VERSIONS[withPrefix];
138
+ const num = Number(normalized);
139
+ if (Number.isInteger(num) && num > 0) return num;
140
+ throw new Error(
141
+ `Invalid JDK version "${input}". Use one of: ${Object.keys(JDK_VERSIONS).join(", ")}, or a class-file major version like 52.`
142
+ );
143
+ }
144
+
145
+ // src/core/request-builder.ts
146
+ var SPRING_GZIP_JDK17_RELATED_PACKERS = /* @__PURE__ */ new Set([
147
+ "SpEL",
148
+ "SpELSpringGzipJDK17",
149
+ "OGNL",
150
+ "OGNLSpringGzipJDK17",
151
+ "JXPath",
152
+ "JXPathSpringGzipJDK17"
153
+ ]);
154
+ var UPPERCASE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
155
+ var CLASS_NAME_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
156
+ function randomChar(chars) {
157
+ return chars[randomInt(chars.length)];
158
+ }
159
+ function generateSpringExpressionInjectorClassName() {
160
+ const randomName = Array.from({ length: 5 }, () => randomChar(CLASS_NAME_LETTERS)).join("");
161
+ return `org.springframework.expression.${randomChar(UPPERCASE_LETTERS)}${randomName}Util`;
162
+ }
163
+ function buildMemShellRequest(opts) {
164
+ const injectorClassName = SPRING_GZIP_JDK17_RELATED_PACKERS.has(opts.packer) ? generateSpringExpressionInjectorClassName() : opts.injectorClassName;
165
+ return {
166
+ shellConfig: {
167
+ server: opts.server,
168
+ serverVersion: opts.serverVersion,
169
+ shellTool: opts.shellTool,
170
+ shellType: opts.shellType,
171
+ targetJreVersion: resolveJreVersion(opts.jdk),
172
+ debug: opts.debug,
173
+ byPassJavaModule: opts.byPassJavaModule,
174
+ shrink: opts.shrink,
175
+ lambdaSuffix: opts.lambdaSuffix,
176
+ probe: opts.probe
177
+ },
178
+ shellToolConfig: {
179
+ shellClassName: opts.shellClassName,
180
+ godzillaPass: opts.godzillaPass,
181
+ godzillaKey: opts.godzillaKey,
182
+ commandParamName: opts.commandParamName,
183
+ commandTemplate: opts.commandTemplate,
184
+ behinderPass: opts.behinderPass,
185
+ antSwordPass: opts.antSwordPass,
186
+ headerName: opts.headerName,
187
+ headerValue: opts.headerValue,
188
+ shellClassBase64: opts.shellClassBase64,
189
+ encryptor: opts.encryptor,
190
+ implementationClass: opts.implementationClass
191
+ },
192
+ injectorConfig: {
193
+ injectorClassName,
194
+ urlPattern: opts.urlPattern,
195
+ staticInitialize: opts.staticInitialize
196
+ },
197
+ packer: opts.packer
198
+ };
199
+ }
200
+ function buildProbeRequest(opts) {
201
+ return {
202
+ probeConfig: {
203
+ probeMethod: opts.probeMethod,
204
+ probeContent: opts.probeContent,
205
+ shellClassName: opts.shellClassName,
206
+ targetJreVersion: resolveJreVersion(opts.jdk),
207
+ debug: opts.debug,
208
+ byPassJavaModule: opts.byPassJavaModule,
209
+ shrink: opts.shrink,
210
+ staticInitialize: opts.staticInitialize,
211
+ lambdaSuffix: opts.lambdaSuffix
212
+ },
213
+ probeContentConfig: {
214
+ host: opts.host,
215
+ seconds: opts.seconds,
216
+ sleepServer: opts.sleepServer,
217
+ server: opts.server,
218
+ reqParamName: opts.reqParamName,
219
+ commandTemplate: opts.commandTemplate
220
+ },
221
+ packer: opts.packer
222
+ };
223
+ }
224
+
225
+ // src/core/output.ts
226
+ import { writeFileSync } from "fs";
227
+ var BINARY_EXTENSIONS = [".class", ".jar", ".zip", ".ser", ".bin"];
228
+ function hasBinaryExtension(path) {
229
+ const lower = path.toLowerCase();
230
+ return BINARY_EXTENSIONS.some((ext) => lower.endsWith(ext));
231
+ }
232
+ function shouldDecode(opts) {
233
+ if (opts.decode !== void 0) return opts.decode;
234
+ if (opts.outFile) return hasBinaryExtension(opts.outFile);
235
+ return false;
236
+ }
237
+ function emitPayload(payload, opts, sinks = {}) {
238
+ const writeFile = sinks.writeFile ?? ((p, d) => writeFileSync(p, d));
239
+ const writeStdout = sinks.writeStdout ?? ((d) => process.stdout.write(d));
240
+ const decoded = shouldDecode(opts);
241
+ if (opts.outFile) {
242
+ if (decoded) {
243
+ const buf = Buffer.from(payload, "base64");
244
+ writeFile(opts.outFile, buf);
245
+ return { destination: opts.outFile, size: buf.length, decoded: true };
246
+ }
247
+ writeFile(opts.outFile, payload);
248
+ return { destination: opts.outFile, size: Buffer.byteLength(payload), decoded: false };
249
+ }
250
+ if (decoded) {
251
+ const buf = Buffer.from(payload, "base64");
252
+ writeStdout(buf.toString("binary"));
253
+ return { destination: "stdout", size: buf.length, decoded: true };
254
+ }
255
+ writeStdout(payload.endsWith("\n") ? payload : `${payload}
256
+ `);
257
+ return { destination: "stdout", size: payload.length, decoded: false };
258
+ }
259
+
260
+ // src/core/config.ts
261
+ import { readFileSync } from "fs";
262
+ import { homedir } from "os";
263
+ import { join } from "path";
264
+ var DEFAULT_API_URL = "https://party.mem.mk";
265
+ var ENV_VAR = "MEMPARTY_API_URL";
266
+ function readRcFile(home) {
267
+ const path = join(home, ".mempartyrc");
268
+ try {
269
+ const raw = readFileSync(path, "utf8");
270
+ return JSON.parse(raw);
271
+ } catch {
272
+ return void 0;
273
+ }
274
+ }
275
+ function resolveApiUrl(input = {}) {
276
+ const env = input.env ?? process.env;
277
+ const home = input.home ?? homedir();
278
+ const fromFlag = input.flag?.trim();
279
+ if (fromFlag) return fromFlag;
280
+ const fromEnv = env[ENV_VAR]?.trim();
281
+ if (fromEnv) return fromEnv;
282
+ const fromFile = readRcFile(home)?.apiUrl?.trim();
283
+ if (fromFile) return fromFile;
284
+ return DEFAULT_API_URL;
285
+ }
286
+
287
+ // src/mcp/server.ts
288
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
289
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
290
+ import { z } from "zod";
291
+
292
+ // src/version.ts
293
+ import { createRequire } from "module";
294
+ var require2 = createRequire(import.meta.url);
295
+ var version = "0.0.0";
296
+ try {
297
+ version = require2("../package.json").version;
298
+ } catch {
299
+ try {
300
+ version = require2("./package.json").version;
301
+ } catch {
302
+ }
303
+ }
304
+ var CLI_VERSION = version;
305
+
306
+ // src/mcp/server.ts
307
+ function jsonContent(data) {
308
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
309
+ }
310
+ function errorContent(err) {
311
+ return {
312
+ isError: true,
313
+ content: [{ type: "text", text: `Error: ${err.message}` }]
314
+ };
315
+ }
316
+ var memShellInput = {
317
+ server: z.string().describe("Target server, e.g. Tomcat"),
318
+ serverVersion: z.string().optional(),
319
+ shellTool: z.string().describe("Shell tool, e.g. Godzilla, Behinder, Command"),
320
+ shellType: z.string().describe("Shell type, e.g. Listener, Filter, Servlet"),
321
+ packer: z.string().describe("Packer, e.g. Base64, Jar, JSP"),
322
+ jdk: z.string().optional().describe("java6/8/9/11/17/21 or class-file major version"),
323
+ debug: z.boolean().optional(),
324
+ byPassJavaModule: z.boolean().optional(),
325
+ shrink: z.boolean().optional(),
326
+ lambdaSuffix: z.boolean().optional(),
327
+ probe: z.boolean().optional(),
328
+ shellClassName: z.string().optional(),
329
+ godzillaPass: z.string().optional(),
330
+ godzillaKey: z.string().optional(),
331
+ behinderPass: z.string().optional(),
332
+ antSwordPass: z.string().optional(),
333
+ commandParamName: z.string().optional(),
334
+ commandTemplate: z.string().optional(),
335
+ encryptor: z.string().optional(),
336
+ implementationClass: z.string().optional(),
337
+ headerName: z.string().optional(),
338
+ headerValue: z.string().optional(),
339
+ shellClassBase64: z.string().optional(),
340
+ urlPattern: z.string().optional(),
341
+ injectorClassName: z.string().optional(),
342
+ staticInitialize: z.boolean().optional()
343
+ };
344
+ var probeInput = {
345
+ probeMethod: z.enum(["ResponseBody", "DNSLog", "Sleep"]),
346
+ probeContent: z.string().describe("BasicInfo, Server, OS, JDK, Bytecode, Command"),
347
+ packer: z.string(),
348
+ jdk: z.string().optional(),
349
+ debug: z.boolean().optional(),
350
+ byPassJavaModule: z.boolean().optional(),
351
+ shrink: z.boolean().optional(),
352
+ lambdaSuffix: z.boolean().optional(),
353
+ staticInitialize: z.boolean().optional(),
354
+ shellClassName: z.string().optional(),
355
+ host: z.string().optional(),
356
+ seconds: z.number().optional(),
357
+ sleepServer: z.string().optional(),
358
+ server: z.string().optional(),
359
+ reqParamName: z.string().optional(),
360
+ commandTemplate: z.string().optional()
361
+ };
362
+ function createMcpServer(client) {
363
+ const server = new McpServer({ name: "memshell-party", version: CLI_VERSION });
364
+ server.registerTool(
365
+ "list_servers",
366
+ { title: "List servers", description: "List supported servers and their shell types" },
367
+ async () => {
368
+ try {
369
+ return jsonContent(await client.getServers());
370
+ } catch (err) {
371
+ return errorContent(err);
372
+ }
373
+ }
374
+ );
375
+ server.registerTool(
376
+ "list_config",
377
+ {
378
+ title: "List full config",
379
+ description: "List every server's shell tools and their supported shell types"
380
+ },
381
+ async () => {
382
+ try {
383
+ return jsonContent(await client.getConfig());
384
+ } catch (err) {
385
+ return errorContent(err);
386
+ }
387
+ }
388
+ );
389
+ server.registerTool(
390
+ "list_packers",
391
+ { title: "List packers", description: "List packers as a parent/child tree" },
392
+ async () => {
393
+ try {
394
+ return jsonContent(await client.getPackerTree());
395
+ } catch (err) {
396
+ return errorContent(err);
397
+ }
398
+ }
399
+ );
400
+ server.registerTool(
401
+ "list_command_configs",
402
+ {
403
+ title: "List command configs",
404
+ description: "List Command-tool encryptors and implementation classes"
405
+ },
406
+ async () => {
407
+ try {
408
+ return jsonContent(await client.getCommandConfigs());
409
+ } catch (err) {
410
+ return errorContent(err);
411
+ }
412
+ }
413
+ );
414
+ server.registerTool(
415
+ "generate_memshell",
416
+ { title: "Generate memory shell", description: "Generate a Java memory shell payload", inputSchema: memShellInput },
417
+ async (args) => {
418
+ try {
419
+ const response = await client.generateMemShell(buildMemShellRequest(args));
420
+ return jsonContent(response);
421
+ } catch (err) {
422
+ return errorContent(err);
423
+ }
424
+ }
425
+ );
426
+ server.registerTool(
427
+ "generate_probe",
428
+ { title: "Generate probe shell", description: "Generate a probe/detection shell payload", inputSchema: probeInput },
429
+ async (args) => {
430
+ try {
431
+ const response = await client.generateProbe(buildProbeRequest(args));
432
+ return jsonContent(response);
433
+ } catch (err) {
434
+ return errorContent(err);
435
+ }
436
+ }
437
+ );
438
+ server.registerTool(
439
+ "parse_classname",
440
+ {
441
+ title: "Parse class name",
442
+ description: "Parse the fully-qualified class name from base64-encoded .class bytes",
443
+ inputSchema: { classBase64: z.string().describe("base64-encoded .class file bytes") }
444
+ },
445
+ async ({ classBase64 }) => {
446
+ try {
447
+ return jsonContent({ className: await client.parseClassName(classBase64) });
448
+ } catch (err) {
449
+ return errorContent(err);
450
+ }
451
+ }
452
+ );
453
+ server.registerTool(
454
+ "server_version",
455
+ { title: "Server version", description: "Get the backend server version info" },
456
+ async () => {
457
+ try {
458
+ return jsonContent(await client.getVersion());
459
+ } catch (err) {
460
+ return errorContent(err);
461
+ }
462
+ }
463
+ );
464
+ return server;
465
+ }
466
+ async function startMcpStdio(client) {
467
+ const server = createMcpServer(client);
468
+ const transport = new StdioServerTransport();
469
+ await server.connect(transport);
470
+ }
471
+ export {
472
+ ApiError,
473
+ CLI_VERSION,
474
+ DEFAULT_API_URL,
475
+ ENV_VAR,
476
+ JDK_VERSIONS,
477
+ MemPartyClient,
478
+ buildMemShellRequest,
479
+ buildProbeRequest,
480
+ createMcpServer,
481
+ emitPayload,
482
+ resolveApiUrl,
483
+ resolveJreVersion,
484
+ shouldDecode,
485
+ startMcpStdio
486
+ };
487
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/client.ts","../src/core/request-builder.ts","../src/core/jdk.ts","../src/core/output.ts","../src/core/config.ts","../src/mcp/server.ts","../src/version.ts"],"sourcesContent":["import type {\n ApiErrorResponse,\n CommandConfigVO,\n MainConfig,\n MemShellGenerateRequest,\n MemShellGenerateResponse,\n PackerTree,\n ProbeShellGenerateRequest,\n ProbeShellGenerateResponse,\n ServerConfig,\n VersionInfo,\n} from \"./types.js\";\n\nexport type FetchLike = typeof fetch;\n\n/** Error thrown when the API responds with a non-2xx status. */\nexport class ApiError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly url: string,\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n\nexport interface MemPartyClientOptions {\n /** Base URL of the MemShellParty backend, e.g. https://party.mem.mk */\n baseUrl: string;\n /** Injectable fetch implementation (defaults to global fetch). Useful for testing. */\n fetch?: FetchLike;\n /** Per-request timeout in milliseconds. Default 30000. */\n timeoutMs?: number;\n}\n\n/**\n * Typed client for the MemShellParty HTTP API.\n * Knows nothing about the CLI or MCP — it is a pure transport layer so every\n * entrypoint (flags, wizard, MCP) can share it.\n */\nexport class MemPartyClient {\n private readonly baseUrl: string;\n private readonly fetchImpl: FetchLike;\n private readonly timeoutMs: number;\n\n constructor(options: MemPartyClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.fetchImpl = options.fetch ?? globalThis.fetch;\n this.timeoutMs = options.timeoutMs ?? 30_000;\n if (typeof this.fetchImpl !== \"function\") {\n throw new Error(\n \"No fetch implementation available. Use Node.js >= 18 or pass a custom fetch.\",\n );\n }\n }\n\n // ---------- config ----------\n\n getServers(): Promise<ServerConfig> {\n return this.request<ServerConfig>(\"GET\", \"/api/config/servers\");\n }\n\n getConfig(): Promise<MainConfig> {\n return this.request<MainConfig>(\"GET\", \"/api/config\");\n }\n\n getPackerTree(): Promise<PackerTree> {\n return this.request<PackerTree>(\"GET\", \"/api/config/packers/tree\");\n }\n\n getPackers(): Promise<string[]> {\n return this.request<string[]>(\"GET\", \"/api/config/packers\");\n }\n\n getCommandConfigs(): Promise<CommandConfigVO> {\n return this.request<CommandConfigVO>(\"GET\", \"/api/config/command/configs\");\n }\n\n getVersion(): Promise<VersionInfo> {\n return this.request<VersionInfo>(\"GET\", \"/api/version\");\n }\n\n // ---------- generation ----------\n\n generateMemShell(req: MemShellGenerateRequest): Promise<MemShellGenerateResponse> {\n return this.request<MemShellGenerateResponse>(\"POST\", \"/api/memshell/generate\", {\n json: req,\n });\n }\n\n generateProbe(req: ProbeShellGenerateRequest): Promise<ProbeShellGenerateResponse> {\n return this.request<ProbeShellGenerateResponse>(\"POST\", \"/api/probe/generate\", {\n json: req,\n });\n }\n\n /** Parse a fully-qualified class name from a base64-encoded .class file. */\n parseClassName(classBase64: string): Promise<string> {\n return this.request<string>(\"POST\", \"/api/className\", {\n text: classBase64,\n raw: true,\n });\n }\n\n // ---------- transport ----------\n\n private async request<T>(\n method: string,\n path: string,\n opts: { json?: unknown; text?: string; raw?: boolean } = {},\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const headers: Record<string, string> = {};\n let body: string | undefined;\n\n if (opts.json !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n body = JSON.stringify(opts.json);\n } else if (opts.text !== undefined) {\n headers[\"Content-Type\"] = \"text/plain\";\n body = opts.text;\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let response: Response;\n try {\n response = await this.fetchImpl(url, {\n method,\n headers,\n body,\n signal: controller.signal,\n });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new ApiError(`Request timed out after ${this.timeoutMs}ms`, 0, url);\n }\n throw new ApiError(\n `Failed to reach ${url}: ${(err as Error).message}`,\n 0,\n url,\n );\n } finally {\n clearTimeout(timer);\n }\n\n const rawText = await response.text();\n\n if (!response.ok) {\n let message = rawText || response.statusText;\n try {\n const parsed = JSON.parse(rawText) as ApiErrorResponse;\n if (parsed?.error) message = parsed.error;\n } catch {\n // body was not JSON — keep raw text\n }\n throw new ApiError(message, response.status, url);\n }\n\n if (opts.raw) {\n return rawText as unknown as T;\n }\n if (rawText === \"\") {\n return undefined as unknown as T;\n }\n return JSON.parse(rawText) as T;\n }\n}\n","import { randomInt } from \"node:crypto\";\n\nimport type {\n MemShellGenerateRequest,\n ProbeShellGenerateRequest,\n} from \"../api/types.js\";\nimport { resolveJreVersion } from \"./jdk.js\";\n\n/**\n * Packers that require a randomised Spring expression injector class name.\n * Ported from web/app/utils/transformer.ts.\n */\nconst SPRING_GZIP_JDK17_RELATED_PACKERS = new Set([\n \"SpEL\",\n \"SpELSpringGzipJDK17\",\n \"OGNL\",\n \"OGNLSpringGzipJDK17\",\n \"JXPath\",\n \"JXPathSpringGzipJDK17\",\n]);\n\nconst UPPERCASE_LETTERS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nconst CLASS_NAME_LETTERS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\nfunction randomChar(chars: string): string {\n return chars[randomInt(chars.length)];\n}\n\nfunction generateSpringExpressionInjectorClassName(): string {\n const randomName = Array.from({ length: 5 }, () => randomChar(CLASS_NAME_LETTERS)).join(\"\");\n return `org.springframework.expression.${randomChar(UPPERCASE_LETTERS)}${randomName}Util`;\n}\n\n/** Flat option set for building a memshell request (from flags or the wizard). */\nexport interface MemShellOptions {\n server: string;\n serverVersion?: string;\n shellTool: string;\n shellType: string;\n packer: string;\n\n jdk?: string | number;\n debug?: boolean;\n byPassJavaModule?: boolean;\n shrink?: boolean;\n lambdaSuffix?: boolean;\n probe?: boolean;\n\n shellClassName?: string;\n godzillaPass?: string;\n godzillaKey?: string;\n commandParamName?: string;\n commandTemplate?: string;\n behinderPass?: string;\n antSwordPass?: string;\n headerName?: string;\n headerValue?: string;\n shellClassBase64?: string;\n encryptor?: string;\n implementationClass?: string;\n\n urlPattern?: string;\n injectorClassName?: string;\n staticInitialize?: boolean;\n}\n\nexport function buildMemShellRequest(opts: MemShellOptions): MemShellGenerateRequest {\n const injectorClassName = SPRING_GZIP_JDK17_RELATED_PACKERS.has(opts.packer)\n ? generateSpringExpressionInjectorClassName()\n : opts.injectorClassName;\n\n return {\n shellConfig: {\n server: opts.server,\n serverVersion: opts.serverVersion,\n shellTool: opts.shellTool,\n shellType: opts.shellType,\n targetJreVersion: resolveJreVersion(opts.jdk),\n debug: opts.debug,\n byPassJavaModule: opts.byPassJavaModule,\n shrink: opts.shrink,\n lambdaSuffix: opts.lambdaSuffix,\n probe: opts.probe,\n },\n shellToolConfig: {\n shellClassName: opts.shellClassName,\n godzillaPass: opts.godzillaPass,\n godzillaKey: opts.godzillaKey,\n commandParamName: opts.commandParamName,\n commandTemplate: opts.commandTemplate,\n behinderPass: opts.behinderPass,\n antSwordPass: opts.antSwordPass,\n headerName: opts.headerName,\n headerValue: opts.headerValue,\n shellClassBase64: opts.shellClassBase64,\n encryptor: opts.encryptor,\n implementationClass: opts.implementationClass,\n },\n injectorConfig: {\n injectorClassName,\n urlPattern: opts.urlPattern,\n staticInitialize: opts.staticInitialize,\n },\n packer: opts.packer,\n };\n}\n\n/** Flat option set for building a probe request. */\nexport interface ProbeOptions {\n probeMethod: string;\n probeContent: string;\n packer: string;\n\n shellClassName?: string;\n jdk?: string | number;\n debug?: boolean;\n byPassJavaModule?: boolean;\n shrink?: boolean;\n staticInitialize?: boolean;\n lambdaSuffix?: boolean;\n\n host?: string;\n seconds?: number;\n sleepServer?: string;\n server?: string;\n reqParamName?: string;\n commandTemplate?: string;\n}\n\nexport function buildProbeRequest(opts: ProbeOptions): ProbeShellGenerateRequest {\n return {\n probeConfig: {\n probeMethod: opts.probeMethod,\n probeContent: opts.probeContent,\n shellClassName: opts.shellClassName,\n targetJreVersion: resolveJreVersion(opts.jdk),\n debug: opts.debug,\n byPassJavaModule: opts.byPassJavaModule,\n shrink: opts.shrink,\n staticInitialize: opts.staticInitialize,\n lambdaSuffix: opts.lambdaSuffix,\n },\n probeContentConfig: {\n host: opts.host,\n seconds: opts.seconds,\n sleepServer: opts.sleepServer,\n server: opts.server,\n reqParamName: opts.reqParamName,\n commandTemplate: opts.commandTemplate,\n },\n packer: opts.packer,\n };\n}\n","/** Maps friendly JDK names to Java class-file major versions. */\nexport const JDK_VERSIONS: Record<string, number> = {\n java6: 50,\n java8: 52,\n java9: 53,\n java11: 55,\n java17: 61,\n java21: 65,\n};\n\n/**\n * Resolve a user-supplied JDK value into a class-file major version number.\n * Accepts friendly names (\"java8\", \"8\"), or a raw major version (\"52\").\n */\nexport function resolveJreVersion(input: string | number | undefined): number | undefined {\n if (input === undefined || input === \"\") return undefined;\n\n if (typeof input === \"number\") return input;\n\n const normalized = input.trim().toLowerCase();\n\n // Friendly name, e.g. \"java8\"\n if (normalized in JDK_VERSIONS) return JDK_VERSIONS[normalized];\n\n // Bare java number, e.g. \"8\" -> java8\n const withPrefix = `java${normalized}`;\n if (withPrefix in JDK_VERSIONS) return JDK_VERSIONS[withPrefix];\n\n // Raw class-file major version, e.g. \"52\"\n const num = Number(normalized);\n if (Number.isInteger(num) && num > 0) return num;\n\n throw new Error(\n `Invalid JDK version \"${input}\". Use one of: ${Object.keys(JDK_VERSIONS).join(\", \")}, or a class-file major version like 52.`,\n );\n}\n","import { writeFileSync } from \"node:fs\";\n\n/** File extensions whose payload is base64-encoded bytes and should be decoded. */\nconst BINARY_EXTENSIONS = [\".class\", \".jar\", \".zip\", \".ser\", \".bin\"];\n\nexport interface OutputOptions {\n /** Destination file path. When omitted, content goes to stdout. */\n outFile?: string;\n /** Force base64 decoding before writing (binary payload). */\n decode?: boolean;\n}\n\nexport interface OutputResult {\n /** Where the payload went: a file path, or \"stdout\". */\n destination: string;\n /** Number of bytes written (file) or characters printed (stdout). */\n size: number;\n /** Whether the payload was base64-decoded. */\n decoded: boolean;\n}\n\nfunction hasBinaryExtension(path: string): boolean {\n const lower = path.toLowerCase();\n return BINARY_EXTENSIONS.some((ext) => lower.endsWith(ext));\n}\n\n/**\n * Decide whether a payload should be base64-decoded before writing.\n * Explicit `decode` wins; otherwise infer from the output file extension.\n */\nexport function shouldDecode(opts: OutputOptions): boolean {\n if (opts.decode !== undefined) return opts.decode;\n if (opts.outFile) return hasBinaryExtension(opts.outFile);\n return false;\n}\n\n/**\n * Emit a payload string either to a file or to stdout.\n * Uses injectable sinks so it can be unit-tested without touching the real fs/stdout.\n */\nexport function emitPayload(\n payload: string,\n opts: OutputOptions,\n sinks: {\n writeFile?: (path: string, data: Buffer | string) => void;\n writeStdout?: (data: string) => void;\n } = {},\n): OutputResult {\n const writeFile = sinks.writeFile ?? ((p, d) => writeFileSync(p, d));\n const writeStdout = sinks.writeStdout ?? ((d) => process.stdout.write(d));\n const decoded = shouldDecode(opts);\n\n if (opts.outFile) {\n if (decoded) {\n const buf = Buffer.from(payload, \"base64\");\n writeFile(opts.outFile, buf);\n return { destination: opts.outFile, size: buf.length, decoded: true };\n }\n writeFile(opts.outFile, payload);\n return { destination: opts.outFile, size: Buffer.byteLength(payload), decoded: false };\n }\n\n // stdout\n if (decoded) {\n const buf = Buffer.from(payload, \"base64\");\n writeStdout(buf.toString(\"binary\"));\n return { destination: \"stdout\", size: buf.length, decoded: true };\n }\n writeStdout(payload.endsWith(\"\\n\") ? payload : `${payload}\\n`);\n return { destination: \"stdout\", size: payload.length, decoded: false };\n}\n","import { readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport const DEFAULT_API_URL = \"https://party.mem.mk\";\nexport const ENV_VAR = \"MEMPARTY_API_URL\";\n\nexport interface ResolveApiUrlInput {\n /** Value from the --api flag (highest priority). */\n flag?: string;\n /** Environment map (defaults to process.env). */\n env?: NodeJS.ProcessEnv;\n /** Home directory (defaults to os.homedir()). Injectable for tests. */\n home?: string;\n}\n\ninterface RcFile {\n apiUrl?: string;\n}\n\nfunction readRcFile(home: string): RcFile | undefined {\n const path = join(home, \".mempartyrc\");\n try {\n const raw = readFileSync(path, \"utf8\");\n return JSON.parse(raw) as RcFile;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resolve the API base URL by priority:\n * 1. --api flag\n * 2. MEMPARTY_API_URL env var\n * 3. ~/.mempartyrc { \"apiUrl\": \"...\" }\n * 4. default public site (https://party.mem.mk)\n */\nexport function resolveApiUrl(input: ResolveApiUrlInput = {}): string {\n const env = input.env ?? process.env;\n const home = input.home ?? homedir();\n\n const fromFlag = input.flag?.trim();\n if (fromFlag) return fromFlag;\n\n const fromEnv = env[ENV_VAR]?.trim();\n if (fromEnv) return fromEnv;\n\n const fromFile = readRcFile(home)?.apiUrl?.trim();\n if (fromFile) return fromFile;\n\n return DEFAULT_API_URL;\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\n\nimport { MemPartyClient } from \"../api/client.js\";\nimport { buildMemShellRequest } from \"../core/request-builder.js\";\nimport { buildProbeRequest } from \"../core/request-builder.js\";\nimport { CLI_VERSION } from \"../version.js\";\n\nfunction jsonContent(data: unknown) {\n return { content: [{ type: \"text\" as const, text: JSON.stringify(data, null, 2) }] };\n}\n\nfunction errorContent(err: unknown) {\n return {\n isError: true,\n content: [{ type: \"text\" as const, text: `Error: ${(err as Error).message}` }],\n };\n}\n\nconst memShellInput = {\n server: z.string().describe(\"Target server, e.g. Tomcat\"),\n serverVersion: z.string().optional(),\n shellTool: z.string().describe(\"Shell tool, e.g. Godzilla, Behinder, Command\"),\n shellType: z.string().describe(\"Shell type, e.g. Listener, Filter, Servlet\"),\n packer: z.string().describe(\"Packer, e.g. Base64, Jar, JSP\"),\n jdk: z.string().optional().describe(\"java6/8/9/11/17/21 or class-file major version\"),\n debug: z.boolean().optional(),\n byPassJavaModule: z.boolean().optional(),\n shrink: z.boolean().optional(),\n lambdaSuffix: z.boolean().optional(),\n probe: z.boolean().optional(),\n shellClassName: z.string().optional(),\n godzillaPass: z.string().optional(),\n godzillaKey: z.string().optional(),\n behinderPass: z.string().optional(),\n antSwordPass: z.string().optional(),\n commandParamName: z.string().optional(),\n commandTemplate: z.string().optional(),\n encryptor: z.string().optional(),\n implementationClass: z.string().optional(),\n headerName: z.string().optional(),\n headerValue: z.string().optional(),\n shellClassBase64: z.string().optional(),\n urlPattern: z.string().optional(),\n injectorClassName: z.string().optional(),\n staticInitialize: z.boolean().optional(),\n};\n\nconst probeInput = {\n probeMethod: z.enum([\"ResponseBody\", \"DNSLog\", \"Sleep\"]),\n probeContent: z.string().describe(\"BasicInfo, Server, OS, JDK, Bytecode, Command\"),\n packer: z.string(),\n jdk: z.string().optional(),\n debug: z.boolean().optional(),\n byPassJavaModule: z.boolean().optional(),\n shrink: z.boolean().optional(),\n lambdaSuffix: z.boolean().optional(),\n staticInitialize: z.boolean().optional(),\n shellClassName: z.string().optional(),\n host: z.string().optional(),\n seconds: z.number().optional(),\n sleepServer: z.string().optional(),\n server: z.string().optional(),\n reqParamName: z.string().optional(),\n commandTemplate: z.string().optional(),\n};\n\nexport function createMcpServer(client: MemPartyClient): McpServer {\n const server = new McpServer({ name: \"memshell-party\", version: CLI_VERSION });\n\n server.registerTool(\n \"list_servers\",\n { title: \"List servers\", description: \"List supported servers and their shell types\" },\n async () => {\n try {\n return jsonContent(await client.getServers());\n } catch (err) {\n return errorContent(err);\n }\n },\n );\n\n server.registerTool(\n \"list_config\",\n {\n title: \"List full config\",\n description: \"List every server's shell tools and their supported shell types\",\n },\n async () => {\n try {\n return jsonContent(await client.getConfig());\n } catch (err) {\n return errorContent(err);\n }\n },\n );\n\n server.registerTool(\n \"list_packers\",\n { title: \"List packers\", description: \"List packers as a parent/child tree\" },\n async () => {\n try {\n return jsonContent(await client.getPackerTree());\n } catch (err) {\n return errorContent(err);\n }\n },\n );\n\n server.registerTool(\n \"list_command_configs\",\n {\n title: \"List command configs\",\n description: \"List Command-tool encryptors and implementation classes\",\n },\n async () => {\n try {\n return jsonContent(await client.getCommandConfigs());\n } catch (err) {\n return errorContent(err);\n }\n },\n );\n\n server.registerTool(\n \"generate_memshell\",\n { title: \"Generate memory shell\", description: \"Generate a Java memory shell payload\", inputSchema: memShellInput },\n async (args) => {\n try {\n const response = await client.generateMemShell(buildMemShellRequest(args));\n return jsonContent(response);\n } catch (err) {\n return errorContent(err);\n }\n },\n );\n\n server.registerTool(\n \"generate_probe\",\n { title: \"Generate probe shell\", description: \"Generate a probe/detection shell payload\", inputSchema: probeInput },\n async (args) => {\n try {\n const response = await client.generateProbe(buildProbeRequest(args));\n return jsonContent(response);\n } catch (err) {\n return errorContent(err);\n }\n },\n );\n\n server.registerTool(\n \"parse_classname\",\n {\n title: \"Parse class name\",\n description: \"Parse the fully-qualified class name from base64-encoded .class bytes\",\n inputSchema: { classBase64: z.string().describe(\"base64-encoded .class file bytes\") },\n },\n async ({ classBase64 }) => {\n try {\n return jsonContent({ className: await client.parseClassName(classBase64) });\n } catch (err) {\n return errorContent(err);\n }\n },\n );\n\n server.registerTool(\n \"server_version\",\n { title: \"Server version\", description: \"Get the backend server version info\" },\n async () => {\n try {\n return jsonContent(await client.getVersion());\n } catch (err) {\n return errorContent(err);\n }\n },\n );\n\n return server;\n}\n\n/** Start the MCP server over stdio. */\nexport async function startMcpStdio(client: MemPartyClient): Promise<void> {\n const server = createMcpServer(client);\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","import { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\n\ninterface PkgJson {\n version: string;\n}\n\n// package.json sits one level above the built dist/ file and above src/ in dev.\nlet version = \"0.0.0\";\ntry {\n version = (require(\"../package.json\") as PkgJson).version;\n} catch {\n try {\n version = (require(\"./package.json\") as PkgJson).version;\n } catch {\n // fall back to placeholder\n }\n}\n\nexport const CLI_VERSION = version;\n"],"mappings":"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","names":["require"]}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "memshell-party-cli",
3
+ "version": "0.1.0",
4
+ "description": "Command-line client and MCP server for MemShellParty (party.mem.mk) — generate Java memory shells and probes from the terminal.",
5
+ "keywords": [
6
+ "memshell",
7
+ "memshellparty",
8
+ "security",
9
+ "redteam",
10
+ "cli",
11
+ "mcp",
12
+ "java"
13
+ ],
14
+ "type": "module",
15
+ "bin": {
16
+ "memparty": "dist/cli.js"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "scripts": {
27
+ "build": "tsup",
28
+ "dev": "tsup --watch",
29
+ "test": "vitest run",
30
+ "test:watch": "vitest",
31
+ "typecheck": "tsc --noEmit",
32
+ "start": "node dist/cli.js",
33
+ "prepublishOnly": "npm run build"
34
+ },
35
+ "dependencies": {
36
+ "@inquirer/prompts": "^7.2.1",
37
+ "@modelcontextprotocol/sdk": "^1.12.1",
38
+ "commander": "^12.1.0",
39
+ "zod": "^3.24.1"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^22.10.2",
43
+ "tsup": "^8.3.5",
44
+ "typescript": "^5.7.2",
45
+ "vitest": "^2.1.8"
46
+ },
47
+ "license": "MIT"
48
+ }