blitzstrike 2.4.16 → 2.4.18

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/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ All notable changes to Blitz Strike are documented here.
5
5
  The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
+ ## [2.4.18] — 2026-09-14
9
+
10
+ ### Fixed — catalog placeholder installs (full audit)
11
+
12
+ - 3 Go tools that had a placeholder install now install for real:
13
+ cloudfox / ligolo-ng (`go install …@latest`), gophish (`go build`).
14
+ - 4 GUI/C2/versioned tools (havoc, ghidra, cutter, velociraptor) + burp-suite-mcp
15
+ are now flagged `installable: false` — bulk-install reports them as "manual
16
+ (install by hand)" instead of failing on a fake "download from github releases".
17
+ - `ensureTool` / `ensure_tool` now return `action: manual` + the note for these
18
+ tools instead of attempting the placeholder command.
19
+
20
+ ## [2.4.17] — 2026-09-14
21
+
22
+ ### Added — auto-provision toolchains + non-interactive installs
23
+
24
+ - Preflight now AUTO-PROVISIONS missing build toolchains (go, cargo, meson, ninja)
25
+ instead of only warning — `install-tools` installs them via apt before the
26
+ mass install, so `go install` / `meson build` / `ninja` no longer fail.
27
+ - All install commands now run with stdin closed (non-interactive) — prompts like
28
+ metasploit's "Overwrite? (y/N)" can no longer hang the run; `yes |` is piped
29
+ where an interactive confirm is required.
30
+
8
31
  ## [2.4.16] — 2026-09-14
9
32
 
10
33
  ### Added — auto-fallback install (toolchain provision + pip fallback)
package/dist/index.js CHANGED
@@ -7403,6 +7403,16 @@ import { join as join6 } from "node:path";
7403
7403
  import { fileURLToPath as fileURLToPath3 } from "node:url";
7404
7404
  import { homedir as homedir3 } from "node:os";
7405
7405
  import { spawnSync, spawn } from "node:child_process";
7406
+ function provisionMissingToolchains() {
7407
+ const missing = [];
7408
+ for (const [tc, inst] of Object.entries(TOOLCHAIN_INSTALL)) {
7409
+ if (hasCommand(tc))
7410
+ continue;
7411
+ missing.push(tc);
7412
+ spawnSync(inst, { shell: true, timeout: 300000, stdio: ["ignore", "pipe", "pipe"] });
7413
+ }
7414
+ return missing;
7415
+ }
7406
7416
  function hasCommand(cmd) {
7407
7417
  return spawnSync(`command -v ${cmd}`, { shell: true, timeout: 8000 }).status === 0;
7408
7418
  }
@@ -7425,11 +7435,11 @@ function provisionToolchain(cmd) {
7425
7435
  }
7426
7436
  function runInstallCommand(cmd, timeoutMs) {
7427
7437
  provisionToolchain(cmd);
7428
- let r = spawnSync(cmd, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR });
7438
+ let r = spawnSync(cmd, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR, stdio: ["ignore", "pipe", "pipe"] });
7429
7439
  let output = `${r.stdout?.toString() ?? ""}${r.stderr?.toString() ?? ""}`;
7430
7440
  if (r.status !== 0 && /--break-system-packages/.test(cmd)) {
7431
7441
  const alt = cmd.replace(/--break-system-packages/g, "--user");
7432
- const r2 = spawnSync(alt, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR });
7442
+ const r2 = spawnSync(alt, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR, stdio: ["ignore", "pipe", "pipe"] });
7433
7443
  if (r2.status === 0)
7434
7444
  r = r2;
