Hands-on exercises

Reading a methodology and running one are different skills, and the gap between them only closes on cases. The three packets on this page are synthetic cases built for practice: realistic artifacts, tasks phased to the seven letters, and an answer key that stays sealed until you have written your own answers. They are deliberately not the three worked-example cases from the chapters, whose verdicts you already know.

How to work a packet

  • Write before you peek. Work every task in writing, actual close-note sentences, not mental bullet points. The traps this practice exists to catch (see Cognitive traps) live in the gap between “I basically know” and what ends up on the page.
  • Use the real templates. Where a task asks for a record, fill the corresponding downloadable template. The friction is the training.
  • Then open the key. Each key gives a model answer and names the traps planted in the packet. Your answer does not need to match it; it needs to survive comparison with it.
  • In a group, debrief out loud. The teaching guide has session plans, timings, and debrief questions for running these as workshops.

The downloads are learner packets: briefing, artifacts, and tasks, with no keys. Print them or drop them in your case-management sandbox; the keys live only on this page.


Exercise 1 · The print server’s new scheduled task

Full arc Guided 60-90 minutes

Briefing. Sunday, 03:41 UTC. You are the on-shift analyst. One alert is in the queue.

SIEM alert, 03:41:02 UTC
rule:      Scheduled task created by service account (rule-4698-svc)
severity:  Medium
host:      prt-01 (Windows Server 2019, print services)
event:     4698 (scheduled task created)
task name: \Microsoft\Windows\UpdateHealth
action:    powershell.exe -NoP -W Hidden -EncodedCommand JAB3AGMAPQBOAGUA...
principal: svc-printmgmt

Pulling the host’s authentication log and the proxy log for context gives you two more artifacts:

Authentication log excerpt, prt-01
03:22:17  4624  logon type 3 (network)            svc-printmgmt  from 10.20.8.114 (wkst-hr-22)
03:24:05  4624  logon type 10 (RemoteInteractive)  svc-printmgmt  from 10.20.8.114 (wkst-hr-22)
90-day baseline: svc-printmgmt appears on prt-01 as a service logon only;
no interactive or RDP logons on record
Proxy log excerpt
03:44:51  prt-01  CONNECT files-cdn-sync[.]net:443  allowed  bytes_out=2.1 MB
90-day baseline: prt-01 outbound is Windows Update and print-vendor telemetry only

Tasks. Work each phase in order. Write your answers before opening the key.

  1. Alert. State the claim the rule makes, and which detection mechanism this is. What is your first parsing action on the alert payload? Which of the three artifacts carries the most validation weight, and why?
  2. Subject. The named principal is a service account. Who acted? List the candidate answers and the evidence that discriminates between them. Run the four dimensions on what you decide the subject is.
  3. Scope. Draw the initial boundary: entities, time window, and lookback. Name one thing you are deliberately leaving out of scope, and the observation that would pull it in.
  4. Uncover. List the sources you would pull, in order, with the question each answers. What are the two questions your timeline must answer before Risk can score this? Where does your hypothesis ledger stand: what is the leading hypothesis, and what is the strongest surviving alternative?
  5. Risk. Score impact and likelihood separately, one paragraph of justification each. What does the matrix say?
  6. Escalation. Which canonical criteria are confirmed by a supplied artifact, and which are one query away? When does escalation fire, and under which rule?
  7. Documentation. Write the record’s summary paragraph. Then write one detection-engineering feedback item this case earns, and say which event it targets.
Answer key: Exercise 1

Alert. The rule claims a service account created a scheduled task, a rule-based detection on event 4698. First parsing action: decode the command, and honesty about what the packet actually contains is part of the answer. The alert carries only the payload’s opening characters: “JAB3AGMAPQBOAGUA…” decodes to “$wc=Ne”, consistent with “$wc = New-Object Net.WebClient”, a stock PowerShell downloader idiom, and consistent-with is a hypothesis, not a finding. The full decoded command, pulled from the 4698 event data, is this case’s first evidence request. The heaviest validation artifact is the authentication log: logon type 10 means someone opened an interactive RDP desktop as a service account, and the baseline says that has never happened in 90 days. Task-creation alerts are common; a service account with an RDP session is the anomaly that carries the case.

