Features / Campaign detection
// Deep dive, for CTI practitioners

Five detectors, one pipeline

A coordinated operator can defeat any single clustering method. rotate subnets, spread across ASNs, vary targets. IntrusionLabs runs five detectors in parallel, each tuned to a different dimension of coordination. Operators that evade one method surface in another.

TL;DR

Every 5 minutes, the aggregation pipeline runs all five detectors and updates the campaign set. Right now 9,491 campaigns are active across the five types. Each detector has published thresholds — no black-box clustering, no hand-picked examples.

// What's active right now

Subnet (/24)
169
active
ASN + temporal
114
active
Target pattern
9,192
active
HASSH fingerprint
9
active
Scanner organization
7
active

// The five detectors

Detector Catches
Subnet (/24) Co-located infrastructure in a single /24 block
ASN + temporal Cross-subnet reuse inside one AS with time-correlated activity
Target pattern Multiple sources probing the same honeypots within a narrow window
HASSH fingerprint Distributed SSH tooling reuse across rented infrastructure
Scanner organization Known legitimate scanning providers, grouped for exclusion from threat views

Thresholds are the only tuning surface. Source: apps/threats/campaigns.py — constants at top of file.

// Why five detectors instead of one

A subnet detector misses distributed botnets. An ASN detector misses coordinated scans across clouds. A target-pattern detector misses operators that randomize targets. A HASSH detector misses operators that rotate SSH libraries. No single clustering method catches everything — but different methods have different blind spots.

Running all five in parallel means a coordinated operator needs to defeat every one of them simultaneously to stay uncategorized. That's a much harder OPSEC problem than defeating any single detector. The HASSH cluster written up in the HASSH launch post rotated across 10 ASNs and 74 countries — subnet and ASN detectors saw noise; HASSH collapsed the disguise.

The scanner-organization detector serves the opposite purpose: it clusters benign infrastructure (Censys, Shodan, Shadowserver, academic scanners) so they can be excluded from threat views instead of polluting the malicious signal.

// Detection cadence and lifecycle

  • Runs every 5 minutes via a systemd timer (intrusionlabs-aggregate.timer) on the aggregation pipeline.
  • 7-day lookback window for actor eligibility — stale actors don't inflate campaign size.
  • Idempotent updates — existing campaigns are updated in place; new ones are created; campaigns with no recent members close after 30 days of inactivity.
  • Every campaign carries a detection rationale — a short sentence explaining why these actors were grouped, stored on the campaign record and shown in the UI.
// Honest about limits

Thresholds are hand-tuned, not learned. They reflect what works on our current sensor footprint; a larger footprint would justify tighter thresholds. If you run IntrusionLabs data through your own pipeline and your thresholds are better, we want to know.

We don't yet run credential-fingerprint or JA4 detectors — both are tracked per session, both are good signals, neither has a campaign detector wired up yet. Tracked in GH #186.

// See also