7435
7445
  output = `${output}
@@ -7543,6 +7553,9 @@ function ensureTool(name) {
7543
7553
  if (!t) {
7544
7554
  return { found: false, query: name, suggestions: tools.slice(0, 5).map((x) => x.name) };
7545
7555
  }
7556
+ if (t.installable === false) {
7557
+ return { name: t.name, installed: false, action: "manual", note: t.note ?? "manual install (GUI/C2/versioned — install by hand)" };
7558
+ }
7546
7559
  const check = spawnSync(t.check_installed.command, { shell: true, timeout: 15000 });
7547
7560
  if (check.status !== 127 && check.error === undefined) {
7548
7561
  return { name: t.name, installed: true, action: "none", note: "already installed" };
@@ -7640,6 +7653,10 @@ function ensureToolAsync(name, timeoutMs = 300000) {
7640
7653
  resolve({ found: false, query: name });
7641
7654
  return;
7642
7655
  }
7656
+ if (t.installable === false) {
7657
+ resolve({ name: t.name, installed: false, action: "manual", note: t.note ?? "manual install (GUI/C2/versioned — install by hand)" });
7658
+ return;
7659
+ }
7643
7660
  const check = spawn(t.check_installed.command, { shell: true, timeout: 15000 });
7644
7661
  check.on("error", () => {});
7645
7662
  check.on("close", (code) => {
@@ -7654,7 +7671,7 @@ function ensureToolAsync(name, timeoutMs = 300000) {
7654
7671
  }
7655
7672
  mkdirSync3(TOOLS_DIR, { recursive: true });
7656
7673
  provisionToolchain(cmd);
7657
- const inst = spawn(cmd, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR });
7674
+ const inst = spawn(cmd, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR, stdio: ["ignore", "pipe", "pipe"] });
7658
7675
  let out = "";
7659
7676
  inst.stdout?.on("data", (d) => {
7660
7677
  out += d.toString();
@@ -7670,7 +7687,7 @@ function ensureToolAsync(name, timeoutMs = 300000) {
7670
7687
  }
7671
7688
  if (/--break-system-packages/.test(cmd)) {
7672
7689
  const alt = cmd.replace(/--break-system-packages/g, "--user");
7673
- const r2 = spawn(alt, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR });
7690
+ const r2 = spawn(alt, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR, stdio: ["ignore", "pipe", "pipe"] });
7674
7691
  let out2 = "";
7675
7692
  r2.stdout?.on("data", (d) => {
7676
7693
  out2 += d.toString();
@@ -7689,9 +7706,9 @@ function ensureToolAsync(name, timeoutMs = 300000) {
7689
7706
  }
7690
7707
  async function installAllTools(opts = {}) {
7691
7708
  const tools = loadTools();
7692
- const skippedMcp = tools.filter((t) => t.category === "mcp-server" && t.installable !== true).map((t) => t.name);
7709
+ const skippedManual = tools.filter((t) => t.installable === false).map((t) => t.name);
7693
7710
  const cat = opts.category?.toLowerCase();
7694
- const targets = tools.filter((t) => (t.category !== "mcp-server" || t.installable === true) && (!cat || t.category === cat));
7711
+ const targets = tools.filter((t) => t.installable !== false && (!cat || t.category === cat));
7695
7712
  const concurrency = Math.max(1, opts.concurrency ?? 4);
7696
7713
  const results = [];
7697
7714
  let idx = 0;
@@ -7713,7 +7730,7 @@ async function installAllTools(opts = {}) {
7713
7730
  installed,
7714
7731
  already_installed: already,
7715
7732
  failed,
7716
- skipped_mcp_servers: skippedMcp,
7733
+ skipped_manual: skippedManual,
7717
7734
  results
7718
7735
  };
7719
7736
  }
@@ -7724,7 +7741,9 @@ var init_catalog = __esm(() => {
7724
7741
  TOOLS_DIR = process.env.BLITZSTRIKE_TOOLS_DIR ?? join6(homedir3(), ".blitzstrike", "tools");
7725
7742
  TOOLCHAIN_INSTALL = {
7726
7743
  go: "apt-get install -y golang-go",
7727
- cargo: "apt-get install -y cargo"
7744
+ cargo: "apt-get install -y cargo",
7745
+ meson: "apt-get install -y meson",
7746
+ ninja: "apt-get install -y ninja-build"
7728
7747
  };
7729
7748
  _provisioned = new Set;
7730
7749
  });
@@ -16044,25 +16063,24 @@ async function runInstallTools(args) {
16044
16063
  await Promise.resolve().then(() => init_catalog());
16045
16064
  if (dryRun) {
16046
16065
  const tools = loadTools();
16047
- const mcp = tools.filter((t) => t.category === "mcp-server" && t.installable !== true);
16048
- const targets = tools.filter((t) => (t.category !== "mcp-server" || t.installable === true) && (!category || t.category === category.toLowerCase()));
16049
- console.log(`Dry run — would attempt ${targets.length} tool(s); ${mcp.length} MCP server(s) skipped (GUI/daemon — connect, not install):`);
16066
+ const manual = tools.filter((t) => t.installable === false);
16067
+ const targets = tools.filter((t) => t.installable !== false && (!category || t.category === category.toLowerCase()));
16068
+ console.log(`Dry run — would attempt ${targets.length} tool(s); ${manual.length} manual/skipped (GUI/C2/versioned — install by hand):`);
16050
16069
  for (const t of targets)
16051
16070
  console.log(` ${t.category.padEnd(11)} ${t.name}`);
16071
+ for (const t of manual)
16072
+ console.log(` [skip] ${t.name} — ${t.note ?? "manual install"}`);
16052
16073
  return;
16053
16074
  }
16054
16075
  console.log(`Installing catalog tools${category ? ` (category: ${category})` : ""} — concurrency ${concurrency}
