| name | indiscriminate-lateral-movement |
| description | Investigate whether an account is fanning out to an unusually large number of distinct hosts from a single source in a short time window (indiscriminate lateral movement). Use when given authentication log exports and asked to check for lateral movement, account compromise, worm-like spread, or "how many systems did this account touch." |
Indiscriminate Lateral Movement
MITRE ATT&CK: T1021 (Remote Services) — commonly .001 RDP, .002 SMB/Windows
Admin Shares, .006 WinRM, depending on the logon type observed.
1. Which question am I trying to answer?
Did account X authenticate to an unusually large number (Y) of distinct
systems in a given time window (Z) from a single source — consistent with
automated/indiscriminate spread rather than normal admin behavior?
2. Which direct evidence do I need?
Per authentication event: Time, Source, Destination, User, Success/Failure,
Logon Type. Distinct-destination fan-out from one source, per user, is the
core signal — logon type helps distinguish remote-execution-style access
(3, 10) from routine interactive use (2).
3. Where do I get that data?
- Windows Security.evtx (domain controllers and member servers): Event ID
4624 (success) / 4625 (failure), field Logon Type. Centralize via
Windows Event Forwarding or a SIEM (Splunk Authentication datamodel,
Sentinel SecurityEvent) — pulling from individual hosts one at a time
will miss the fan-out pattern.
- Linux:
/var/log/auth.log (Debian/Ubuntu) or /var/log/secure
(RHEL/CentOS) — Accepted password/Accepted publickey and Failed password lines.
- VPN/NPS/RADIUS logs if the source is remote access rather than
on-network.
- NetFlow/firewall logs can corroborate destination fan-out when host
logs are incomplete, but they don't carry
User, so they're a supporting
source, not a substitute for authentication logs.
4. How do I analyze that data to answer the question?
Export/normalize events into a CSV with columns: timestamp, user, source, destination, success, logon_type (see repo README for the shared schema).
Then run:
python3 scripts/analyze.py --input auth_events.csv \
--window-minutes 60 --min-destinations 5
Logic: for each (user, source) pair, slide a --window-minutes window over
successful logons and count distinct destinations touched inside it. A window
with distinct destinations at or above --min-destinations is flagged, with
the full destination list printed for review.
Tuning: the defaults (5 distinct hosts / 60 minutes) are a starting point,
not a universal constant. Jump boxes, RMM tools, and patch-management service
accounts routinely exceed this — baseline those accounts and either exclude
them or raise their personal threshold before trusting this against your
environment.
5. What answer does the analysis provide?
A list of (user, source, time window, destination count, destination list)
tuples where fan-out exceeded the threshold. This is evidence of a pattern
consistent with automated/indiscriminate lateral movement — it is not proof
of compromise on its own. Before escalating a flag, rule out:
- Known-legitimate fan-out sources: RMM/patch management, backup agents,
vulnerability scanners, and admin jump hosts — these are the dominant
false-positive driver for this analytic.
- Logon type mismatch: fan-out via type 2 (interactive) on many hosts is
a different (and often more concerning) story than type 3/10 — check which
logon types drove the flagged count.
- Time-of-day: fan-out during a scheduled maintenance window is lower
confidence than the same pattern at 3 a.m. local time for that user.
If those are ruled out, the finding supports pivoting to host-level triage
(process execution, new accounts, persistence) on the flagged destinations,
starting with the earliest one in the window.