BLA
BLA (Blind LLM Agents) is the open-source Blue Defense MCP and CLI built to protect software artifacts against automated AI reverse-engineering workflows.
Auditable TTP extraction, campaign clustering and ACH attribution with confidence grading
SecurityPython · TeXGitHub @rakshit-737OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Auditable ACH attribution for threat intel: span-anchored ATT&CK extraction, campaign clustering, and a leakage-controlled benchmark under planted, authentic and mimicked false flags
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Auditable attribution for threat intelligence: span-anchored ATT&CK extraction, campaign clustering, and Analysis of Competing Hypotheses that has to consider "unknown actor" and "someone framed X".
Contribution. An open, leakage-controlled benchmark for attack attribution under planted, authentic and mimicked false-flag evidence, plus an auditable ACH engine measured on it; the numbers, including where ACH loses, are in the table below.Read the full README ↗Auditable attribution for threat intelligence: span-anchored ATT&CK extraction, campaign clustering, and Analysis of Competing Hypotheses that has to consider "unknown actor" and "someone framed X".
Contribution. An open, leakage-controlled benchmark for attack attribution under planted, authentic and mimicked false-flag evidence, plus an auditable ACH engine measured on it; the numbers, including where ACH loses, are in the table below.
Docs: https://rakshit-737.github.io/occam-cti-attribution/ · Live demo: https://rakshit-737.github.io/occam-cti-attribution/demo/ · Evaluation: docs/evaluation.md · Preprint (PDF): https://rakshit-737.github.io/occam-cti-attribution/preprint.pdf (source)
Does automated ACH with mandatory disconfirming-evidence weighting give better-calibrated, less overconfident attribution than naive TTP-similarity matching, especially under false flags?
Mostly no. Its remaining advantage is an inspectable matrix with span-anchored evidence, which is a design property and is not measured here.
| Question (274 held-out ATT&CK incidents, 103 groups) | OCCAM ACH | Best simple baseline | Naive TTP-similarity |
|---|---|---|---|
| Framed group named, 3 planted spoofable markers | 1.1% [0.0–2.6] | 0% [0.0–3.6]† (similarity ignoring spoofable rows) | 88.0% [82.3–93.3] |
| Correct under planted markers (true group named or frame detected) | 73.4% [66.9–79.6] | 92.0% [88.4–95.2] (consistency gate, cross-fitted) | 11.3% [6.4–16.9] |
| Genuine markers wrongly called a frame-up | 18.6% [13.8–24.4] | 0% [0.0–3.6]† (similarity) / 23.0% [16.7–29.2] (gate) | 0% [0.0–3.6]† |
| Framed group named, mimicry of 3 rare TTPs/tools | 27.0% [21.3–33.5] | 32.1% [25.4–39.2] (IDF coverage) | 76.3% [70.9–81.8] |
| Correct under mimicry (true group named or frame detected) | 17.9% [12.2–23.8] | 28.8% [21.9–35.8] (IDF coverage) | 21.2% [15.5–27.0] |
| Correct "unknown" when the true group is untracked | 46.0% [39.3–53.1] (64.2% with a top-5 shortlist) | 93.4% [90.6–96.1] (decline below a cosine threshold matched to ACH's closed-world accuracy) | 0% [0.0–3.6]† |
| Closed-world top-1 | 29.9% [22.9–37.1] | 53.3% [45.3–60.8] (similarity) | 53.3% [45.3–60.8] |
| Brier, one setting-agnostic calibration map, closed + open + planted pooled (lower is better) | 0.214 [0.202–0.226] | 0.214 [0.203–0.226] (abstaining baseline) | 0.160 [0.141–0.178]; ACH minus it: +0.031 to +0.080 |
| Wrong at stated p ≥ 0.8, planted markers, raw outputs | 0/274 | 3/274 (similarity ignoring spoofable rows) | 194/274 |
| Closed / open / planted on 575 incidents, 21 campaigns, temporal splits | open and planted: same direction; closed: lower on 575 incidents (39.0% vs 47.8%), tied in temporal splits (extended); controls and mimicry not re-run there |
Brackets are 95% group-cluster bootstrap intervals, and paired differences use the same resamples. † marks a rate of exactly 0 or 1, where the bootstrap interval is degenerate; a Wilson interval with the 103 groups as the sample size is shown instead. Sources: results/falseflag.md / .json and results/attribution.md. Both were produced by bench run 37093689060 at commit 09cde53, and every benchmark result JSON records its run in provenance (the fitted map results/grade_calibration.json has none; it is written by the same bench_attribution.py run as results/attribution.json).
Browser: open the live workbench demo and click any matrix cell.
Docker (API + workbench on loopback only):
docker run --rm -p 127.0.0.1:8000:8000 ghcr.io/rakshit-737/occam-cti-attribution:latest # then open http://127.0.0.1:8000/
Python, zero dependencies:
git clone --depth 1 https://github.com/rakshit-737/occam-cti-attribution && cd occam
python -m pip install -e . && occam demo # or: python -m occam demo
occam ach false_flag_games # one bundled scenario
Expected output (abridged):
ASSESSMENT: It is roughly even chance / cannot be determined that: False flag: another actor framed ACTOR-EMBER
CONFIDENCE: LOW
False-flag indicators considered:
- Markers implicate ACTOR-EMBER, but hard evidence ['E5', 'E6', 'E7', 'E8', 'E9'] contradicts that actor.
flowchart TB
R["Report text"] --> EX["Span-anchored extraction"]
ATT[("ATT&CK profiles")] --> EX
EX --> EV["Graded evidence rows"]
EV --> ACH["ACH matrix"]
ATT --> ACH
AN["Analyst overrides"] --> ACH
ACH --> RANK["Least-inconsistency ranking"]
RANK --> CONF["Confidence caps"]
CONF --> OUT["CLI, STIX 2.1, API, workbench"]
A step-by-step walkthrough with the matrix is on How it works; design decisions are in docs/adr/.
| Module | Role | Extra deps |
|---|---|---|
occam/extract.py, occam/classifier.py | Span-anchored IOC/TTP/software extraction; optional TF-IDF + LR sentence classifier | none / ml |
occam/knowledge.py, occam/attack.py | ATT&CK STIX loader, group profiles, usage-based rarity | none |
occam/ach.py | Hypotheses, cell rating, diagnosticity, ranking, confidence caps, sensitivity; ablation switches | none |
occam/attribution.py | ACHAttributor and the similarity / IDF-coverage baselines | none |
occam/evaluation.py, occam/calibration.py | Held-out protocols (closed, open, false flag, authentic, mimicry, campaigns, temporal) and calibration | none |
occam/graph.py, occam/neo4j.py | Diamond graph, kNN-Louvain campaigns, Cypher export | graph |
occam/stix.py, occam/api.py, ui/ | STIX 2.1 export, FastAPI + read-only TAXII 2.1, React workbench | stix, api |
Every table is generated by scripts/bench_*.py from pinned public data. The JSON and Markdown are in results/, and each file names the GitHub Actions run and commit that produced it: bench run 37093689060 for all of them. The bench workflow regenerates them and lists any value that changed. The Evaluation page has every table with its methodology.
False flags, controls and ablations (results/falseflag.md).
Abstention trade-off (figure). ACH's operating point (29.9% closed-world top-1, 46.0% correct declines) lies inside the cosine-threshold baseline's frontier.
Threshold sensitivity (results/sensitivity.md). The cell-rule thresholds (common: ≥30% of groups; rare: ≤3 groups) were set by hand. Over a 3 x 3 grid:
| Metric | Range across the grid |
|---|---|
| Closed-world accuracy | 27.0–35.4% |
| Correct declines | 36.9–59.1% |
| Framed under planted markers | 0.7–1.1% |
| False alarms on genuine markers | 15.0–27.4% |
| Framed under mimicry | 24.8–36.1% |
Choosing the thresholds on one group fold and applying them to the other picks a 20% cut-off. Compared with the shipped thresholds, that choice:
Held-out attribution (results/attribution.md). Closed, open and false-flag settings on 274 incidents from 103 groups, with group-cluster CIs, per-setting and setting-agnostic calibration, and 5 framing seeds.
Extended protocols (results/attribution_extended.md). These cover all 575 report incidents, 21 held-out campaigns, 31 unattributed campaigns, and temporal splits (profiles from ATT&CK v12.1 / v15.1, incidents added later). The authentic, mimicry and simple-baseline controls were run only on the 274-incident set.
Reproduction of published TTP extraction (rcATT) (results/rcatt_reproduction.md).
TTP extraction on TRAM2 (results/extraction.md). TF-IDF + LR trained on ATT&CK procedures plus TRAM folds reaches document micro-F1 0.710 (document-bootstrap 95% CI 0.680–0.738; fold SD 0.023). Trained on ATT&CK procedures alone it reaches 0.618, and keywords reach 0.388. Two caveats:
Campaign clustering (results/clustering.md). On 270 held-out events from 36 groups:
| Method | ARI [95% group-jackknife interval] |
|---|---|
| kNN-Louvain | 0.249 [0.17–0.32] |
| Dense-graph Louvain, tuned the same way | 0.203 [0.14–0.26] |
| Single linkage | 0.107 |
The kNN-minus-dense ARI difference is −0.019 to +0.110, so the kNN step is not clearly justified. Across 10 input orders, kNN-Louvain gives ARI 0.248 ± 0.013.
End-to-end on 75 APTnotes reports (results/aptnotes.md).
results/aptnotes_clf_top10.md) hurts ACH: it drops to 0.160 (12 reports lost, none gained; McNemar p = 0.0005). Similarity is unchanged at 0.293 (p = 1.0).python -m pip install -e ".[dev,pdf,bench]"
python -m pytest -q # 80+ tests; real-data tests skip without the datasets
python scripts/download_data.py # ~400 MB, pinned + checksummed, into ../../datasets/occam or $OCCAM_DATA
D=../../datasets/occam
occam train-classifier --attack $D/enterprise-attack-19.2.json --tram $D/tram/multi_label.json --out model.pkl # ~26 min, ~340 MB
occam attribute occam/demo/reports/r3_tide_energy.txt --attack $D/enterprise-attack-19.2.json --classifier model.pkl
uvicorn occam.api:app --host 127.0.0.1 --port 8000 # API + workbench; cd ui && npm ci && npm run dev for the React dev server
occam attribute needs the classifier on real reports. With the full ATT&CK knowledge base, keyword extraction matches technique names only, so the bundled demo report yields a single evidence row (PsExec), and all 8 candidate groups tie at zero inconsistency. Exact commands, expected numbers and measured runtimes for every benchmark are on the Reproduce page.
Methods and frameworks.
Automated attribution and extraction.
OCCAM does not claim ACH or false-flag reasoning as new ideas. It automates ACH over ATT&CK and measures it against marker-aware baselines, controls and ablations.
Tools. MISP and OpenCTI store and share intelligence, ATT&CK Navigator visualises it, and TRAM and rcATT map text to ATT&CK. OCCAM emits Navigator layers and STIX and can sit beside them.
Full references are in paper/refs.bib. Each DOI, arXiv id and URL there is resolved by scripts/check_refs.py, with the outcome logged in paper/refs_check.log.
Attribution has diplomatic, legal and human consequences. OCCAM is decision support: every output says it needs human review, and results about real ATT&CK groups are benchmark artefacts, not findings. It reads text and JSON only, never contacts the infrastructure it describes, and never downloads malware. The API binds to 127.0.0.1, rejects foreign Host headers, caps request sizes and supports an optional bearer token. See THREAT_MODEL.md, SECURITY.md and CONTRIBUTING.md.
Cite via CITATION.cff. Code: MIT (LICENSE). ATT&CK® IDs and names are © The MITRE Corporation (ATT&CK Terms of Use); TRAM2 data is Apache-2.0 (CTID); rcATT data and preprocessing are MIT (V. Legoy); APTnotes reports are © their publishers and are not redistributed.