Agent Foskett Academy • KQL Academy • Module 12 • Lesson 150 • Endpoint Investigation

Lesson 150 — Building the Complete Endpoint Compromise Timeline

Nine investigations have followed the attack from one suspicious browser process through execution, file activity, outbound communication, persistence, credential-access evidence and a logon to another endpoint.

Now we stop investigating the clues in isolation. In the final lesson of Module 12, we use KQL to bring the evidence together chronologically and build the complete endpoint compromise timeline.

The final timeline is not a list of alerts. It is a sequence of evidence where every conclusion can be traced back to telemetry.
Agent Foskett KQL Academy complete endpoint compromise timeline
Your final case file

WS-FIN-042 began with a suspicious browser-to-PowerShell chain. The evidence now reaches another endpoint. Your task is to turn every clue into one defensible investigation story.

✓ Reconstruct execution evidence
✓ Add file and network activity
✓ Add persistence and Defender evidence
✓ Follow the account to the second device

Case briefing — Lessons 141 to 149

THE MODULE 12 CASE Lesson 141 — browser spawned PowerShell ↓ Lesson 142 — PowerShell command was encoded ↓ Lesson 143 — process tree was abnormal ↓ Lesson 144 — file appeared before execution ↓ Lesson 145 — process connected to an external IP ↓ Lesson 146 — scheduled task persistence ↓ Lesson 147 — Registry Run persistence ↓ Lesson 148 — LSASS-related credential-access evidence ↓ Lesson 149 — account logged on to another device ↓ LESSON 150 Build the complete endpoint compromise timeline

Investigation objective

Bring the strongest evidence from the Module 12 investigation into chronological order, distinguish observed facts from analytical conclusions and produce a defensible assessment of what happened on WS-FIN-042 and what should be investigated next.

Investigator's rule

Chronology is powerful because attackers create dependencies. A file must exist before it executes. Persistence follows execution. Credential access can precede account movement. The order helps test whether the working theory is plausible.

Stage 1 — rebuild the process story

Start with process telemetry. Reconstruct the execution sequence and preserve the account, command line and initiating process so the earliest part of the attack remains evidence-led.

01-rebuild-process-story.kql
12345678910111213
let TargetDevice = "WS-FIN-042";
let StartTime = datetime(2026-08-18 01:20:00);
let EndTime = datetime(2026-08-18 01:35:00);
DeviceProcessEvents
| where DeviceName =~ TargetDevice
| where Timestamp between (StartTime .. EndTime)
| project Timestamp,
          EvidenceType="Process",
          DeviceName,
          AccountName,
          Detail=strcat(FileName, " | ", ProcessCommandLine),
          Source=InitiatingProcessFileName
| order by Timestamp asc

Start with observed facts

Record what Defender observed before interpreting it: process name, command line, parent, account and timestamp. Terms such as “malicious execution” belong in the assessment only after the evidence supports them.

Preserve the chain

The browser-to-PowerShell relationship from Lesson 141 still matters at Lesson 150. Later evidence does not replace the first clue; it gives that clue additional context.

Stage 2 — add file and network evidence

Next, combine the file and network activity surrounding the suspicious execution. The objective is to show what appeared on disk and where the process communicated.

02-add-file-and-network-evidence.kql
123456789101112131415161718192021222324252627
let TargetDevice = "WS-FIN-042";
let StartTime = datetime(2026-08-18 01:20:00);
let EndTime = datetime(2026-08-18 01:35:00);
union
(
    DeviceFileEvents
    | where DeviceName =~ TargetDevice
    | where Timestamp between (StartTime .. EndTime)
    | project Timestamp,
              EvidenceType="File",
              DeviceName,
              AccountName=InitiatingProcessAccountName,
              Detail=strcat(ActionType, " | ", FolderPath, "\\", FileName),
              Source=InitiatingProcessFileName
),
(
    DeviceNetworkEvents
    | where DeviceName =~ TargetDevice
    | where Timestamp between (StartTime .. EndTime)
    | project Timestamp,
              EvidenceType="Network",
              DeviceName,
              AccountName=InitiatingProcessAccountName,
              Detail=strcat(RemoteIP, ":", tostring(RemotePort), " | ", RemoteUrl),
              Source=InitiatingProcessFileName
)
| order by Timestamp asc

Different tables, one story

DeviceFileEvents and DeviceNetworkEvents answer different questions. The timeline becomes useful when their timestamps and initiating-process context are correlated.

Do not hide uncertainty

If a URL, hash, source or process relationship is missing, leave the limitation visible. A defensible timeline is stronger when it distinguishes known evidence from unanswered questions.

Stage 3 — add persistence and credential-access evidence

Now add the Registry Run persistence clue and Defender alert evidence associated with the credential-access stage. These events explain how the investigation moved beyond initial execution.

