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.
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
// 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.
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.
- Operator discovery → — the HASSH detector in depth
- Pivot surfaces → — start at any IP/ASN/fingerprint and find the rest of the campaign
- Browse active campaigns →