blitzstrike 2.4.166 → 2.4.168

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,35 @@ 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.168] — 2026-10-11
9
+
10
+ ### Fixed — blind_sqli_extract: space extraction + drift-proof time fallback
11
+
12
+ - Added SPACE (+ parens/comma) to the extraction linear-fallback charset, so
13
+ version/database strings with embedded spaces (e.g. "Microsoft SQL Server 2012")
14
+ extract fully instead of stopping at the first space.
15
+ - Auto-fall back to the TIME oracle when a marker-less byte-count boolean oracle
16
+ extracts nothing — the time oracle is deterministic and immune to page-size
17
+ drift on dynamic remote pages.
18
+ - Excluded WAF-sensitive chars (#, =, <, >, quotes, %, &, ;, |, *) from the
19
+ charset: a WAF that strips one of them turns the comparison into `= ''`
20
+ (always-true past the string end), which previously produced a false trailing run.
21
+
22
+ ## [2.4.167] — 2026-10-11
23
+
24
+ ### Fixed — blind_oracle detection false-negative + false-positive (real target)
25
+
26
+ - Added QUOTE/ERROR probes (`value'` / `value"`) to `blind_oracle`: a trailing
27
+ quote that turns a successful (2xx) request into a server error (5xx) is now a
28
+ `sql_error` signal — error-based SQLi is detected instead of being missed.
29
+ - Arithmetic/coercion "identity" now requires a SUCCESSFUL (2xx) baseline — an
30
+ error baseline (e.g. a file-include param where `value=1` already 500s) is no
31
+ longer misread as "evaluated arithmetically", killing a false positive on
32
+ non-SQL sinks.
33
+ - Verified no-hint on a live target (testasp.vulnweb.com): `id` (error-based
34
+ SQLi, previously 0 signals) now detected as `sql_error`; `item` (LFI, previously
35
+ 5 false SQL signals) now correctly 0.
36
+
8
37
  ## [2.4.166] — 2026-10-11
9
38
 
10
39
  ### Added — expanded WAF-bypass techniques (sqlmap + PayloadsAllTheThings)
package/dist/index.js CHANGED
@@ -62349,6 +62349,12 @@ function sstiProbes(value) {
62349
62349
  { sink: "ssti", name: "mustache_math", payload: `${value}{{7*7}}` }
62350
62350
  ];
62351
62351
  }
62352
+ function quoteProbes(value) {
62353
+ return [
62354
+ { sink: "sql_error", name: "single_quote", payload: `${value}'` },
62355
+ { sink: "sql_error", name: "double_quote", payload: `${value}"` }
62356
+ ];
62357
+ }
62352
62358
  function xssProbe(value, marker) {
62353
62359
  return { sink: "xss", name: "marker", payload: `${value}${marker}` };
62354
62360
  }
@@ -62363,14 +62369,20 @@ function timeProbes(dbms, value) {
62363
62369
  }
62364
62370
  function classifyBlindProbe(input) {
62365
62371
  const same = input.bodyHash === input.baselineHash;
62372
+ const baselineOk = input.baselineStatus >= 200 && input.baselineStatus < 400;
62366
62373
  let signal = false;
62367
62374
  let reason = "";
62368
- if (input.sink === "sql_arithmetic" && same) {
62375
+ if (input.sink === "sql_arithmetic" && same && baselineOk) {
62369
62376
  signal = true;
62370
- reason = "arithmetic identity returned the SAME result as the bare value — the parameter is evaluated arithmetically (SQL/expression context).";
62371
- } else if (input.sink === "sql_coercion" && same) {
62377
+ reason = "arithmetic identity returned the SAME result as the bare value (both succeeded) — the parameter is evaluated arithmetically (SQL/expression context).";
62378
+ } else if (input.sink === "sql_coercion" && same && baselineOk) {
62372
62379
  signal = true;
62373
62380
  reason = "type-coerced variant returned the SAME result — the parameter is normalized numerically (SQL typed column).";
62381
+ } else if (input.sink === "sql_error") {
62382
+ if (baselineOk && input.status >= 500) {
62383
+ signal = true;
62384
+ reason = `a trailing quote triggered a server error (HTTP ${input.status}) while the bare value succeeded (HTTP ${input.baselineStatus}) — the parameter is interpolated into a SQL string (error-based SQLi).`;
62385
+ }
62374
62386
  } else if (input.sink === "ssti" && !same && /49/.test(input.body)) {
62375
62387
  signal = true;
62376
62388
  reason = "the SSTI arithmetic (7*7) rendered as 49 in the response — the parameter reaches a template engine (SSTI).";
@@ -62401,8 +62413,10 @@ async function blindOracle(baseUrl, param, value, opts = {}) {
62401
62413
  return { error: "baseline fetch failed", base_url: base, param, detail: String(e) };
62402
62414
  }
62403
62415
  const probes = [];
62404
- if (sinks.includes("sql"))
62416
+ if (sinks.includes("sql")) {
62405
62417
  probes.push(...arithmeticProbes(value));
62418
+ probes.push(...quoteProbes(value));
62419
+ }
62406
62420
  if (sinks.includes("ssti"))
62407
62421
  probes.push(...sstiProbes(value));
62408
62422
  if (sinks.includes("xss"))
@@ -62421,8 +62435,10 @@ async function blindOracle(baseUrl, param, value, opts = {}) {
62421
62435
  const cls = classifyBlindProbe({
62422
62436
  baselineHash,
62423
62437
  baselineSize,
62438
+ baselineStatus,
62424
62439
  bodyHash,
62425
62440
  size: body.length,
62441
+ status,
62426
62442
  sink: p.sink,
62427
62443
  name: p.name,
62428
62444
  body,
@@ -62713,7 +62729,7 @@ async function blindSqliExtract(baseUrl, param, value, dbms, target, opts = {})
62713
62729
  }
62714
62730
  }
62715
62731
  }
62716
- const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}_/.-:@";
62732
+ const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}_/.-:@(), ";
62717
62733
  const caseInsensitive = p.dbms === "mysql" || p.dbms === "mssql";
62718
62734
  const bsCharset = caseInsensitive ? "0123456789abcdefghijklmnopqrstuvwxyz" : "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
62719
62735
  const baseTpl = (channel === "time" ? p.extraction.time : p.extraction.boolean).replace(/^'/, ctx);
@@ -62776,6 +62792,9 @@ async function blindSqliExtract(baseUrl, param, value, dbms, target, opts = {})
62776
62792
  out += ch;
62777
62793
  }
62778
62794
  out = out.trimEnd();
62795
+ if (out.length === 0 && channel === "boolean" && !marker) {
62796
+ return await blindSqliExtract(baseUrl, param, value, dbms, target, { ...opts, channel: "time" });
62797
+ }
62779
62798
  return {
62780
62799
  dbms,
62781
62800
  target,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blitzstrike",
3
- "version": "2.4.166",
3
+ "version": "2.4.168",
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": {