03-add-persistence-and-alert-evidence.kql
12345678910111213141516171819202122232425262728
let TargetDevice = "WS-FIN-042";
let StartTime = datetime(2026-08-18 01:20:00);
let EndTime = datetime(2026-08-18 01:35:00);
union
(
    DeviceRegistryEvents
    | where DeviceName =~ TargetDevice
    | where Timestamp between (StartTime .. EndTime)
    | where RegistryKey contains @"\CurrentVersion\Run"
    | project Timestamp,
              EvidenceType="Registry persistence",
              DeviceName,
              AccountName=InitiatingProcessAccountName,
              Detail=strcat(RegistryValueName, " | ", RegistryValueData),
              Source=InitiatingProcessFileName
),
(
    AlertEvidence
    | where DeviceName =~ TargetDevice
    | where Timestamp between (StartTime .. EndTime)
    | project Timestamp,
              EvidenceType="Defender alert evidence",
              DeviceName,
              AccountName,
              Detail=strcat(FileName, " | ", ProcessCommandLine),
              Source=EvidenceRole
)
| order by Timestamp asc

Remember the scheduled task

Lesson 146 established another persistence mechanism. Depending on your environment and telemetry, scheduled-task evidence may come from process, alert or other endpoint records. Preserve that evidence separately if it cannot be represented faithfully in this query.

Detection is not outcome

The LSASS-related evidence supports a credential-access hypothesis, but it does not automatically prove that credentials were successfully extracted. Keep that distinction in the final report.

Stage 4 — add the account movement

Follow alex.wilson through endpoint logon telemetry and place the second-device authentication into the same incident window.

04-add-account-movement.kql
1234567891011121314
let TargetAccount = "alex.wilson";
let StartTime = datetime(2026-08-18 01:20:00);
let EndTime = datetime(2026-08-18 01:40:00);
DeviceLogonEvents
| where Timestamp between (StartTime .. EndTime)
| where AccountName =~ TargetAccount
| project Timestamp,
          EvidenceType="Logon",
          DeviceName,
          AccountName,
          Detail=strcat(ActionType, " | ", LogonType,
                        " | RemoteIP=", RemoteIP),
          Source=RemoteDeviceName
| order by Timestamp asc

The second endpoint changes scope

Once WS-HR-017 becomes part of the evidence, the investigation is no longer confined to WS-FIN-042. The destination device becomes a new hunting pivot.

Possible lateral movement

The timing may strongly support the hypothesis, particularly after suspected credential access, but the final wording should still reflect source, logon type and destination evidence actually available.

Stage 5 — create the consolidated hunting timeline

Finally, normalise several core hunting tables into a common structure and sort them by time. This produces an analyst-friendly view of the incident sequence while retaining the original table-specific evidence for deeper validation.

05-build-consolidated-endpoint-timeline.kql
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
let TargetDevice = "WS-FIN-042";
let TargetAccount = "alex.wilson";
let StartTime = datetime(2026-08-18 01:20:00);
let EndTime = datetime(2026-08-18 01:40:00);
union
(
    DeviceProcessEvents
    | where DeviceName =~ TargetDevice
    | where Timestamp between (StartTime .. EndTime)
    | project Timestamp, Stage="Execution",
              DeviceName, AccountName,
              Evidence=strcat(FileName, " | ", ProcessCommandLine)
),
(
    DeviceFileEvents
    | where DeviceName =~ TargetDevice
    | where Timestamp between (StartTime .. EndTime)
    | project Timestamp, Stage="File",
              DeviceName, AccountName=InitiatingProcessAccountName,
              Evidence=strcat(ActionType, " | ", FolderPath, "\\", FileName)
),
(
    DeviceNetworkEvents
    | where DeviceName =~ TargetDevice
    | where Timestamp between (StartTime .. EndTime)
    | project Timestamp, Stage="Network",
              DeviceName, AccountName=InitiatingProcessAccountName,
              Evidence=strcat(RemoteIP, ":", tostring(RemotePort), " | ", RemoteUrl)
),
(
    DeviceRegistryEvents
    | where DeviceName =~ TargetDevice
    | where Timestamp between (StartTime .. EndTime)
    | where RegistryKey contains @"\CurrentVersion\Run"
    | project Timestamp, Stage="Persistence",
              DeviceName, AccountName=InitiatingProcessAccountName,
              Evidence=strcat(RegistryValueName, " | ", RegistryValueData)
),
(
    DeviceLogonEvents
    | where AccountName =~ TargetAccount
    | where Timestamp between (StartTime .. EndTime)
    | project Timestamp, Stage="Authentication",
              DeviceName, AccountName,
              Evidence=strcat(ActionType, " | ", LogonType,
                              " | RemoteIP=", RemoteIP)
)
| order by Timestamp asc

