Lab 02 — Tooling IOC / OPSEC Linter
Check a tooling inventory against an OPSEC checklist and return ranked findings with detection descriptions and per-tool noise scores.
What it builds
An OPSEC linter that ingests a list of tool configuration dicts (C2 agents, loaders, utilities) and checks each against a weighted checklist of known-default indicators. Returns a ranked findings list (HIGH → MEDIUM → LOW) with detection descriptions and a numeric noise score per tool.
Why it matters
OPSEC hygiene is measurable. Every default indicator has a public detection rule. This lab turns the OPSEC assessment from "gut feel" into a ranked, actionable report — the kind that goes in a Mandiant engagement appendix.
Files
| File | Purpose |
|---|---|
lab.py | Your implementation — fill in the TODO stubs |
solution.py | Reference implementation — all tests pass |
test_lab.py | Adversarial tests |
requirements.txt | pytest only — pure stdlib |
Running
LAB_MODULE=solution python3 -m pytest -q # 15 tests
python3 -m pytest -q # your implementation
API
lint(inventory: list[dict], known_bad_imphash: dict) -> list[dict]
# Returns list of {tool_name, noise_score, findings: [{check, severity, detection}]}
# Sorted: highest noise_score first
highest_risk_tool(linted: list[dict]) -> str
# Returns the tool_name with the highest noise_score
noise_score(findings: list[dict]) -> int
# HIGH=3, MEDIUM=2, LOW=1; sum of all finding weights
check_named_pipe(tool: dict) -> dict | None
check_user_agent(tool: dict) -> dict | None
check_imphash(tool: dict, known_bad: dict) -> dict | None
check_pdb(tool: dict) -> dict | None
check_sleep_jitter(tool: dict) -> dict | None
check_beacon_uri(tool: dict) -> dict | None