@remnux/mcp-server 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/LICENSE +674 -0
- package/README.md +720 -0
- package/dist/archive-extractor.d.ts +46 -0
- package/dist/archive-extractor.d.ts.map +1 -0
- package/dist/archive-extractor.js +268 -0
- package/dist/archive-extractor.js.map +1 -0
- package/dist/catalog/index.d.ts +40 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +114 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +154 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/archive-passwords.txt +3 -0
- package/dist/connectors/docker.d.ts +13 -0
- package/dist/connectors/docker.d.ts.map +1 -0
- package/dist/connectors/docker.js +201 -0
- package/dist/connectors/docker.js.map +1 -0
- package/dist/connectors/index.d.ts +27 -0
- package/dist/connectors/index.d.ts.map +1 -0
- package/dist/connectors/index.js +23 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/local.d.ts +10 -0
- package/dist/connectors/local.d.ts.map +1 -0
- package/dist/connectors/local.js +105 -0
- package/dist/connectors/local.js.map +1 -0
- package/dist/connectors/ssh.d.ts +21 -0
- package/dist/connectors/ssh.d.ts.map +1 -0
- package/dist/connectors/ssh.js +237 -0
- package/dist/connectors/ssh.js.map +1 -0
- package/dist/errors/error-mapper.d.ts +9 -0
- package/dist/errors/error-mapper.d.ts.map +1 -0
- package/dist/errors/error-mapper.js +24 -0
- package/dist/errors/error-mapper.js.map +1 -0
- package/dist/errors/remnux-error.d.ts +14 -0
- package/dist/errors/remnux-error.d.ts.map +1 -0
- package/dist/errors/remnux-error.js +19 -0
- package/dist/errors/remnux-error.js.map +1 -0
- package/dist/file-type-mappings.d.ts +30 -0
- package/dist/file-type-mappings.d.ts.map +1 -0
- package/dist/file-type-mappings.js +136 -0
- package/dist/file-type-mappings.js.map +1 -0
- package/dist/file-upload.d.ts +44 -0
- package/dist/file-upload.d.ts.map +1 -0
- package/dist/file-upload.js +170 -0
- package/dist/file-upload.js.map +1 -0
- package/dist/handlers/analyze-file.d.ts +10 -0
- package/dist/handlers/analyze-file.d.ts.map +1 -0
- package/dist/handlers/analyze-file.js +149 -0
- package/dist/handlers/analyze-file.js.map +1 -0
- package/dist/handlers/check-tools.d.ts +9 -0
- package/dist/handlers/check-tools.d.ts.map +1 -0
- package/dist/handlers/check-tools.js +47 -0
- package/dist/handlers/check-tools.js.map +1 -0
- package/dist/handlers/download-file.d.ts +10 -0
- package/dist/handlers/download-file.d.ts.map +1 -0
- package/dist/handlers/download-file.js +113 -0
- package/dist/handlers/download-file.js.map +1 -0
- package/dist/handlers/download-from-url.d.ts +30 -0
- package/dist/handlers/download-from-url.d.ts.map +1 -0
- package/dist/handlers/download-from-url.js +295 -0
- package/dist/handlers/download-from-url.js.map +1 -0
- package/dist/handlers/extract-archive.d.ts +10 -0
- package/dist/handlers/extract-archive.d.ts.map +1 -0
- package/dist/handlers/extract-archive.js +57 -0
- package/dist/handlers/extract-archive.js.map +1 -0
- package/dist/handlers/extract-iocs.d.ts +10 -0
- package/dist/handlers/extract-iocs.d.ts.map +1 -0
- package/dist/handlers/extract-iocs.js +21 -0
- package/dist/handlers/extract-iocs.js.map +1 -0
- package/dist/handlers/get-file-info.d.ts +10 -0
- package/dist/handlers/get-file-info.d.ts.map +1 -0
- package/dist/handlers/get-file-info.js +89 -0
- package/dist/handlers/get-file-info.js.map +1 -0
- package/dist/handlers/list-files.d.ts +10 -0
- package/dist/handlers/list-files.d.ts.map +1 -0
- package/dist/handlers/list-files.js +60 -0
- package/dist/handlers/list-files.js.map +1 -0
- package/dist/handlers/run-tool.d.ts +10 -0
- package/dist/handlers/run-tool.d.ts.map +1 -0
- package/dist/handlers/run-tool.js +99 -0
- package/dist/handlers/run-tool.js.map +1 -0
- package/dist/handlers/suggest-tools.d.ts +10 -0
- package/dist/handlers/suggest-tools.d.ts.map +1 -0
- package/dist/handlers/suggest-tools.js +202 -0
- package/dist/handlers/suggest-tools.js.map +1 -0
- package/dist/handlers/types.d.ts +15 -0
- package/dist/handlers/types.d.ts.map +1 -0
- package/dist/handlers/types.js +2 -0
- package/dist/handlers/types.js.map +1 -0
- package/dist/handlers/upload-file.d.ts +10 -0
- package/dist/handlers/upload-file.d.ts.map +1 -0
- package/dist/handlers/upload-file.js +33 -0
- package/dist/handlers/upload-file.js.map +1 -0
- package/dist/handlers/upload-from-host.d.ts +10 -0
- package/dist/handlers/upload-from-host.d.ts.map +1 -0
- package/dist/handlers/upload-from-host.js +33 -0
- package/dist/handlers/upload-from-host.js.map +1 -0
- package/dist/handlers/upload-sample.d.ts +10 -0
- package/dist/handlers/upload-sample.d.ts.map +1 -0
- package/dist/handlers/upload-sample.js +26 -0
- package/dist/handlers/upload-sample.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +254 -0
- package/dist/index.js.map +1 -0
- package/dist/ioc/extractor.d.ts +21 -0
- package/dist/ioc/extractor.d.ts.map +1 -0
- package/dist/ioc/extractor.js +91 -0
- package/dist/ioc/extractor.js.map +1 -0
- package/dist/ioc/known-values.d.ts +7 -0
- package/dist/ioc/known-values.d.ts.map +1 -0
- package/dist/ioc/known-values.js +43 -0
- package/dist/ioc/known-values.js.map +1 -0
- package/dist/ioc/noise.d.ts +6 -0
- package/dist/ioc/noise.d.ts.map +1 -0
- package/dist/ioc/noise.js +170 -0
- package/dist/ioc/noise.js.map +1 -0
- package/dist/ioc/patterns.d.ts +10 -0
- package/dist/ioc/patterns.d.ts.map +1 -0
- package/dist/ioc/patterns.js +65 -0
- package/dist/ioc/patterns.js.map +1 -0
- package/dist/ioc/scoring.d.ts +6 -0
- package/dist/ioc/scoring.d.ts.map +1 -0
- package/dist/ioc/scoring.js +69 -0
- package/dist/ioc/scoring.js.map +1 -0
- package/dist/parsers/capa.d.ts +9 -0
- package/dist/parsers/capa.d.ts.map +1 -0
- package/dist/parsers/capa.js +55 -0
- package/dist/parsers/capa.js.map +1 -0
- package/dist/parsers/diec.d.ts +9 -0
- package/dist/parsers/diec.d.ts.map +1 -0
- package/dist/parsers/diec.js +53 -0
- package/dist/parsers/diec.js.map +1 -0
- package/dist/parsers/floss.d.ts +14 -0
- package/dist/parsers/floss.d.ts.map +1 -0
- package/dist/parsers/floss.js +89 -0
- package/dist/parsers/floss.js.map +1 -0
- package/dist/parsers/index.d.ts +16 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +46 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/oleid.d.ts +8 -0
- package/dist/parsers/oleid.d.ts.map +1 -0
- package/dist/parsers/oleid.js +94 -0
- package/dist/parsers/oleid.js.map +1 -0
- package/dist/parsers/olevba.d.ts +8 -0
- package/dist/parsers/olevba.d.ts.map +1 -0
- package/dist/parsers/olevba.js +83 -0
- package/dist/parsers/olevba.js.map +1 -0
- package/dist/parsers/passthrough.d.ts +6 -0
- package/dist/parsers/passthrough.d.ts.map +1 -0
- package/dist/parsers/passthrough.js +13 -0
- package/dist/parsers/passthrough.js.map +1 -0
- package/dist/parsers/pdf-parser.d.ts +9 -0
- package/dist/parsers/pdf-parser.d.ts.map +1 -0
- package/dist/parsers/pdf-parser.js +76 -0
- package/dist/parsers/pdf-parser.js.map +1 -0
- package/dist/parsers/pdfid.d.ts +9 -0
- package/dist/parsers/pdfid.d.ts.map +1 -0
- package/dist/parsers/pdfid.js +56 -0
- package/dist/parsers/pdfid.js.map +1 -0
- package/dist/parsers/peframe.d.ts +8 -0
- package/dist/parsers/peframe.d.ts.map +1 -0
- package/dist/parsers/peframe.js +76 -0
- package/dist/parsers/peframe.js.map +1 -0
- package/dist/parsers/readelf.d.ts +8 -0
- package/dist/parsers/readelf.d.ts.map +1 -0
- package/dist/parsers/readelf.js +50 -0
- package/dist/parsers/readelf.js.map +1 -0
- package/dist/parsers/types.d.ts +30 -0
- package/dist/parsers/types.d.ts.map +1 -0
- package/dist/parsers/types.js +5 -0
- package/dist/parsers/types.js.map +1 -0
- package/dist/parsers/yara.d.ts +8 -0
- package/dist/parsers/yara.d.ts.map +1 -0
- package/dist/parsers/yara.js +88 -0
- package/dist/parsers/yara.js.map +1 -0
- package/dist/response.d.ts +44 -0
- package/dist/response.d.ts.map +1 -0
- package/dist/response.js +48 -0
- package/dist/response.js.map +1 -0
- package/dist/schemas/tools.d.ts +135 -0
- package/dist/schemas/tools.d.ts.map +1 -0
- package/dist/schemas/tools.js +53 -0
- package/dist/schemas/tools.js.map +1 -0
- package/dist/security/blocklist.d.ts +69 -0
- package/dist/security/blocklist.d.ts.map +1 -0
- package/dist/security/blocklist.js +148 -0
- package/dist/security/blocklist.js.map +1 -0
- package/dist/state/session.d.ts +35 -0
- package/dist/state/session.d.ts.map +1 -0
- package/dist/state/session.js +45 -0
- package/dist/state/session.js.map +1 -0
- package/dist/tools/definitions.d.ts +9 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +708 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/invoker.d.ts +17 -0
- package/dist/tools/invoker.d.ts.map +1 -0
- package/dist/tools/invoker.js +44 -0
- package/dist/tools/invoker.js.map +1 -0
- package/dist/tools/registry.d.ts +62 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +53 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/workflows/engine.d.ts +27 -0
- package/dist/workflows/engine.d.ts.map +1 -0
- package/dist/workflows/engine.js +224 -0
- package/dist/workflows/engine.js.map +1 -0
- package/dist/workflows/loader.d.ts +33 -0
- package/dist/workflows/loader.d.ts.map +1 -0
- package/dist/workflows/loader.js +130 -0
- package/dist/workflows/loader.js.map +1 -0
- package/dist/workflows/types.d.ts +109 -0
- package/dist/workflows/types.d.ts.map +1 -0
- package/dist/workflows/types.js +5 -0
- package/dist/workflows/types.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archive extraction module for REMnux MCP server
|
|
3
|
+
*
|
|
4
|
+
* Supports .zip, .7z, and .rar archives with automatic password detection.
|
|
5
|
+
* Passwords are tried from a configurable list for malware sample archives.
|
|
6
|
+
*/
|
|
7
|
+
import type { Connector } from "./connectors/index.js";
|
|
8
|
+
export type ArchiveType = "zip" | "7z" | "rar" | null;
|
|
9
|
+
export interface ExtractionResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
files: string[];
|
|
12
|
+
password?: string;
|
|
13
|
+
error?: string;
|
|
14
|
+
outputDir: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Detect archive type from filename extension
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectArchiveType(filename: string): ArchiveType;
|
|
20
|
+
/**
|
|
21
|
+
* Load password list from config file
|
|
22
|
+
* Returns default list if file not found
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadPasswordList(): string[];
|
|
25
|
+
/**
|
|
26
|
+
* Build extraction command for given archive type and tool
|
|
27
|
+
*
|
|
28
|
+
* @param archiveType - Type of archive (zip, 7z, rar)
|
|
29
|
+
* @param archivePath - Full path to archive file
|
|
30
|
+
* @param outputDir - Directory to extract files to
|
|
31
|
+
* @param password - Optional password for encrypted archives
|
|
32
|
+
* @returns Command array for execution
|
|
33
|
+
*/
|
|
34
|
+
export declare function getExtractionCommand(archiveType: ArchiveType, archivePath: string, outputDir: string, password?: string): string[];
|
|
35
|
+
/**
|
|
36
|
+
* Extract an archive file with automatic password detection
|
|
37
|
+
*
|
|
38
|
+
* @param connector - Connector to execute commands on REMnux
|
|
39
|
+
* @param archivePath - Full path to archive file inside REMnux
|
|
40
|
+
* @param samplesDir - Base samples directory for output
|
|
41
|
+
* @param customPassword - Optional password to try first
|
|
42
|
+
* @param outputSubdir - Optional subdirectory name (defaults to archive name without extension)
|
|
43
|
+
* @returns Extraction result with file list and password used
|
|
44
|
+
*/
|
|
45
|
+
export declare function extractArchive(connector: Connector, archivePath: string, samplesDir: string, customPassword?: string, outputSubdir?: string): Promise<ExtractionResult>;
|
|
46
|
+
//# sourceMappingURL=archive-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-extractor.d.ts","sourceRoot":"","sources":["../src/archive-extractor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,uBAAuB,CAAC;AAKnE,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC;AAEtD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAY/D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAgB3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,EAAE,CAwCV;AAgGD;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,MAAM,EACvB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,gBAAgB,CAAC,CAsG3B"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archive extraction module for REMnux MCP server
|
|
3
|
+
*
|
|
4
|
+
* Supports .zip, .7z, and .rar archives with automatic password detection.
|
|
5
|
+
* Passwords are tried from a configurable list for malware sample archives.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync } from "fs";
|
|
8
|
+
import { dirname, join, basename, extname, resolve, normalize } from "path";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
/**
|
|
13
|
+
* Detect archive type from filename extension
|
|
14
|
+
*/
|
|
15
|
+
export function detectArchiveType(filename) {
|
|
16
|
+
const ext = extname(filename).toLowerCase();
|
|
17
|
+
switch (ext) {
|
|
18
|
+
case ".zip":
|
|
19
|
+
return "zip";
|
|
20
|
+
case ".7z":
|
|
21
|
+
return "7z";
|
|
22
|
+
case ".rar":
|
|
23
|
+
return "rar";
|
|
24
|
+
default:
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Load password list from config file
|
|
30
|
+
* Returns default list if file not found
|
|
31
|
+
*/
|
|
32
|
+
export function loadPasswordList() {
|
|
33
|
+
const defaultPasswords = ["infected", "malware", "virus"];
|
|
34
|
+
try {
|
|
35
|
+
const passwordFile = join(__dirname, "config", "archive-passwords.txt");
|
|
36
|
+
const content = readFileSync(passwordFile, "utf-8");
|
|
37
|
+
const passwords = content
|
|
38
|
+
.split("\n")
|
|
39
|
+
.map((line) => line.trim())
|
|
40
|
+
.filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
41
|
+
return passwords.length > 0 ? passwords : defaultPasswords;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Fallback to defaults if file not found
|
|
45
|
+
return defaultPasswords;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Build extraction command for given archive type and tool
|
|
50
|
+
*
|
|
51
|
+
* @param archiveType - Type of archive (zip, 7z, rar)
|
|
52
|
+
* @param archivePath - Full path to archive file
|
|
53
|
+
* @param outputDir - Directory to extract files to
|
|
54
|
+
* @param password - Optional password for encrypted archives
|
|
55
|
+
* @returns Command array for execution
|
|
56
|
+
*/
|
|
57
|
+
export function getExtractionCommand(archiveType, archivePath, outputDir, password) {
|
|
58
|
+
// Validate inputs don't contain shell metacharacters
|
|
59
|
+
// This is defense-in-depth; the connector should also escape properly
|
|
60
|
+
if (password && /[;&|`$\n\r'"\\]/.test(password)) {
|
|
61
|
+
throw new Error("Password contains invalid characters");
|
|
62
|
+
}
|
|
63
|
+
switch (archiveType) {
|
|
64
|
+
case "7z":
|
|
65
|
+
// 7z x archive.7z -ooutputdir -ppassword -y
|
|
66
|
+
// -y: assume yes on all queries (non-interactive)
|
|
67
|
+
const cmd7z = ["7z", "x", archivePath, `-o${outputDir}`, "-y"];
|
|
68
|
+
if (password) {
|
|
69
|
+
cmd7z.push(`-p${password}`);
|
|
70
|
+
}
|
|
71
|
+
return cmd7z;
|
|
72
|
+
case "zip":
|
|
73
|
+
// unzip -P password -d outputdir archive.zip
|
|
74
|
+
// -o: overwrite without prompting
|
|
75
|
+
const cmdZip = ["unzip", "-o"];
|
|
76
|
+
if (password) {
|
|
77
|
+
cmdZip.push("-P", password);
|
|
78
|
+
}
|
|
79
|
+
cmdZip.push("-d", outputDir, archivePath);
|
|
80
|
+
return cmdZip;
|
|
81
|
+
case "rar":
|
|
82
|
+
// unrar x -ppassword archive.rar outputdir/
|
|
83
|
+
// -o+: overwrite existing files
|
|
84
|
+
const cmdRar = ["unrar", "x", "-o+"];
|
|
85
|
+
if (password) {
|
|
86
|
+
cmdRar.push(`-p${password}`);
|
|
87
|
+
}
|
|
88
|
+
cmdRar.push(archivePath, outputDir + "/");
|
|
89
|
+
return cmdRar;
|
|
90
|
+
default:
|
|
91
|
+
throw new Error(`Unsupported archive type: ${archiveType}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if extraction result indicates wrong password
|
|
96
|
+
*/
|
|
97
|
+
function isWrongPasswordError(result, _archiveType) {
|
|
98
|
+
const output = (result.stderr + result.stdout).toLowerCase();
|
|
99
|
+
// Common password error patterns across tools
|
|
100
|
+
const passwordErrors = [
|
|
101
|
+
"wrong password",
|
|
102
|
+
"incorrect password",
|
|
103
|
+
"bad password",
|
|
104
|
+
"password required",
|
|
105
|
+
"encrypted",
|
|
106
|
+
"need password",
|
|
107
|
+
"checksum error", // 7z uses this for wrong password
|
|
108
|
+
"crc failed", // unrar uses this for wrong password
|
|
109
|
+
];
|
|
110
|
+
// Check if exit code indicates failure AND output mentions password issues
|
|
111
|
+
if (result.exitCode !== 0) {
|
|
112
|
+
return passwordErrors.some((pattern) => output.includes(pattern));
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* List files in a directory
|
|
118
|
+
*/
|
|
119
|
+
async function listExtractedFiles(connector, outputDir) {
|
|
120
|
+
try {
|
|
121
|
+
const result = await connector.execute(["find", outputDir, "-type", "f", "-printf", "%P\\n"], { timeout: 30000 });
|
|
122
|
+
if (result.exitCode === 0 && result.stdout) {
|
|
123
|
+
return result.stdout
|
|
124
|
+
.split("\n")
|
|
125
|
+
.map((f) => f.trim())
|
|
126
|
+
.filter((f) => f.length > 0);
|
|
127
|
+
}
|
|
128
|
+
// Fallback to ls if find doesn't support -printf (e.g., BSD)
|
|
129
|
+
const lsResult = await connector.execute(["ls", "-1R", outputDir], { timeout: 30000 });
|
|
130
|
+
if (lsResult.exitCode === 0 && lsResult.stdout) {
|
|
131
|
+
return lsResult.stdout
|
|
132
|
+
.split("\n")
|
|
133
|
+
.map((f) => f.trim())
|
|
134
|
+
.filter((f) => f.length > 0 && !f.endsWith(":"));
|
|
135
|
+
}
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Validate that extracted files don't escape the sandbox (zip-slip protection)
|
|
144
|
+
* Malicious archives can contain entries like "../../../etc/cron.d/evil"
|
|
145
|
+
*
|
|
146
|
+
* @param files - Relative file paths from extraction
|
|
147
|
+
* @param outputDir - Expected output directory
|
|
148
|
+
* @returns Array of files that attempted path escape (empty if all safe)
|
|
149
|
+
*/
|
|
150
|
+
function validateExtractedPaths(files, outputDir) {
|
|
151
|
+
const escapeAttempts = [];
|
|
152
|
+
const normalizedBase = resolve(outputDir);
|
|
153
|
+
for (const file of files) {
|
|
154
|
+
// Check for obvious traversal patterns
|
|
155
|
+
if (file.includes("..") || file.startsWith("/")) {
|
|
156
|
+
escapeAttempts.push(file);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
// Resolve the full path and ensure it stays within outputDir
|
|
160
|
+
const resolvedPath = resolve(outputDir, normalize(file));
|
|
161
|
+
if (!resolvedPath.startsWith(normalizedBase + "/") && resolvedPath !== normalizedBase) {
|
|
162
|
+
escapeAttempts.push(file);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return escapeAttempts;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Extract an archive file with automatic password detection
|
|
169
|
+
*
|
|
170
|
+
* @param connector - Connector to execute commands on REMnux
|
|
171
|
+
* @param archivePath - Full path to archive file inside REMnux
|
|
172
|
+
* @param samplesDir - Base samples directory for output
|
|
173
|
+
* @param customPassword - Optional password to try first
|
|
174
|
+
* @param outputSubdir - Optional subdirectory name (defaults to archive name without extension)
|
|
175
|
+
* @returns Extraction result with file list and password used
|
|
176
|
+
*/
|
|
177
|
+
export async function extractArchive(connector, archivePath, samplesDir, customPassword, outputSubdir) {
|
|
178
|
+
// Detect archive type
|
|
179
|
+
const archiveType = detectArchiveType(archivePath);
|
|
180
|
+
if (!archiveType) {
|
|
181
|
+
return {
|
|
182
|
+
success: false,
|
|
183
|
+
files: [],
|
|
184
|
+
error: `Unsupported archive format: ${extname(archivePath)}`,
|
|
185
|
+
outputDir: "",
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
// Determine output directory
|
|
189
|
+
const archiveName = basename(archivePath, extname(archivePath));
|
|
190
|
+
const subdir = outputSubdir || archiveName;
|
|
191
|
+
const outputDir = join(samplesDir, subdir);
|
|
192
|
+
// Create output directory
|
|
193
|
+
const mkdirResult = await connector.execute(["mkdir", "-p", outputDir], {
|
|
194
|
+
timeout: 10000,
|
|
195
|
+
});
|
|
196
|
+
if (mkdirResult.exitCode !== 0) {
|
|
197
|
+
return {
|
|
198
|
+
success: false,
|
|
199
|
+
files: [],
|
|
200
|
+
error: `Failed to create output directory: ${mkdirResult.stderr}`,
|
|
201
|
+
outputDir,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
// Build password list to try
|
|
205
|
+
const passwordsToTry = [];
|
|
206
|
+
// 1. Custom password first if provided
|
|
207
|
+
if (customPassword) {
|
|
208
|
+
passwordsToTry.push(customPassword);
|
|
209
|
+
}
|
|
210
|
+
// 2. Try without password (archive might not be encrypted)
|
|
211
|
+
passwordsToTry.push(undefined);
|
|
212
|
+
// 3. Add passwords from config file
|
|
213
|
+
const configPasswords = loadPasswordList();
|
|
214
|
+
for (const pwd of configPasswords) {
|
|
215
|
+
if (pwd !== customPassword) {
|
|
216
|
+
// Avoid duplicates
|
|
217
|
+
passwordsToTry.push(pwd);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Try extraction with each password
|
|
221
|
+
let lastError = "";
|
|
222
|
+
for (const password of passwordsToTry) {
|
|
223
|
+
try {
|
|
224
|
+
const cmd = getExtractionCommand(archiveType, archivePath, outputDir, password);
|
|
225
|
+
const result = await connector.execute(cmd, { timeout: 120000 });
|
|
226
|
+
if (result.exitCode === 0) {
|
|
227
|
+
// Success! List extracted files
|
|
228
|
+
const files = await listExtractedFiles(connector, outputDir);
|
|
229
|
+
// Validate for zip-slip attacks (path traversal in archive entries)
|
|
230
|
+
const escapeAttempts = validateExtractedPaths(files, outputDir);
|
|
231
|
+
if (escapeAttempts.length > 0) {
|
|
232
|
+
// Clean up potentially malicious files
|
|
233
|
+
await connector.execute(["rm", "-rf", outputDir], { timeout: 30000 });
|
|
234
|
+
return {
|
|
235
|
+
success: false,
|
|
236
|
+
files: [],
|
|
237
|
+
error: `Archive contains path escape attempts (zip-slip): ${escapeAttempts.slice(0, 3).join(", ")}${escapeAttempts.length > 3 ? ` and ${escapeAttempts.length - 3} more` : ""}`,
|
|
238
|
+
outputDir,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
success: true,
|
|
243
|
+
files,
|
|
244
|
+
password: password, // undefined if no password was needed
|
|
245
|
+
outputDir,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
// Check if this is a password error
|
|
249
|
+
if (isWrongPasswordError(result, archiveType)) {
|
|
250
|
+
lastError = "Incorrect password";
|
|
251
|
+
continue; // Try next password
|
|
252
|
+
}
|
|
253
|
+
// Some other error - might still try other passwords for encrypted archives
|
|
254
|
+
lastError = result.stderr || result.stdout || "Unknown extraction error";
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
lastError = err instanceof Error ? err.message : "Extraction failed";
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// All passwords failed
|
|
261
|
+
return {
|
|
262
|
+
success: false,
|
|
263
|
+
files: [],
|
|
264
|
+
error: `Extraction failed: ${lastError}. Tried ${passwordsToTry.length} password(s).`,
|
|
265
|
+
outputDir,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=archive-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-extractor.js","sourceRoot":"","sources":["../src/archive-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Catalog — complete REMnux tool inventory from salt-states.
|
|
3
|
+
*
|
|
4
|
+
* Provides discovery of all ~200 tools on REMnux, complementing the
|
|
5
|
+
* smaller auto-run registry (~35 tools) used by analyze_file.
|
|
6
|
+
*/
|
|
7
|
+
export interface CatalogTool {
|
|
8
|
+
command: string;
|
|
9
|
+
name: string;
|
|
10
|
+
category: string;
|
|
11
|
+
description: string;
|
|
12
|
+
website: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ToolsIndex {
|
|
15
|
+
version: string;
|
|
16
|
+
updated: string;
|
|
17
|
+
tools: CatalogTool[];
|
|
18
|
+
}
|
|
19
|
+
declare class ToolCatalog {
|
|
20
|
+
private tools;
|
|
21
|
+
private byMcpCategory;
|
|
22
|
+
private bySaltCategory;
|
|
23
|
+
readonly version: string;
|
|
24
|
+
readonly updated: string;
|
|
25
|
+
constructor(index: ToolsIndex);
|
|
26
|
+
/** All tools in the catalog. */
|
|
27
|
+
all(): readonly CatalogTool[];
|
|
28
|
+
/** Tools matching an MCP file-type category (PE, PDF, OLE2, etc.). */
|
|
29
|
+
forMcpCategory(mcpCategory: string): CatalogTool[];
|
|
30
|
+
/** Tools matching a salt-states category string. */
|
|
31
|
+
forSaltCategory(saltCategory: string): CatalogTool[];
|
|
32
|
+
/** All unique salt-states categories. */
|
|
33
|
+
categories(): string[];
|
|
34
|
+
/** Total tool count. */
|
|
35
|
+
get size(): number;
|
|
36
|
+
}
|
|
37
|
+
/** Singleton catalog instance. */
|
|
38
|
+
export declare const toolCatalog: ToolCatalog;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/catalog/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AA0DD,cAAM,WAAW;IACf,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,cAAc,CAA6B;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,KAAK,EAAE,UAAU;IA0B7B,gCAAgC;IAChC,GAAG,IAAI,SAAS,WAAW,EAAE;IAI7B,sEAAsE;IACtE,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE;IAIlD,oDAAoD;IACpD,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,WAAW,EAAE;IAIpD,yCAAyC;IACzC,UAAU,IAAI,MAAM,EAAE;IAItB,wBAAwB;IACxB,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF;AAWD,kCAAkC;AAClC,eAAO,MAAM,WAAW,aAA+B,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Catalog — complete REMnux tool inventory from salt-states.
|
|
3
|
+
*
|
|
4
|
+
* Provides discovery of all ~200 tools on REMnux, complementing the
|
|
5
|
+
* smaller auto-run registry (~35 tools) used by analyze_file.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
8
|
+
import { resolve, dirname } from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
/**
|
|
11
|
+
* Maps salt-states categories to MCP file-type category names.
|
|
12
|
+
* Multiple salt-states categories can map to one MCP category.
|
|
13
|
+
*/
|
|
14
|
+
const SALT_TO_MCP_CATEGORY = {
|
|
15
|
+
// PE
|
|
16
|
+
"Examine Static Properties: PE Files": "PE",
|
|
17
|
+
"Statically Analyze Code: PE Files": "PE",
|
|
18
|
+
"Statically Analyze Code: Unpacking": "PE",
|
|
19
|
+
// .NET
|
|
20
|
+
"Examine Static Properties: .NET": "DOTNET",
|
|
21
|
+
"Statically Analyze Code: .NET": "DOTNET",
|
|
22
|
+
// PDF
|
|
23
|
+
"Analyze Documents: PDF": "PDF",
|
|
24
|
+
// Office (OLE2, OOXML, RTF share tools)
|
|
25
|
+
"Analyze Documents: Microsoft Office": "OLE2",
|
|
26
|
+
// ELF
|
|
27
|
+
"Examine Static Properties: ELF Files": "ELF",
|
|
28
|
+
"Dynamically Reverse-Engineer Code: ELF Files": "ELF",
|
|
29
|
+
// Scripts
|
|
30
|
+
"Statically Analyze Code: Scripts": "Script",
|
|
31
|
+
"Dynamically Reverse-Engineer Code: Scripts": "Script",
|
|
32
|
+
// Java/JAR
|
|
33
|
+
"Statically Analyze Code: Java": "JAR",
|
|
34
|
+
// Email
|
|
35
|
+
"Analyze Documents: Email Messages": "Email",
|
|
36
|
+
// Android/APK
|
|
37
|
+
"Statically Analyze Code: Android": "APK",
|
|
38
|
+
// General document analysis maps to OLE2 (broad category)
|
|
39
|
+
"Analyze Documents: General": "OLE2",
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Reverse map: MCP category → set of salt-states categories.
|
|
43
|
+
*/
|
|
44
|
+
const MCP_TO_SALT_CATEGORIES = new Map();
|
|
45
|
+
for (const [salt, mcp] of Object.entries(SALT_TO_MCP_CATEGORY)) {
|
|
46
|
+
const existing = MCP_TO_SALT_CATEGORIES.get(mcp) ?? [];
|
|
47
|
+
existing.push(salt);
|
|
48
|
+
MCP_TO_SALT_CATEGORIES.set(mcp, existing);
|
|
49
|
+
}
|
|
50
|
+
// OOXML and RTF share Office analysis tools with OLE2
|
|
51
|
+
const officeCats = MCP_TO_SALT_CATEGORIES.get("OLE2") ?? [];
|
|
52
|
+
MCP_TO_SALT_CATEGORIES.set("OOXML", [...officeCats]);
|
|
53
|
+
MCP_TO_SALT_CATEGORIES.set("RTF", [...officeCats]);
|
|
54
|
+
class ToolCatalog {
|
|
55
|
+
tools;
|
|
56
|
+
byMcpCategory;
|
|
57
|
+
bySaltCategory;
|
|
58
|
+
version;
|
|
59
|
+
updated;
|
|
60
|
+
constructor(index) {
|
|
61
|
+
this.tools = index.tools;
|
|
62
|
+
this.version = index.version;
|
|
63
|
+
this.updated = index.updated;
|
|
64
|
+
// Index by salt-states category
|
|
65
|
+
this.bySaltCategory = new Map();
|
|
66
|
+
for (const tool of this.tools) {
|
|
67
|
+
const existing = this.bySaltCategory.get(tool.category) ?? [];
|
|
68
|
+
existing.push(tool);
|
|
69
|
+
this.bySaltCategory.set(tool.category, existing);
|
|
70
|
+
}
|
|
71
|
+
// Index by MCP category
|
|
72
|
+
this.byMcpCategory = new Map();
|
|
73
|
+
for (const [mcpCat, saltCats] of MCP_TO_SALT_CATEGORIES) {
|
|
74
|
+
const tools = [];
|
|
75
|
+
for (const saltCat of saltCats) {
|
|
76
|
+
tools.push(...(this.bySaltCategory.get(saltCat) ?? []));
|
|
77
|
+
}
|
|
78
|
+
if (tools.length > 0) {
|
|
79
|
+
this.byMcpCategory.set(mcpCat, tools);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** All tools in the catalog. */
|
|
84
|
+
all() {
|
|
85
|
+
return this.tools;
|
|
86
|
+
}
|
|
87
|
+
/** Tools matching an MCP file-type category (PE, PDF, OLE2, etc.). */
|
|
88
|
+
forMcpCategory(mcpCategory) {
|
|
89
|
+
return this.byMcpCategory.get(mcpCategory) ?? [];
|
|
90
|
+
}
|
|
91
|
+
/** Tools matching a salt-states category string. */
|
|
92
|
+
forSaltCategory(saltCategory) {
|
|
93
|
+
return this.bySaltCategory.get(saltCategory) ?? [];
|
|
94
|
+
}
|
|
95
|
+
/** All unique salt-states categories. */
|
|
96
|
+
categories() {
|
|
97
|
+
return [...this.bySaltCategory.keys()].sort();
|
|
98
|
+
}
|
|
99
|
+
/** Total tool count. */
|
|
100
|
+
get size() {
|
|
101
|
+
return this.tools.length;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Load the bundled tools-index.json. */
|
|
105
|
+
function loadIndex() {
|
|
106
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
107
|
+
// data/ is at package root, two levels up from dist/catalog/ or src/catalog/
|
|
108
|
+
const indexPath = resolve(__dirname, "../../data/tools-index.json");
|
|
109
|
+
const raw = readFileSync(indexPath, "utf-8");
|
|
110
|
+
return JSON.parse(raw);
|
|
111
|
+
}
|
|
112
|
+
/** Singleton catalog instance. */
|
|
113
|
+
export const toolCatalog = new ToolCatalog(loadIndex());
|
|
114
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/catalog/index.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { startServer } from "./index.js";
|
|
3
|
+
function parseArgs() {
|
|
4
|
+
const args = process.argv.slice(2);
|
|
5
|
+
const config = {
|
|
6
|
+
mode: "docker",
|
|
7
|
+
container: "remnux",
|
|
8
|
+
samplesDir: "/home/remnux/files/samples",
|
|
9
|
+
outputDir: "/home/remnux/files/output",
|
|
10
|
+
timeout: 300,
|
|
11
|
+
noSandbox: true,
|
|
12
|
+
};
|
|
13
|
+
for (let i = 0; i < args.length; i++) {
|
|
14
|
+
let arg = args[i];
|
|
15
|
+
let value = args[i + 1];
|
|
16
|
+
let usedEqualsSyntax = false;
|
|
17
|
+
// Support --flag=value syntax: split on first '='
|
|
18
|
+
if (arg.startsWith("--") && arg.includes("=")) {
|
|
19
|
+
const eqIndex = arg.indexOf("=");
|
|
20
|
+
value = arg.slice(eqIndex + 1);
|
|
21
|
+
arg = arg.slice(0, eqIndex);
|
|
22
|
+
usedEqualsSyntax = true;
|
|
23
|
+
}
|
|
24
|
+
// Helper: only skip next arg if value came from separate arg (not '=' syntax)
|
|
25
|
+
const consumeValue = () => { if (!usedEqualsSyntax)
|
|
26
|
+
i++; };
|
|
27
|
+
switch (arg) {
|
|
28
|
+
case "--mode":
|
|
29
|
+
if (value === "docker" || value === "ssh" || value === "local") {
|
|
30
|
+
config.mode = value;
|
|
31
|
+
}
|
|
32
|
+
consumeValue();
|
|
33
|
+
break;
|
|
34
|
+
case "--container":
|
|
35
|
+
config.container = value;
|
|
36
|
+
consumeValue();
|
|
37
|
+
break;
|
|
38
|
+
case "--host":
|
|
39
|
+
config.host = value;
|
|
40
|
+
consumeValue();
|
|
41
|
+
break;
|
|
42
|
+
case "--user":
|
|
43
|
+
config.user = value;
|
|
44
|
+
consumeValue();
|
|
45
|
+
break;
|
|
46
|
+
case "--port":
|
|
47
|
+
config.port = parseInt(value, 10);
|
|
48
|
+
consumeValue();
|
|
49
|
+
break;
|
|
50
|
+
case "--password":
|
|
51
|
+
config.password = value;
|
|
52
|
+
consumeValue();
|
|
53
|
+
break;
|
|
54
|
+
case "--samples-dir":
|
|
55
|
+
config.samplesDir = value;
|
|
56
|
+
consumeValue();
|
|
57
|
+
break;
|
|
58
|
+
case "--output-dir":
|
|
59
|
+
config.outputDir = value;
|
|
60
|
+
consumeValue();
|
|
61
|
+
break;
|
|
62
|
+
case "--timeout":
|
|
63
|
+
config.timeout = parseInt(value, 10);
|
|
64
|
+
consumeValue();
|
|
65
|
+
break;
|
|
66
|
+
case "--sandbox":
|
|
67
|
+
config.noSandbox = false;
|
|
68
|
+
break;
|
|
69
|
+
case "--no-sandbox":
|
|
70
|
+
// Backwards compatibility — already the default
|
|
71
|
+
break;
|
|
72
|
+
case "--transport":
|
|
73
|
+
if (value === "stdio" || value === "http") {
|
|
74
|
+
config.transport = value;
|
|
75
|
+
}
|
|
76
|
+
consumeValue();
|
|
77
|
+
break;
|
|
78
|
+
case "--http-port":
|
|
79
|
+
config.httpPort = parseInt(value, 10);
|
|
80
|
+
consumeValue();
|
|
81
|
+
break;
|
|
82
|
+
case "--http-host":
|
|
83
|
+
config.httpHost = value;
|
|
84
|
+
consumeValue();
|
|
85
|
+
break;
|
|
86
|
+
case "--http-token":
|
|
87
|
+
config.httpToken = value;
|
|
88
|
+
consumeValue();
|
|
89
|
+
break;
|
|
90
|
+
case "--help":
|
|
91
|
+
case "-h":
|
|
92
|
+
printHelp();
|
|
93
|
+
process.exit(0);
|
|
94
|
+
case "--version":
|
|
95
|
+
case "-v":
|
|
96
|
+
console.log("remnux-mcp-server v0.1.0");
|
|
97
|
+
process.exit(0);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Read token from env var if not set via CLI
|
|
101
|
+
if (!config.httpToken && process.env.MCP_TOKEN) {
|
|
102
|
+
config.httpToken = process.env.MCP_TOKEN;
|
|
103
|
+
}
|
|
104
|
+
return config;
|
|
105
|
+
}
|
|
106
|
+
function printHelp() {
|
|
107
|
+
console.log(`
|
|
108
|
+
remnux-mcp-server - MCP server for REMnux malware analysis tools
|
|
109
|
+
|
|
110
|
+
USAGE:
|
|
111
|
+
remnux-mcp-server [OPTIONS]
|
|
112
|
+
|
|
113
|
+
OPTIONS:
|
|
114
|
+
--mode <mode> Connection mode: docker, ssh, or local (default: docker)
|
|
115
|
+
--container <name> Docker container name/ID (default: remnux)
|
|
116
|
+
--host <host> SSH host (for ssh mode)
|
|
117
|
+
--user <user> SSH user (default: remnux)
|
|
118
|
+
--port <port> SSH port (default: 22)
|
|
119
|
+
--password <pass> SSH password (uses SSH agent if omitted)
|
|
120
|
+
--samples-dir <path> Path to samples directory (default: /home/remnux/files/samples)
|
|
121
|
+
--output-dir <path> Path to output directory (default: /home/remnux/files/output)
|
|
122
|
+
--timeout <seconds> Default command timeout (default: 300)
|
|
123
|
+
--sandbox Enable path sandboxing (restrict files to samples/output dirs)
|
|
124
|
+
--no-sandbox No-op (sandbox is already off by default)
|
|
125
|
+
--transport <mode> Transport: stdio (default) or http
|
|
126
|
+
--http-port <port> HTTP port (default: 3000)
|
|
127
|
+
--http-host <host> HTTP bind address (default: 127.0.0.1)
|
|
128
|
+
--http-token <token> Bearer token for HTTP auth (also reads MCP_TOKEN env var)
|
|
129
|
+
-h, --help Show this help message
|
|
130
|
+
-v, --version Show version
|
|
131
|
+
|
|
132
|
+
EXAMPLES:
|
|
133
|
+
# Docker mode (default, stdio transport)
|
|
134
|
+
remnux-mcp-server --mode=docker --container=remnux
|
|
135
|
+
|
|
136
|
+
# SSH mode
|
|
137
|
+
remnux-mcp-server --mode=ssh --host=192.168.1.100 --user=remnux
|
|
138
|
+
|
|
139
|
+
# HTTP transport (Model B: server inside REMnux)
|
|
140
|
+
remnux-mcp-server --mode=local --transport=http --http-token=SECRET
|
|
141
|
+
|
|
142
|
+
# Add to Claude Code (stdio)
|
|
143
|
+
claude mcp add remnux --transport stdio -- npx remnux-mcp-server
|
|
144
|
+
|
|
145
|
+
For tool discovery and documentation, use the REMnux docs MCP:
|
|
146
|
+
https://docs.remnux.org/~gitbook/mcp
|
|
147
|
+
`);
|
|
148
|
+
}
|
|
149
|
+
// Start server
|
|
150
|
+
startServer(parseArgs()).catch((error) => {
|
|
151
|
+
console.error("Failed to start server:", error);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
});
|
|
154
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|