16055
16076
  `);
16056
- const chainMap = { go: "golang", java: "default-jdk", python3: "python3", pip3: "python3-pip", cargo: "cargo", make: "build-essential", meson: "meson", ninja: "ninja-build", gcc: "build-essential", git: "git" };
16057
- const missingChains = Object.keys(chainMap).filter((c) => spawnSync5(`command -v ${c}`, { shell: true }).status !== 0);
16058
- if (missingChains.length) {
16059
- console.log(`⚠ Missing toolchains: ${missingChains.join(", ")} (${missingChains.map((c) => chainMap[c]).join(", ")})`);
16060
- console.log(` Tools that need them will FAIL below. Install first, e.g.:
16061
- apt install -y ${missingChains.map((c) => chainMap[c]).join(" ")}
16077
+ const provisioned = provisionMissingToolchains();
16078
+ if (provisioned.length) {
16079
+ console.log(`Provisioned missing toolchains: ${provisioned.join(", ")}
16062
16080
  `);
16063
16081
  }
16064
16082
  const tools = loadTools();
16065
- const totalTargets = tools.filter((t) => (t.category !== "mcp-server" || t.installable === true) && (!category || t.category === category.toLowerCase())).length;
16083
+ const totalTargets = tools.filter((t) => t.installable !== false && (!category || t.category === category.toLowerCase())).length;
16066
16084
  let done = 0;
16067
16085
  const r = await installAllTools({
16068
16086
  category,
@@ -16076,9 +16094,9 @@ async function runInstallTools(args) {
16076
16094
  });
16077
16095
  console.log(`
16078
16096
  Summary: ${r.target_count} targets · ${r.installed} newly installed · ${r.already_installed} already present · ${r.failed} failed`);
16079
- const mcp = r.skipped_mcp_servers;
16080
- if (mcp.length)
16081
- console.log(`Skipped MCP servers (connect them): ${mcp.join(", ")}`);
16097
+ const manual = r.skipped_manual;
16098
+ if (manual.length)
16099
+ console.log(`Skipped manual tools (GUI/C2/versioned — install by hand): ${manual.join(", ")}`);
16082
16100
  const failedList = r.results.filter((x) => x.installed !== true);
16083
16101
  if (failedList.length) {
16084
16102
  console.log(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blitzstrike",
3
- "version": "2.4.16",
3
+ "version": "2.4.18",
4
4
  "description": "Blitz Strike — a universal MCP security-audit toolbelt. BLITZ sweeps the attack surface, EAGLE-EYE traces source-to-sink, STRIKE verifies live. 57 attack chains, 130-tool catalog, intelligence data layer. One server, every agent.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2696,7 +2696,7 @@
2696
2696
  }
2697
2697
  ],
2698
2698
  "install": {
2699
- "linux": "download from github releases",
2699
+ "linux": "go install github.com/nicocha30/ligolo-ng@latest",
2700
2700
  "darwin": "manual",
2701
2701
  "win32": "manual"
2702
2702
  },
@@ -2823,7 +2823,9 @@
2823
2823
  ],
