Some intrusions now move from reconnaissance to encryption in hours rather than weeks. A response that depends on a morning triage queue cannot keep up. Instead of looking for individual events, measure velocity: how many stages of the ransomware lifecycle appear on the same host or account inside a short window, and act automatically when that window is breached.
Signals at a Glance
| Stage | Typical early-warning evidence | ATT&CK |
|---|---|---|
| Discovery | nltest, net group, AdFind-style queries, share enumeration | T1087 |
| Credential access | LSASS access, NTDS or SAM extraction | T1003 |
| Defense evasion | Security tool disable, log clearing | T1562.001 |
| Lateral movement and deployment | PsExec, WMI, GPO or task fan-out | T1570 |
| Impact preparation and encryption | Backup deletion, mass file modification | T1486 |
Measuring Stage Velocity
Tag each relevant event with a lifecycle stage, then count distinct stages per host and per account in a rolling window. A single stage is administration. Three or more within hours is the pattern to treat as active ransomware preparation:
// Defender / Sentinel (KQL) - distinct lifecycle stages per device within 6 hours
let recon = DeviceProcessEvents
| where FileName in~ ("nltest.exe","net.exe","net1.exe","adfind.exe","dsquery.exe")
| where ProcessCommandLine has_any ("dclist","domain admins","trusted_domains","computer")
| extend Stage = "1-discovery";
let cred = DeviceEvents
| where ActionType == "OpenProcessApiCall" and FileName =~ "lsass.exe"
| extend Stage = "2-credential";
let evade = DeviceProcessEvents
| where ProcessCommandLine has_any ("DisableRealtimeMonitoring","Add-MpPreference","wevtutil cl")
| extend Stage = "3-evasion";
let impact = DeviceProcessEvents
| where ProcessCommandLine has_any ("delete shadows","delete catalog","recoveryenabled")
| extend Stage = "4-impact-prep";
union recon, cred, evade, impact
| summarize stages=make_set(Stage), n=dcount(Stage), first=min(Timestamp), last=max(Timestamp) by DeviceName, bin(Timestamp, 6h)
| where n >= 3
| extend minutes = datetime_diff('minute', last, first)
// tune/validate: replace tags with your own validated detections as inputs
Acting at the Speed of the Attack
- Measure your own mean time from alert to containment, and set automation thresholds below the intrusion speeds you are defending against.
- Automate reversible actions first: isolate the host, disable the account session, block the source. Keep deletion and wiping manual.
- Pre-approve containment for domain controllers and backup servers, since these are the assets you cannot afford to deliberate over.
- Record the timestamps of each stage in every case. Your own distribution of stage intervals is better than any published average.
The aim is not to predict encryption. It is to make the earlier stages expensive enough that the operator runs out of quiet time before the final one.
DFIR Report-style kill-chain analyses for stage ordering and timing, CISA #StopRansomware advisories for typical behaviours, MITRE CAR for sequence analytics, and Splunk ESCU risk-based content. Interval claims differ widely between incidents, so rely on your own case data and baseline your environment.
Build Detections That Fire
Mjolnir Security helps blue teams turn threat intelligence into high-fidelity detections across endpoint, network, identity and cloud telemetry.
- Detection Engineering We build and tune detections mapped to ATT&CK from your own telemetry.
- Threat Hunting as a Service Hypothesis-driven hunts for the behaviours on this page.
- 24/7 Incident Response Containment when a detection fires. Call +1 833 403 5875.
Stay ahead of emerging threats. Get notified when we publish new intelligence reports and advisories.
Subscribe to Alerts