The Timeline Told The Story
The sign-in looked normal.
The data access looked normal.
The lateral movement looked normal.
The timeline changed everything.
The logs already knew.

Briefing summary
A single event can look normal. A timeline changes everything. When sign-ins, role changes, data access and device activity are placed in order, the investigation starts to explain itself.
Why the timeline matters
First hunt: start with the sign-in
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
IdentityLogonEvents | where Timestamp > ago(7d) | where AccountUpn has "user@domain.com" | project Timestamp, AccountUpn, Application, LogonType, IPAddress, DeviceName | order by Timestamp asc
Second hunt: look for privilege escalation
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
CloudAppEvents | where Timestamp > ago(7d) | where AccountDisplayName has "user" | where ActionType has_any ( "Add member to role", "Add member to group", "Consent to application", "Update user") | project Timestamp, AccountDisplayName, ActionType, Application, IPAddress, RawEventData | order by Timestamp asc
Third hunt: identify data access
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
CloudAppEvents | where Timestamp > ago(7d) | where AccountDisplayName has "user" | where ActionType has_any ( "FileDownloaded", "FileAccessed", "MailItemsAccessed", "SearchQueryPerformed") | project Timestamp, AccountDisplayName, ActionType, Application, IPAddress, ObjectName | order by Timestamp asc
Fourth hunt: check for lateral movement
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
DeviceNetworkEvents | where Timestamp > ago(7d) | where InitiatingProcessAccountUpn has "user@domain.com" | where RemotePort in (445, 3389, 5985, 5986) | project Timestamp, DeviceName, InitiatingProcessAccountUpn, InitiatingProcessFileName, RemoteUrl, RemoteIP, RemotePort | order by Timestamp asc
Fifth hunt: assemble the timeline
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
let TargetUser = "user@domain.com"; let SignIns = IdentityLogonEvents | where Timestamp > ago(7d) | where AccountUpn == TargetUser | project Timestamp, EventType = "Sign-in", Account = AccountUpn, Detail = Application, IPAddress, DeviceName; let CloudActions = CloudAppEvents | where Timestamp > ago(7d) | where AccountDisplayName has "user" | project Timestamp, EventType = ActionType, Account = AccountDisplayName, Detail = Application, IPAddress, DeviceName = "Cloud"; SignIns | union CloudActions | order by Timestamp asc
What the timeline can prove
The Agent Foskett investigator mindset
How GEMXIT approaches timeline investigations
Final thought
The timeline told the story.
The logs already knew.
It is: “What story does the timeline tell?”
Continue the investigation with The Logs Already Knew, The User Was Added To A Privileged Group At 3:12AM, The After-Hours Download, The VPN Login Continued After The Exit Meeting, KQL Threat Hunting, Microsoft Defender KQL Threat Hunting Complete Guide, Microsoft Defender and the GEMXIT Security Review.
Develop IT. Protect IT.GEMXIT PTY LTD | GEMXIT UK LTD