Subject. The principal on the alert is svc-printmgmt, but a service account is a credential, not an actor. Candidates: (a) an administrator legitimately using the account, (b) an automation process on wkst-hr-22, (c) a human attacker who has obtained the account’s credentials and is operating from wkst-hr-22. The logon type discriminates against (b): services and automation authenticate with network or service logons, not RemoteInteractive sessions at 03:24 on a Sunday. Between (a) and (c) the supplied artifacts cannot decide, both put a human on wkst-hr-22 holding the credential, and the checks that separate them (a change-ticket search, one message to the account’s owning team) are evidence requests the model answer states rather than presumes. The working subject is whoever was interactive on wkst-hr-22 at 03:24, acting through the service account. Four dimensions on that composite subject: authentication abnormal (first RemoteInteractive logon in the 90-day baseline), authorization unestablished (nothing supplied gives an HR-badged workstation a maintenance path to a print server, and no change record is in the packet; verify, do not assume), behavior abnormal (task creation, hidden-window encoded PowerShell), relationships now spanning two hosts and one service identity.

Scope. Entities: prt-01, svc-printmgmt, wkst-hr-22, and wkst-hr-22’s assigned user as a distinct fourth entity whose own compromise is now the leading question. Window: 03:00 UTC to now for the activity in front of you, with a longer lookback (7 days minimum) on wkst-hr-22, because if the credential was taken from that workstation, the theft happened at some earlier, unknown time; the lookback prices that hypothesis without asserting it. Deliberately out: the other print servers and every other host svc-printmgmt can reach, until Uncover produces evidence of contact; the observation that pulls them in is any successful authentication sourced from either host inside the window.

Uncover. Sources in order: the full decoded command from the 4698 event data (what the task actually runs), EDR on wkst-hr-22 (is it compromised, and what else has it touched), EDR on prt-01 (what has executed since 03:24), domain authentication logs filtered on svc-printmgmt and on wkst-hr-22 as source (spread, if any), proxy history for both hosts (what files-cdn-sync[.]net is to this network), and the change-management system (does anything authorize weekend work on prt-01). The timeline’s two required answers: how did whoever was on wkst-hr-22 come to hold service-account credentials, and what has executed on prt-01 since 03:24. Leading hypothesis: hands-on-keyboard use of the account from a compromised workstation, with the scheduled task as persistence. Strongest surviving alternative: an administrator doing undocumented weekend maintenance from a borrowed desk. Nothing in the packet kills it, no artifact shows the ticket search coming back empty or the owning team denying the session, so the ledger holds it open, names the two checks that would settle it, and records “cannot determine yet” beside it. An answer that buries the alternative under an assumed empty ticket queue fails this phase.

Risk. Impact high: an actor with working service-account credentials and interactive access on a server is positioned to reach anything that account and host can touch; print servers commonly hold broad connectivity plus credential material in spooler and vendor services. Likelihood follows the evidence, and the evidence is strong but not closed: the chain (first-in-baseline RemoteInteractive logon, task named to mimic an OS component, hidden-window encoded PowerShell, 2.1 MB outbound to a domain absent from a 90-day baseline) is multi-source and artifact-backed, but High requires independent sources corroborating malicious behavior, and what they corroborate so far is an anomaly whose one benign explanation is untested. The honest score is Medium, with the upgrade triggers named: the decoded command resolving to a downloader, an empty change-ticket search, or the owning team denying the session. High × Medium: P2, escalate within the shift. Scoring likelihood High here requires facts the packet does not contain, and writing “no surviving benign explanation” over a live alternative is the exact move the ledger exists to prevent.