Why normalise the columns?

Each Defender table has its own schema. Projecting common fields such as timestamp, stage, device, account and evidence makes cross-table chronology easier to review without pretending the underlying events are identical.

Keep the source queries

The consolidated timeline is a working investigation view, not a replacement for raw evidence. Preserve the focused queries and original records used to validate important findings.

Agent Foskett's complete endpoint compromise timeline

01:22:19 Browser → PowerShell ↓ ENCODED COMMAND Suspicious execution context established ↓ PROCESS TREE Ancestry does not match normal user behaviour ↓ FILE ACTIVITY File appears shortly before execution ↓ 01:22:24 Outbound connection to external destination ↓ 01:24:03 Scheduled-task persistence ↓ 01:25:11 Registry Run persistence ↓ 01:27:00 LSASS-related Defender evidence ↓ 01:31:12 alex.wilson logs on to WS-HR-017 ↓ FINAL ASSESSMENT Evidence supports endpoint compromise with persistence, suspected credential access and possible lateral movement
Nine separate clues became one investigation when we put them in the correct order.

Facts, hypotheses and conclusions

StatementClassificationWhy
A browser spawned PowerShell on WS-FIN-042.Observed factSupported directly by process telemetry.
A file appeared shortly before related execution.Observed factSupported by file and process timestamps.
The process communicated with an external destination.Observed factSupported by network telemetry.
Persistence was established.Supported conclusionScheduled-task and Registry Run evidence support persistence.
The attacker successfully stole credentials.Not establishedLSASS-related evidence supports suspicion but not necessarily successful extraction.
The account movement may represent lateral movement.Supported hypothesisTiming and second-device authentication warrant further investigation.
WS-FIN-042 was compromised.Defensible conclusionThe combined execution, file, network and persistence evidence supports compromise.

Write the final finding like an investigator

Example: Microsoft Defender XDR telemetry supports the assessment that WS-FIN-042 was compromised. The incident began with an abnormal browser-to-PowerShell execution chain that included encoded command-line activity. File telemetry recorded a file appearing shortly before execution, and network telemetry associated the suspicious process sequence with an outbound connection to an external destination. Subsequent evidence identified scheduled-task and Registry Run persistence. Defender later surfaced LSASS-related evidence consistent with suspected credential-access activity. Approximately four minutes later, the affected account, alex.wilson, authenticated to WS-HR-017. The available evidence supports confirmed endpoint compromise and persistence, suspected credential access and possible lateral movement. WS-HR-017 and subsequent account activity should be investigated before concluding that lateral movement or credential theft was successful.

What happens next?

A completed timeline should produce actions, not just a document. Preserve evidence, contain the affected endpoint where appropriate, remove confirmed persistence, investigate the second device, review the affected account and authentication activity, and hunt the strongest indicators across the wider environment in accordance with your organisation's incident-response process.

The timeline tells you what happened. The next pivots tell you how far it went.

Lesson 150 key takeaways

  • Build incident timelines from observed telemetry before writing conclusions.
  • Correlate process, file, network, registry, alert and authentication evidence chronologically.
  • Use common projected fields to make cross-table timelines easier to review.
  • Keep focused source queries and raw records for validation.
  • Distinguish observed facts, supported hypotheses and defensible conclusions.
  • Do not overstate credential-access evidence as confirmed credential theft.
  • A second-device authentication expands the investigation scope.
  • Multiple persistence mechanisms strengthen the endpoint-compromise assessment.
  • Document telemetry limitations instead of filling gaps with assumptions.
  • A defensible investigation is one where every important conclusion can be traced back to evidence.

Module 12 complete

You began Module 12 with one suspicious parent-child process relationship. Ten lessons later, you have followed the evidence through execution, process ancestry, files, network activity, persistence, credential-access evidence and possible lateral movement — then turned it into a complete investigation timeline.

Module 12 complete • Lesson 150 complete • The investigation is defensible because the evidence tells the story.

Continue your KQL investigation training

You have completed Module 12: Advanced Endpoint Investigation — Following the Attack Chain.

Related Agent Foskett Investigations

Keep practising the same evidence-led investigation method across endpoint, identity and Microsoft security telemetry.

🔎 KQL Academy — Module 12: Advanced Endpoint Investigation

Module complete — from the first suspicious process to a defensible endpoint compromise assessment.

Build an endpoint compromise timeline with KQL

Lesson 150 of the Agent Foskett KQL Academy brings Microsoft Defender XDR process, file, network, registry, alert and logon evidence together to reconstruct a complete endpoint compromise timeline.

Correlate Microsoft Defender XDR evidence across the attack chain

Learn how to distinguish facts from hypotheses, normalise evidence across hunting tables, preserve investigation limitations and write a defensible final endpoint compromise assessment.