feat: cloud / mobile / binary-RE offensive loadouts (arsenal + detection benchmarks)
Three new category loadouts, each = arsenal + an offline-scorable benchmark, opt-in and
honestly scoped (roster marks all 🚧; pacu/frida stay catalog_only, unit-tested non-mintable):
- cloud: aws/az/gcloud + scoutsuite/cloudfox/pmapper; cloud:bench IaC-misconfig detection
- mobile: apkleaks/mobsfscan/drozer/objection/class-dump; mobile:bench static ruleset
- binary/RE: ghidra/objdump/checksec/strings/readelf/gdb; binary:bench decompiled-sink detector
Mobile/binary benches are DETECTOR REGRESSION CHECKS (rules+fixtures co-authored — a pass is a
floor, not a detection rate). No new headline numbers; verify-claims 24/24.
tsc clean; 337 tests; lint 0 errors.
This commit is contained in:
1 parent
a5667374bf
commit
537d5345dc
17 files changed
+1026
No files matched your search
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Locks the Binary/RE loadout's decompiled-vuln detector + benchmark into CI: the ruleset must catch
|
||||
* every seeded memory-safety / injection sink in the corpus and stay clean on the bounded-function
|
||||
* controls (strncpy/snprintf/fgets, literal printf). Deterministic + self-contained.
|
||||
*/
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { loadCorpus, detect, scoreCorpus, RULES } from '../../scripts/binary-vuln-bench.mjs';
|
||||
|
||||
describe('binary/RE decompiled-vuln benchmark', () => {
|
||||
const corpus = loadCorpus();
|
||||
const score = scoreCorpus(corpus);
|
||||
|
||||
it('corpus has seeded sinks + safe controls with ground truth', () => {
|
||||
expect(corpus.fixtures.length).toBeGreaterThanOrEqual(6);
|
||||
expect(corpus.fixtures.some((f) => f.clean)).toBe(true);
|
||||
expect(corpus.fixtures.every((f) => f.clean || f.expect.length > 0)).toBe(true);
|
||||
});
|
||||
|
||||
it('detects every seeded sink', () => {
|
||||
expect(score.detection.hits).toBe(score.detection.total);
|
||||
expect(score.detection.total).toBeGreaterThanOrEqual(6);
|
||||
});
|
||||
|
||||
it('does not false-positive on bounded-function controls', () => {
|
||||
expect(score.discrimination.falsePositives).toBe(0);
|
||||
// the bounded equivalents must NOT trip the unbounded rules
|
||||
expect(detect('strncpy(buf, src, sizeof(buf) - 1);').size).toBe(0);
|
||||
expect(detect('snprintf(out, sizeof(out), "%s", x);').size).toBe(0);
|
||||
expect(detect('fgets(name, sizeof(name), stdin);').size).toBe(0);
|
||||
// ...but the unbounded ones must
|
||||
expect(detect('strcpy(buf, src);').has('B-STRCPY')).toBe(true);
|
||||
expect(detect('printf(user);').has('B-FORMAT-STRING')).toBe(true);
|
||||
});
|
||||
|
||||
it('ruleset spans memory-safety + injection + integer-overflow', () => {
|
||||
expect(RULES.length).toBeGreaterThanOrEqual(6);
|
||||
expect(RULES.some((r) => r.id === 'B-CMD-INJECTION')).toBe(true);
|
||||
expect(RULES.some((r) => r.id === 'B-INT-OVERFLOW')).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user