2824
2824
  "requires_root": false,
2825
2825
  "pipes": [],
2826
- "homepage": ""
2826
+ "homepage": "",
2827
+ "installable": false,
2828
+ "note": "C2 framework — source build (Go + Qt), manual setup"
2827
2829
  },
2828
2830
  {
2829
2831
  "name": "metasploit",
@@ -2846,7 +2848,7 @@
2846
2848
  }
2847
2849
  ],
2848
2850
  "install": {
2849
- "linux": "curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb | bash",
2851
+ "linux": "curl -sL https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb -o /tmp/msfinstall && chmod +x /tmp/msfinstall && yes | /tmp/msfinstall",
2850
2852
  "darwin": "brew install metasploit",
2851
2853
  "win32": "manual"
2852
2854
  },
@@ -2912,7 +2914,7 @@
2912
2914
  }
2913
2915
  ],
2914
2916
  "install": {
2915
- "linux": "download from github releases",
2917
+ "linux": "git clone --depth 1 https://github.com/gophish/gophish.git && cd gophish && go build && cp gophish /usr/local/bin/",
2916
2918
  "darwin": "manual",
2917
2919
  "win32": "manual"
2918
2920
  },
@@ -3477,7 +3479,9 @@
3477
3479
  "alternatives": [],
3478
3480
  "requires_root": false,
3479
3481
  "pipes": [],
3480
- "homepage": ""
3482
+ "homepage": "",
3483
+ "installable": false,
3484
+ "note": "DFIR agent — versioned binary download, manual"
3481
3485
  },
3482
3486
  {
3483
3487
  "name": "ghidra",
@@ -3512,7 +3516,9 @@
3512
3516
  ],
3513
3517
  "requires_root": false,
3514
3518
  "pipes": [],
3515
- "homepage": ""
3519
+ "homepage": "",
3520
+ "installable": false,
3521
+ "note": "GUI reverse-engineering suite (Java) — download from NSA GitHub releases, manual"
3516
3522
  },
3517
3523
  {
3518
3524
  "name": "radare2",
@@ -3627,7 +3633,9 @@
3627
3633
  ],
3628
3634
  "requires_root": false,
3629
3635
  "pipes": [],
3630
- "homepage": ""
3636
+ "homepage": "",
3637
+ "installable": false,
3638
+ "note": "GUI reverse-engineering suite (Rizin-based) — AppImage download, manual"
3631
3639
  },
3632
3640
  {
3633
3641
  "name": "gdb",
@@ -4841,7 +4849,7 @@
4841
4849
  }
4842
4850
  ],
4843
4851
  "install": {
4844
- "linux": "download from github releases",
4852
+ "linux": "go install github.com/BishopFox/cloudfox@latest",
4845
4853
  "darwin": "manual",
4846
4854
  "win32": "manual"
4847
4855
  },
@@ -5633,7 +5641,8 @@
5633
5641
  "requires_root": false,
5634
5642
  "pipes": [],
5635
5643
  "homepage": "https://github.com/PortSwigger/mcp-server",
5636
- "installable": false
5644
+ "installable": false,
5645
+ "note": "Java GUI (Burp) — build JAR + load in Burp Extensions, then connect SSE"
5637
5646
  }
5638
5647
  ]
5639
5648
  }