Escalation. Confirmed by a supplied artifact: none, and writing that sentence is the graded move. The type 10 logon confirms an interactive hop as a service account, an artifact-backed anomaly, but lateral movement as a canonical criterion means attacker expansion, which requires the administrator alternative dead first. Confirmed malicious activity requires the decoded command or destination intelligence on files-cdn-sync[.]net, and the packet contains neither. So at packet time the case escalates on the matrix, P2 within the shift, and the break-glass rule is primed rather than fired: the moment any named trigger returns hostile (the decode is a downloader, the ticket search is empty and the owning team denies the session, intel condemns the domain), confirmation exists and the case pages IR from wherever in the arc that result lands. The rest of the arc then runs under IR’s clock, as scoping support.

Documentation. Summary model, observations first, assessment second: “First interactive (RemoteInteractive) logon on record for service account svc-printmgmt, from workstation wkst-hr-22 to print server prt-01 at 03:24 UTC Sunday, against a 90-day baseline of service logons only. The account created a scheduled task masquerading as an OS component at 03:41 via hidden-window encoded PowerShell; at 03:44, prt-01 sent 2.1 MB to files-cdn-sync[.]net, a destination absent from its 90-day baseline. Assessed as likely hands-on-keyboard use of the account from wkst-hr-22 with the task as persistence; the undocumented-maintenance alternative remains open pending the change-ticket search and account-owner contact. Escalated P2 within shift; the decoded command, the ticket search, and destination intelligence are the recorded break-glass triggers.” Detection feedback: the 4698 rule fired at persistence, late in the chain. The earlier, cheaper signal is the authentication event: interactive or RemoteInteractive logons (types 2 and 10) by any svc-* principal should alert on their own. That rule would have fired at 03:24, seventeen minutes before this one.

Traps planted in this packet. Anchoring: the alert names a Medium-severity task-creation event, and the task’s OS-flavored name invites a “Windows doing Windows things” dismissal. The case pivots on an artifact the alert never mentions. Availability: if your last service-account case was a misconfigured backup job, candidate (b) feels more likely than the evidence supports. The logon type is the discriminator that beats both. The third trap is the invented fact: the artifacts stop exactly where the satisfying conclusions start. Grading rewards the answer that marks the decoded command, the ticket search, and the transfer’s nature as “cannot determine yet,” each with the query that settles it, and penalizes the answer that asserts them. An analyst who manufactures the missing facts has failed the packet even while guessing the author’s intended incident.


Full arc Less guidance 45-60 minutes

Briefing. Tuesday, 10:05 UTC. The queue hands you an identity alert.

IdP alert, 10:05:33 UTC
rule:      OAuth consent granted to unverified publisher (rule-oauth-unv)
severity:  High
account:   adm-jkoh (IT administration)
app:       "SharePoint Migration Manager"   publisher: unverified
scopes:    Sites.FullControl.All, offline_access
consent:   10:02:14 UTC, interactive, MFA satisfied, corporate device
Tenant audit excerpt, 10:00-10:40 UTC
10:12-10:38  bulk file reads by app "SharePoint Migration Manager"
             ~14,000 items across 6 site collections
             source IP range: 198.51.100.32/28
Change-management system, search result
CHG-4182  "SharePoint tenant migration, wave 3 of 5"
          window: Tuesday 09:00-17:00 UTC
          executed by: adm-jkoh
          vendor: CloudShift Migrations Ltd
          vendor doc: migration traffic sources 198.51.100.32/28

Tasks. Same seven phases, fewer hints. This packet’s questions are shorter on purpose; the discipline being trained is verification.

  1. Alert. The rule fired on exactly what its logic describes. What kind of verdict is still open, and what vocabulary from the C.L.E.A.R. glossary names it?
  2. Subject → Uncover. The change ticket looks like it explains everything. List every claim in the ticket you can independently verify against the two log artifacts, and verify each one. Then list the checks the artifacts cannot satisfy, and where you would go for each.
  3. Risk. Write the verdict paragraph, including what stops this from being a close-on-sight.
  4. Escalation → Documentation. There are two more migration waves scheduled. What artifact should this close produce so waves 4 and 5 cost five minutes instead of an hour, and which two fields in it must be re-verified every wave rather than assumed?
Answer key: Exercise 2

Alert. The detection is correct: an unverified-publisher app did receive tenant-level consent. The open question is context, and the verdict this is heading toward is a benign true positive: the logic matched exactly what it describes, and the local context (a sanctioned migration) clears it. That is not a false-positive, and recording the difference matters, because a false-positive verdict would send tuning feedback against a rule that is working.

Subject → Uncover. Verifiable claims, verified: the ticket’s executor matches the consenting account (adm-jkoh on both); the consent timestamp sits inside the ticket’s window (10:02 inside 09:00-17:00); the app’s activity source range matches the vendor’s documented range (198.51.100.32/28 on both); the consent ceremony is consistent with a human administrator (interactive, MFA, corporate device), not a hijacked session. Checks the artifacts cannot satisfy: whether the app’s publisher identity is actually CloudShift’s registered application rather than a lookalike display name, which requires the app ID from the vendor’s onboarding doc or a call to the vendor, because display names are attacker-choosable; whether adm-jkoh actually performed the consent, which one out-of-band message to the ticket owner settles; and whether the read volume matches the wave’s expected site collections, which the migration runbook answers. The name-versus-identity check is the load-bearing one: timing an attack inside someone else’s maintenance window, with a plausibly named app, is an established adversary pattern.

Risk. Model verdict: “Impact if hostile would be high (tenant-wide file read with standing access), but likelihood is low: the consent’s principal, timing, source range, and ceremony all match an approved change record, and the app identity was confirmed against the vendor’s registered application ID rather than its display name. Assessed as benign true positive: sanctioned migration activity correctly flagged by a correctly-broad detection. Residual risk: the standing consent outlives the migration; a decommission check is scheduled with the ticket’s closure.” The close-on-sight stopper: until the app ID and the executor were verified, the ticket was a hypothesis, not an explanation. A change ticket in the search results is a fact about the change-management system, not about the consent event.

Escalation → Documentation. The close should produce a pattern-library entry (“OAuth consent by IT admin during documented migration wave”) so waves 4 and 5 are Level 0 closes against named discriminators. The two fields that must be re-verified every wave: the consenting principal against the wave’s ticket executor, and the application ID against the vendor’s registered app. The fields that may be inherited: the vendor’s source range and the window structure. An entry whose discriminators are “there was a ticket” will eventually close the real thing.

Traps planted in this packet. Deference and premature closure: the change ticket radiates authority, and everything after it reads as confirmation. The packet is passed only by treating the ticket as one more claim to verify. Automation bias variant: the vendor’s own doc supplied the IP range, and the range matching proves the traffic is from the vendor’s infrastructure, not that the app is the vendor’s app.


Exercise 3 · The Level 0 drill

Fast path Timed: 5 minutes

Briefing. Set a five-minute timer. This is a queue-speed drill for the fast path: one recurring alert, one pattern-library entry, one decision.

EDR alert, 02:47:10 UTC
rule:      Possible cryptomining: sustained CPU >90% for 30m
           + persistent outbound TLS to non-allowlisted host
host:      ci-build-14 (group: ci-build-agents)
process:   bazel (build toolchain), CPU 96% sustained
outbound:  cache.buildcache-vendor.io:443, persistent, 41 min
Pattern library entry PTN-017: "Nightly CI compile load on build agents"
owner: detection-engineering    review date: current
eligibility constraint: applies only to hosts inventory-tagged
  "ephemeral-runner / nonprivileged"; never to runners holding deploy,
  signing, secret, or repository-write capability
discriminators:
  1. host is a member of group ci-build-agents
  2. top process is the build toolchain (bazel or gradle)
  3. outbound destination is the vendor build-cache endpoint named in this entry
     (cache.buildcache-vendor.io)
  4. activity falls in the nightly pipeline window, 01:30-04:30 UTC
Asset inventory, ci-build-14
group:        ci-build-agents
criticality:  standard (not crown-jewel)
capability:   ephemeral container runner; scoped read-only repo token;
              no deploy, signing, secret-store, or repository-write scopes
tag:          ephemeral-runner / nonprivileged   (verified: current quarter)
data class:   build artifacts only; no regulated data in reach

Task. Decide whether this alert qualifies for a Level 0 close. If it does, fill the five fields of the pattern-close record, checking the eligibility gate and each discriminator against the artifacts, not from memory. If it does not, say which gate check or discriminator failed and what level the case moves to. Then, timer off: write one sentence for each discriminator describing the alert that would fail it, and one for the eligibility gate.

Answer key: Exercise 3

The gate, before the discriminators. A CI build agent is exactly the kind of subject that fails Level 0 by default: runners commonly hold deploy credentials, signing keys, secret-store access, or repository write scopes, any of which makes the “nonprivileged subject” gate check false however benign the load looks. This packet passes only because the inventory artifact proves otherwise: standard criticality, ephemeral nonprivileged runner with a scoped read-only token, no regulated data, tag verified this quarter — and PTN-017’s own eligibility constraint requires that tag. All three gate checks fill from the inventory artifact, with the source named. Without that artifact, the honest answer is Level 1, not a slower Level 0: an unknown gate check is a failed gate check.

The close. With the gate proven, all four discriminators check against the artifact: ci-build-14 is in ci-build-agents (1 ✓), the top process is bazel (2 ✓), the destination string matches the entry’s named endpoint (3 ✓), and 02:47 falls inside 01:30-04:30 (4 ✓). This is a legitimate Level 0 close: pattern PTN-017, checks recorded as the gate evidence plus the four observations above, verdict “detection correct (sustained load to non-allowlisted host is what the rule hunts); disposition benign-confirmed, expected nightly CI load matching the documented pattern,” disposition closed with analyst and timestamp. Total honest time: under four minutes, and every field filled from an artifact.

The failures that force Level 1. (0) The same alert from release-signer-2, a runner holding signing keys: the gate fails on capability, whatever the discriminators say, and no discriminator can buy the close back. (1) The same alert on wkst-hr-22: a host outside the group means the pattern does not apply at all, whatever else matches. (2) Top process xmrig, or anything that is not the named toolchain: the load is real but the worker is wrong. (3) Destination cache.buildcache-vendor.io.cdn-relay[.]net or any string that merely contains the endpoint: the discriminator is an exact match to the entry’s named host, and lookalike suffixing is exactly how miners hide in CI. (4) The identical alert at 14:00: nightly load at midafternoon is a schedule anomaly the pattern does not cover. Any failure moves the case up the ladder, and per the ladder rules it does not slide back down mid-case.

The trap being drilled. The pattern reflex: by the twentieth night, the reflex is to close on the rule name alone. The five-minute close stays defensible only because the gate and the discriminators were checked against this alert’s artifacts. The discriminator that rusts first is (3), because “the destination looked right” and “the destination string equals the entry’s named endpoint” feel identical at queue speed and are not. The gate check that rusts first is privilege, because “it’s just a build agent” is a sentence that has preceded several real signing-key thefts.

Writing your own packets

These three follow a reusable shape: a briefing an analyst would actually receive, artifacts with the discriminating detail buried in a boring field, tasks phased to the letters, and a key that names the planted traps. Closed cases from your own queue, sanitized per the Documentation example’s sharing discipline, make better packets than anything synthetic; the teaching guide covers turning a real case into an exercise.

Key Takeaway

The methodology is learned in the writing: the close note that has to cite an artifact, the ledger that has to hold an alternative, the discriminator that has to be checked against the field instead of the memory. Three packets is a start; a team that converts one real case a month into a packet builds a training library no course can sell them.