Skip to content

feat(asm): attack-surface management — external discovery, continuous monitoring, engagement - #198

Open
ehartford wants to merge 1 commit into
mainfrom
feat/asm-attack-surface
Open

feat(asm): attack-surface management — external discovery, continuous monitoring, engagement#198
ehartford wants to merge 1 commit into
mainfrom
feat/asm-attack-surface

Conversation

@ehartford

@ehartford ehartford commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Ports the discovery/continuity/engagement ideas from Sn1per into Clearwing — reimagined agentically and feeding Clearwing's existing deep scanning/verification, without copying Sn1per's shallow version-only detection (the false-positive firehose Clearwing exists to avoid).

Why

Clearwing is deep on a known target but had no way to discover what's out there, track what changes over time, or organize a surface across runs. scanner_tools only scans a host you already supply. This adds the missing front half.

What (new clearwing/asm/ subsystem + clearwing asm command)

Layer Module Notes
Asset inventory assets.py / scope.py Scope-keyed SQLite store modeled on HistoricalFindingsDB; record_observations returns only the new assets (delta detection).
Discovery discovery.py + agent/tools/recon/discovery_tools.py Passive-first, host-safe @tools: crt.sh cert transparency, Wayback, optional GitHub/Shodan/Censys, DNS resolution, HTTP liveness + tech fingerprint, screenshot gallery. Projected into the knowledge graph.
Continuous monitor monitor.py Poll loop (modeled on CommitMonitor): discover → delta → ASSET_DISCOVERED → scan new hosts. Never exploits or triggers approval-gated actions automatically.
Notifications notify.py Outbound Slack/webhook (the missing outbound half), subscribing to ASSET_DISCOVERED/FINDING_RECORDED, best-effort.
Threat intel threatintel.py CISA KEV + EPSS enrichment; findings sort KEV-first.
Mass sweep sweep.py Parallel port/service/vuln scan across a discovered surface.
Modes modes.py Named playbooks: recon, stealth, web-assessment, external-sweep.
Reporting report.py Per-scope aggregate markdown/json.

Wiring (additive, with baselines updated): an asm config section; EventType.ASSET_DISCOVERED + payload; knowledge-graph entity/relationship types (domain/subdomain/url/technology); the discovery tool category in get_all_tools(); the asm CLI subcommand (scan/monitor/sweep/report/list); read-only web endpoints + a WebSocket event.

Design choices

  • Passive-first / host-safe. Discovery queries public archives (crt.sh, Wayback, KEV, EPSS) exactly like the existing NVD/CVE lookups; light active steps (DNS, HTTP liveness) match proxy_request/scan_ports. Heavy active enum is left to the Kali container. ASM never auto-exploits.
  • Delta store vs. graph. The SQLite AssetStore is authoritative for "what's new since last run"; the knowledge graph is a queryable/visualizable projection.
  • No new scheduler. asm monitor is a poll loop (daemon or --once for cron / clearwing schedule) — the repo has no scheduler library.

Tests / docs

48 focused ASM tests (store delta, discovery, monitor, notifier, threat-intel, sweep, modes, report, CLI) — all green, plus shared-file regressions (events, tool registry, knowledge, config, webui, scanner, reporting) pass; ruff clean; two baseline tests updated for the new event + 6 new tools. Docs: docs/asm.md, a docs/cli.md section, README, mkdocs nav.

Note

This is a large single PR (~2.8k lines) by request — organized so each layer is an independent module with its own tests. Happy to split if the team prefers.

@ehartford
ehartford requested a review from ropoctl as a code owner August 29, 2026 08:58
Clearwing is deep on a known target but had no way to discover what's out
there, track what changes, or organize a surface across runs. This adds that
front half — reimagined agentically and feeding the existing deep scanning /
verification pipeline — ported from the ideas in Sn1per without its shallow
version-only detection.

New `clearwing/asm/` subsystem + a `clearwing asm` command:

- assets.py / scope.py — a scope-keyed SQLite AssetStore (modeled on
  HistoricalFindingsDB) with idempotent ingest and delta detection
  (record_observations returns only NEW assets), and a Scope engagement model.
- discovery.py + agent/tools/recon/discovery_tools.py — passive-first, host-safe
  discovery as pure-Python @tool functions: crt.sh certificate transparency,
  Wayback URL mining, optional GitHub/Shodan/Censys, DNS resolution, HTTP
  liveness + tech fingerprint, and a screenshot gallery. Orchestrated into a
  normalized asset hierarchy and projected into the knowledge graph.
- monitor.py — continuous ASM poll loop (modeled on CommitMonitor): each cycle
  discovers, records the delta, emits ASSET_DISCOVERED, and drives the existing
  port/service/vuln scanners on new hosts. Never exploits or triggers
  approval-gated actions automatically.
- notify.py — outbound Slack/generic webhook notifier (the missing outbound
  half), subscribing to ASSET_DISCOVERED / FINDING_RECORDED, best-effort.
- threatintel.py — CISA KEV + EPSS enrichment; findings sort KEV-first.
- sweep.py — mass parallel scanning across a discovered surface.
- modes.py — named playbooks (recon, stealth, web-assessment, external-sweep).
- report.py — per-scope aggregate markdown/json reports.

Wiring: an `asm` config section, EventType.ASSET_DISCOVERED + payload, knowledge
-graph entity/relationship types (domain/subdomain/url/technology), the
discovery tool category in get_all_tools(), the `asm` CLI subcommand
(scan/monitor/sweep/report/list), and read-only web endpoints + WebSocket event.

Tests: 48 focused ASM tests (store delta, discovery, monitor, notifier,
threat-intel, sweep, modes, report, CLI). Docs: docs/asm.md, a cli.md section,
README. Full ASM suite + shared-file regressions green; ruff clean.
@ehartford
ehartford force-pushed the feat/asm-attack-surface branch from 0b11d47 to 5c51032 Compare August 29, 2026 23:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant