EDR Telemetry Field Reference — Field Guide
1. How to Hunt With This Data
The agent ships two kinds of event, and knowing which one you are looking at is the first skill to build.
| Raw telemetry | Detection Finding | |
|---|---|---|
| What it is | An observation. "This process wrote this file." | A verdict. "This behaviour matched rule X." |
| class_uid | The activity's own class (1007, 1001, 201005, …) | Always 2004 |
| Carries a rule and its ATT&CK mapping? | No | Yes — in finding_info |
| Severity | severity_id = 1 (Informational) | severity_id = 2 (Low) or higher |
| Volume | High | Low |
A Detection Finding is built as a complete copy of the raw event that triggered it, with the finding taxonomy laid on top. The finding therefore already carries the full context — actor, file, reg_key, src_endpoint, process, unmapped.*, metadata — so you rarely need to go back to the origin event to understand what happened. The origin event's own class is preserved in associated_class_uid / associated_class_name.
The seven-step loop
Whether you are investigating an alert, validating a control, or exploring a suspicion, the same loop applies.
┌─ 1. SCOPE ────────────────────────────────────────────────────────┐
│ device.hostname = "WORKSTATION-01" │
│ and time >= <start ms> and time <= <end ms + 60000> │
│ Add a short tail: findings are emitted just after the activity │
│ they describe. │
└───────────────────────────────────────────────────────────────────┘
↓
┌─ 2. LOOK FOR A VERDICT FIRST ─────────────────────────────────────┐
│ class_uid = 2004 (Detection Finding) │
│ → finding_info.title / analytic.name = the rule that fired │
│ → finding_info.analytic.desc = why it fired │
│ → associated_class_uid = what kind of activity │
│ triggered it │
│ Also check: class_uid = 201003 (behaviour detections) │
│ class_uid = 2001 (browser threats) │
│ type_name = "yara_detection_event" │
└───────────────────────────────────────────────────────────────────┘
↓
┌─ 3. TAKE THE dpid AND PULL THE WHOLE CHAIN ───────────────────────┐
│ device.hostname = "WORKSTATION-01" and dpid = 1247 │
│ ← take the dpid from any event in step 2 │
│ This returns EVERY event the agent attributed to the same │
│ logical chain, across all classes AND across processes. │
│ Keep the host filter: the counter is per-endpoint. │
└───────────────────────────────────────────────────────────────────┘
↓
┌─ 4. PROFILE THE ACTING PROCESS ───────────────────────────────────┐
│ actor.process.uid = "<uuid>" ← never reused, unlike pid │
│ Returns files touched, registry written, DNS resolved, sockets │
│ opened, modules loaded, APIs called — by that one process │
│ instance. │
└───────────────────────────────────────────────────────────────────┘
↓
┌─ 5. WALK THE PROCESS TREE ────────────────────────────────────────┐
│ actor.process.lineage_uid contains "<ancestor uuid>" │
│ Everything any descendant did. Use this to catch the stages │
│ that ran in child processes. │
└───────────────────────────────────────────────────────────────────┘
↓
┌─ 6. NO VERDICT? HUNT THE RAW TELEMETRY DIRECTLY ──────────────────┐
│ Use Section 7 (Hunting Index) to go straight to the class and │
│ field that records the activity you care about, and query it in │
│ the scoped window from step 1. │
└───────────────────────────────────────────────────────────────────┘
↓
┌─ 7. NOTHING AT ALL? CHECK THE COLLECTION SCOPE ───────────────────┐
│ Section 3. Three things determine whether a class is on the wire: │
│ the global collection switch, the per-class telemetry flag, and │
│ the fact that classes 201008 / 201009 / 201010 travel only as │
│ Detection Finding context. │
└───────────────────────────────────────────────────────────────────┘Why step 2 comes before step 6
Start narrow and widen. A finding, where one exists, answers two questions in a single row — which rule fired, and what the activity actually was.
Activity you want to explain
│
▼
┌──────────────────────────────┐
│ class_uid = 2004 │
│ Did a rule fire on it? │
└──────────────────────────────┘
│ │
YES│ │NO
▼ ▼
┌────────────────────────┐ ┌──────────────────────────────┐
│ The finding row gives │ │ Section 7 gives you the │
│ you BOTH the rule that │ │ class and field that records │
│ fired AND the full │ │ the activity you are after │
│ evidence, copied from │ └──────────────────────────────┘
│ the origin event │ │
└────────────────────────┘ ▼
│ ┌──────────────────────────────┐
│ │ Nothing at all? That is a │
│ │ collection-scope question - │
│ │ see Section 3 │
│ └──────────────────────────────┘
│ │
└────────────────┬──────────────┘
▼
┌──────────────────────────────────────────────────┐
│ WIDEN │
│ dpid → the whole activity chain │
│ actor.process.uid → everything that process │
│ did │
│ lineage_uid → everything its │
│ descendants did │
└──────────────────────────────────────────────────┘Timing expectations
- Batches are cut at 5,000 events, 30 seconds, or the moment a detection fires — whichever comes first. Expect activity to become searchable within roughly 30 seconds on a quiet endpoint, and sooner where a detection is involved.
- The raw origin event is pushed before the Detection Finding(s) it produced, so ordering by time reads naturally.
- One raw event that trips N behaviour rules produces N separate Detection Findings, all sharing the same dpid and the same origin context.
Two habits that prevent wrong answers
- Always pair activity_id with class_uid. Activity IDs are class-specific, so the same number means different things in different classes. activity_id = 6 on its own is ambiguous — it is File Create in File Activity, Start in Scheduled Job Activity and Continue in Windows Service Activity. Only class_uid = 1001 and activity_id = 6 unambiguously means "a file was created".
- Correlate on UUIDs, never on pids. Windows reuses process IDs. actor.process.uid does not get reused.
2. Anatomy of an Event — The Common Envelope
Every event, in every class, carries the same envelope. Learn it once.
2.1 Classification — "what kind of event is this?"
| Field | Type | Description |
|---|---|---|
| class_uid | integer | The primary filter. Which event class this is. Full list in 6.0. |
| class_name | string | Human-readable class, e.g. "WMI Activity", "Detection Finding". |
| activity_id | integer | What happened within the class. Class-specific. See 9.1. |
| activity_name | string | Human-readable activity, e.g. "Launch", "Binding Activated". |
| type_uid | integer | Composite class + activity identifier. Usually class_uid × 100 + ocsf_activity_id. |
| type_name | string | e.g. "WMI Activity: Binding Activated". For API Telemetry this carries the API name. |
| category_uid | integer | 1 System Activity, 2 Findings, 3 Identity & Access Management, 4 Network Activity. |
| category_name | string | Human-readable category. |
| severity_id | integer | 1 Informational for raw telemetry; 2 Low for findings; WMI and engine-diagnostic events set their own. |
| severity | string | Caption of severity_id. |
2.2 Correlation — "how do I tie this to everything else?"
| Field | Type | Description |
|---|---|---|
| dpid | unsigned integer | Activity-chain token. Same value across every event the agent attributed to one logical chain, including across processes. A per-endpoint counter, so always pair it with a host filter. 0 = unassigned. |
| actor.process.uid | string (UUID) | The acting process instance. Never reused. |
| actor.process.lineage_uid | string[] | Ancestor process UUIDs. |
| associated_class_uid | integer | On a Detection Finding: the origin event's class. 0/absent elsewhere. |
| associated_class_name | string | Caption of the above. |
| session.uid | string | Windows logon session LUID (e.g. "0x3e7"). Joins account, service and task events to the Authentication event for the same session. |
2.3 Time
| Field | Type | Description |
|---|---|---|
| time | integer (epoch ms) | When the event occurred on the endpoint. Always UTC. |
| timezone_offset | integer | Endpoint's UTC offset in minutes (IST = 330, EST = −300). |
| metadata.original_time | integer | Original timestamp as reported by the event source. |
| query_time | integer (epoch ms) | DNS Activity only. |
All timestamps are epoch milliseconds. There is no string date format anywhere in the schema.
2.4 Where — device and tenant
| Field | Type | Description | Example |
|---|---|---|---|
| device.hostname | string | DNS hostname. Your primary scoping filter. | "WORKSTATION-01" |
| device.ip | string | Primary IPv4 address | "192.168.1.100" |
| device.uid | string | Device UUID | |
| device.type_id / device.type | integer / string | Device type identifier and caption | |
| device.os.type_id / device.os.type | integer / string | 100 / "Windows" | |
| device.os.version | string | Full OS caption | "Microsoft Windows 11 Pro" |
| componentid | integer | Endpoint agent installation ID | |
| component_id | integer | Same value as componentid; filter on either | |
| customerid | integer | Customer / organisation ID | |
| resourceid | integer | Resource ID in the management platform | |
| zoid | integer | Zone / office ID — filter by site | |
| zaaid | integer | Account-area (tenant) ID | |
| batch_name | string | Delivery batch identifier, injected into every event. Format <component_id>_<timestamp_ms>_<batch_number> | "1001000000012345_1772685020358_297" |
2.5 Product metadata
| Field | Type | Value |
|---|---|---|
| metadata.product.name | string | "ManageEngine EDR" |
| metadata.product.vendor_name | string | "ManageEngine" |
| metadata.product.version | string | Installed agent version, e.g. "1.0.63.7" |
| metadata.product.uid | string | "ManageEngine_EDR" |
| metadata.log_name | string | "ME_EDR_EVENTS" |
| metadata.log_provider | string | "ManageEngine EDR" |
| metadata.version | string | "1.3.0" (OCSF schema version reported) |
| metadata.tenant_uid | string | Same value as zaaid |
| metadata.sequence | integer | Source sequence number |
Browser-sourced events (classes 4002 / 6001 / 6002 / 2001) receive their metadata from the browser extension, so metadata.product may describe the browser or extension rather than the agent.
2.6 Outcome
| Field | Type | Description |
|---|---|---|
| status_id | integer | 0 Unknown, 1 Success, 2 Failure, 99 Other |
| status | string | Caption of status_id |
| status_code | string | Source-reported code. Hex NTSTATUS for SMB ("0xC0000016"), Kerberos result code for ticket events ("0x18"), WMI HRESULT ("0x80041032") |
| status_detail | string | Human-readable outcome, decoded where possible (e.g. "Unknown username or bad password", "Pre-authentication failed (bad password)") |
| message | string | One-line human summary. On three classes it carries a JSON payload instead — noted in those class sections. |
| exit_code | integer | Process exit-code field; carries 0. |
2.7 Observables
observables is a short array summarising the event's key artefact. It is a convenience filter, not a complete index.
| Field | Type | Description |
|---|---|---|
| observables[].type_id | integer | 0 Unknown, 1 Hostname, 2 IP Address, 10 Endpoint, 24 File, 25 Process, 99 Other |
| observables[].type | string | e.g. "Registry", "Service", "Job", "WMI", "Volume", "Module", "ComputerAccount", "RemoteProcess", "Command", "User", "Group" |
| observables[].name | string | Usually a descriptive label ("File Write Event"); for some classes an attribute pointer ("job.name") |
| observables[].value | string | The value, when name is an attribute pointer |
Observable presence by class:
| Class | Observable name | type |
|---|---|---|
| 1007 Process | "Process Launch Event" / "Process Terminate Event" | — |
| 1001 File | "File Create/Write/Delete/Read/Rename/Set Attributes Event" | — |
| 201001 / 201002 Registry | "Registry Key Create Event", "Registry Value Modify Event", … | "Registry" |
| 4001 Network | "Inbound/Outbound Network Connection" | "IP Address" |
| 4003 DNS | the queried hostname | "Hostname" |
| 3002 Authentication | target username | "User" |
| 1005 Module | full module path | "Module" |
| 1006 Scheduled Job | "job.name" (with value = task name) | "Job" |
| 201004 Windows Service | service short name | "Service" |
| 201005 WMI | consumer name, else namespace | "WMI" |
| 201009 Volume | volume device path | "Volume" |
| 1011 Device Power State | initiator image path, or username on an abort | "Process" / "User" |
| 3001 Account Change | target username / computer account | "User" / "ComputerAccount" |
| 3006 Group Management | target group name | "Group" |
| 3005 User Access Mgmt | target username | "User" |
| 4006 SMB | remote IP (in value) plus username | "IP Address", "User" |
| 201007 Command | the input command | "Command" |
| 1007 (remote creation) | remote process name | "RemoteProcess" |
| 201004 (remote creation) | remote service name | "RemoteService" |
Classes 201003, 201008, 1009, 4002 / 6001 / 6002 / 2001 and YARA detections carry no observables array.
3. Telemetry Delivery and Collection Scope
If an activity produced no telemetry, work through this section before concluding it was not captured.
3.1 Collection and delivery
The agent transforms each captured event into an OCSF JSON object, groups them into batches and uploads over HTTPS.
A batch closes on whichever of these comes first:
- 5,000 events accumulate.
- 30 seconds elapse.
- A detection fires. An alert triggers an immediate flush, so telemetry from around a detection reaches the server without waiting for either threshold above.
Each batch is gzip-compressed and uploaded as one file, and every event in it carries the batch identifier in batch_name. Under normal load there is a short pause (~2 s) between successive uploads.
Retry behaviour on upload failure:
| Failure | Action |
|---|---|
| Network, authentication or resource failure | Exponential backoff and retry; the batch is retained on disk rather than discarded |
| Rate limited (HTTP 429) | Exponential backoff, capped at 30 minutes between retries |
| Authentication error | Auth token refreshed, then the upload is retried |
| Payload too large (HTTP 413) | Batch dropped |
| Batch above the 4 MB file cap | Batch dropped |
| Telemetry folder above the 500 MB cap | Oldest pending batches dropped until the folder is back under the cap |
Each dropped batch is reported to the server in its own batch-summary record, so the delivery record stays complete.
Disk safeguards: the telemetry folder is capped at 500 MB and a single compressed batch at 4 MB, which bounds the agent's disk footprint on the endpoint.
3.2 Scope control 1 — the global collection switch
All OCSF telemetry generation sits behind one master switch, delivered as server-side policy. When it is off, nothing is emitted — not even Detection Findings.
3.3 Scope control 2 — per-class telemetry flags
Each class is individually enabled by a bit in a telemetry flag mask. If the bit is clear, that class's raw events are not emitted.
| Flag | Bit | Gates class(es) |
|---|---|---|
| TELEMETRY_PROCESS | 1 | 1007 Process Activity |
| TELEMETRY_LOGON | 2 | 3002 Authentication |
| TELEMETRY_REGISTRY | 3 | 201001, 201002 Registry |
| TELEMETRY_FILE | 4 | 1001 File Activity |
| TELEMETRY_NETWORK | 5 | 4001 Network Activity |
| TELEMETRY_DNS | 6 | 4003 DNS Activity |
| TELEMETRY_IMAGE_LOAD | 7 | 1005 Module Activity |
| TELEMETRY_BEHAVIOUR | 8 | behaviour persistence |
| TELEMETRY_BROWSER | 9 | 4002 / 6001 / 6002 / 2001 |
| TELEMETRY_ACCOUNT_AND_OBJECT | 10 | 3001 Account Change, 3006 Group Management, 3005 User Access Management, computer-account changes |
| TELEMETRY_SERVICE_LIFECYCLE | 11 | 201004 Windows Service Activity |
| TELEMETRY_SCHEDULED_JOB | 12 | 1006 Scheduled Job Activity |
| TELEMETRY_WMI_ACTIVITY | 13 | 201005 WMI Activity |
| TELEMETRY_REMOTE | 14 | remote process creation (1007), remote service creation (201004), 201007 Command Activity |
| TELEMETRY_SMB | 15 | 4006 SMB Activity |
| TELEMETRY_AMSI | 16 | 1009 Script Activity |
| TELEMETRY_SHUTDOWN | 17 | 1011 Device Power State Activity |
Classes that flow whenever global collection is on, without a per-class flag: YARA detections, Suspicious Behaviour Activity, and all Detection Findings. Browser-sourced classes are also delivered whenever collection is enabled.
The most useful fact in this section: Detection Findings are emitted whenever collection is on and a behaviour fires — independent of the origin class's telemetry flag. So with, say, Module Activity disabled, a module-based behaviour still produces a finding carrying the full module context. Findings present but raw events absent is normally a flag question, not a capture question.
3.4 Scope control 3 — classes that travel as finding context
Three classes fire on essentially every relevant operation, so they are delivered as the context of a Detection Finding rather than as standalone events:
| Class | Why | How to query it |
|---|---|---|
| 201008 API Telemetry Activity | One event per hooked API call | class_uid = 2004 and associated_class_uid = 201008 |
| 201009 Volume Activity | Every raw volume read/write | class_uid = 2004 and associated_class_uid = 201009 |
| 201010 On-Write Scan Result | Every executable write on the endpoint | class_uid = 2004 and associated_class_uid = 201010 |
# Correct way to hunt API-call evidence:
class_uid = 2004
and associated_class_uid = 201008
and unmapped.api_telemetry.api_name = "ApiTelemetry_NtCreateRemoteThread"3.5 Scope control 4 — per-process daily event limits
Each process has a daily allowance per activity type, which keeps any single high-volume process from crowding out telemetry from the rest of the endpoint. Once a process reaches its allowance for a given activity, further events of that type from that process are collected again the next day; every other process is unaffected.
| Class | Activity | Daily limit per process |
|---|---|---|
| 1001 File Activity | Create / Read / Write / Delete / Rename | 40,000 each |
| 1001 File Activity | Directory Create | 10,000 |
| 201001 Registry Key | Create / Delete | 50,000 each |
| 201001 Registry Key | Rename | 30,000 |
| 201001 Registry Key | Set Security | 20,000 |
| 201002 Registry Value | Modify / Delete | 50,000 each |
| 4001 Network Activity | Traffic | 100,000 |
| 4003 DNS Activity | Query | 100,000 |
Process Activity and Authentication carry no per-process limit. The remaining classes (1005, 1006, 1009, 1011, 201003—201010, 4006, 3001, 3005, 3006) are bounded by their telemetry flag and by the narrowness of their source rather than by a count.
Reading high-volume activity: where a single process generates activity at this scale, the Detection Finding is the reliable summary of what happened — it is emitted per rule fire and is not subject to these allowances. Use the raw events for the detail and the finding for the verdict.
3.6 Scope control 5 — content filters
| Rule | Effect |
|---|---|
| File operations | Create, Write, Rename, Delete and Directory Create are collected. |
| Loopback / same-host SMB | Not collected — same-host SMB carries no cross-host security value. |
| Global registry and path filters | A sizeable allowlist suppresses high-noise registry keys, queries and paths before events are generated. |
| Browser events | Dropped when the browser payload cannot be parsed. |
4. The Three Correlation Pivots
4.1 dpid — the activity-chain token
dpid (Data Provenance ID) is a correlation token the agent assigns before an event is queued. Every event the agent attributes to the same logical chain of activity carries the same value — including events from different processes.
| Type | Unsigned 64-bit integer |
| Form | A plain counter value. It has no internal structure — it is not a hash, a timestamp, a process ID or a UUID, and no part of it can be decoded. Its only meaning is identity: same number, same chain. |
| Typical values | The counter starts at 1000 on a newly initialised agent and increments by one per chain, so real values are usually four or five digits — 1000, 1247, 3812. It persists across agent restarts and continues from where it stopped. |
| 0 | Unassigned — the event was not attributed to a chain |
| Scope | Cross-process and cross-class, but per-endpoint — see below |
| On findings | A Detection Finding inherits the same dpid as its origin raw event |
Always scope a dpid query to one host
Each endpoint runs its own independent counter, seeded at 1000. dpid = 1247 on one machine has no relationship to dpid = 1247 on another. A dpid query without a host filter will pull together unrelated activity from every endpoint that happens to have reached that number.
`
Correct
device.hostname = "WORKSTATION-01" and dpid = 1247
Also correct — componentid identifies one agent installation
componentid = 1001000000012345 and dpid = 1247
`
On agent startup the engine also mints one DPID for each process already running, so a fresh agent on a busy machine will have advanced its counter by a few hundred before it observes anything new. A low value therefore does not mean "early in the incident" — it means "early in this agent's lifetime". Order chains by time, never by dpid.
# The single most valuable investigative query.
# Take the dpid from any event of interest, then:
device.hostname = "WORKSTATION-01" and dpid = 1247This returns the process launches, file writes, registry keys, DNS lookups, network connections, module loads, service installs and findings the agent grouped into one chain — even where the activity moved between processes and actor.process.uid therefore changes.
Why it beats actor.process.uid: real activity crosses process boundaries (winword.exe → cmd.exe → powershell.exe → an injected explorer.exe). actor.process.uid gives you one hop; dpid gives you the chain.
# Recommended triage pattern:
# 1. Find the findings in your window
class_uid = 2004 and device.hostname = "WORKSTATION-01"
and time >= 1704067200000 and time < 1704070800000
# 2. Collect the distinct dpid values, then for each:
device.hostname = "WORKSTATION-01" and dpid = <value>
# 3. Sort by time — you now have the reconstructed chain.4.2 actor.process.uid — the process-instance key
A UUID identifying one process instance. It is not reused, so it is safe to pivot on across long windows.
# Everything one process instance did, across every class:
actor.process.uid = "a7f3c9e1-4b2d-4e8a-9c1f-2d3e4f5a6b7c"Present as actor.process.uid on every class that has an acting process. On Process Activity events the subject process also has its own process.uid.
# Step 1 — find the process instance
class_uid = 1007 and activity_id = 1
and process.name = "powershell.exe"
and process.cmd_line contains "-enc"
# Step 2 — take process.uid from the result, then profile it
actor.process.uid = "<the uid>"4.3 lineage_uid — the ancestry array
process.lineage_uid and actor.process.lineage_uid are arrays of ancestor process UUIDs, ordered nearest-first (index 0 = parent). Up to 5 ancestors are recorded.
explorer.exe (AAA) → cmd.exe (BBB) → powershell.exe (CCC) → updater.exe (DDD)
For the updater.exe launch event:
process.uid = "DDD"
process.lineage_uid = ["CCC", "BBB", "AAA"]Because it is a string array, contains matches any element — which makes it a subtree query:
# Every event produced by any descendant of cmd.exe (BBB):
actor.process.lineage_uid contains "BBB"4.4 Secondary join keys
| Key | Joins | Notes |
|---|---|---|
| session.uid | Authentication ↔ Account Change / Group Management / User Access Management / Scheduled Job / Windows Service | Windows logon LUID as hex ("0x3e7" SYSTEM, "0x3e4" NETWORK SERVICE, "0x3e5" LOCAL SERVICE). Ties an action back to the logon that performed it. |
| unmapped.smb.session_uuid | SMB events belonging to one remote session | Server-minted correlation UUID |
| unmapped.wmi_activity.operation_id | A WMI write-confirm event ↔ its initiating operation-start | Correlates the parts of one WMI subscription install |
| job.uid | Scheduled-task events for one task instance | Windows TaskInstanceId GUID |
| file.sha256 / hashes[].value | The same binary across endpoints | |
| unmapped.on_write_scan_result.process_uuid | A drop verdict ↔ the dropping process | |
| unmapped.command_activity.process_uuid | Shell I/O ↔ the shell host process | |
| unmapped.api_telemetry.process_uuid | An API call ↔ the calling process | Consistent with actor.process.uid |
5. Understanding "Actor" Across All Classes
actor answers "who did this?". Its meaning shifts by class, and getting it wrong is the most common hunting mistake.
5.1 Process Activity — three process objects
| Field | Role |
|---|---|
| process | The subject — the process that was launched or terminated. |
| process.parent_process | The claimed parent — what Windows reports via PPID. Can be falsified by the parent. |
| actor.process | The real initiator — where a falsified PPID is detected, this is set to the real creator. |
Normal:
cmd.exe (1234) launches powershell.exe (5678)
process = powershell.exe (5678)
process.parent_process = cmd.exe (1234)
actor.process = cmd.exe (1234) ← same
Falsified parent:
process (9999) launches powershell.exe (5678) claiming explorer.exe (1000)
process = powershell.exe (5678)
process.parent_process = explorer.exe (1000) ← claimed
actor.process = the real creator (9999) ← actual
# Detect a falsified parent process:
class_uid = 1007 and activity_id = 1
and actor.process.pid != process.parent_process.pid5.2 File, Registry, Network, DNS, Module, Volume, Script, API Telemetry
actor.process is simply the process that performed the action.
| Class | actor.process is… |
|---|---|
| 1001 File | The process that created / wrote / deleted / renamed the file |
| 201001 / 201002 Registry | The process that touched the key or value |
| 4001 Network | The process that owned the socket |
| 4003 DNS | The process that issued the query |
| 1005 Module | The process the module was loaded into |
| 201009 Volume | The process holding the raw volume handle |
| 1009 Script | The process that submitted content to AMSI (powershell.exe, wscript.exe, winword.exe…) |
| 201008 API Telemetry | The process that called the API — monitoring is in-process, so this is always the caller |
| 201010 On-Write Scan Result | The process that wrote the file, not the file's own process |
5.3 Identity classes (3001, 3005, 3006) — subject vs target
| Field | Role |
|---|---|
| actor.user | The subject — who performed the change |
| user (top level) | The target — the account that was changed |
| group | The group that was modified (3006 only) |
| session.uid | The subject's logon session |
| actor.process | The generating process (typically lsass.exe) |
# Who created accounts, and which accounts were created?
class_uid = 3001 and activity_id = 1001
# → actor.user.name = the creator, user.name = the new account5.4 Authentication (3002)
| Field | Role |
|---|---|
| user | The target — the account being authenticated |
| actor.user | The subject — the account that initiated the logon |
| actor.process | The logon handler (lsass.exe, winlogon.exe), when a pid is available |
| src_endpoint.ip / src_endpoint.name | Source of a remote logon |
When one account authenticates as another, actor.user and user differ. That difference is often the whole signal.
5.5 Lifecycle classes (1006, 201004, 1011)
These distinguish who asked from what ran:
| Class | actor.process | The thing acted on |
|---|---|---|
| 1006 Scheduled Job | The task-registration caller (schtasks.exe, powershell.exe) | job.* — and job.run_as is who the task runs as |
| 201004 Windows Service | The Service Control Manager caller (sc.exe, net1.exe, powershell.exe) | win_service.*; win_service.hosting_process.pid is the process actually running the service |
| 1011 Device Power State | The shutdown initiator | unmapped.device_power_state.* |
For Windows Service Activity: actor.process is populated from the Service Control Manager caller, so it names the process that requested the operation. Service-led events — state changes and stop notifications — are reported by the service itself and carry no caller, so actor.process is not populated on those.
5.6 Detection Finding (2004)
actor is copied wholesale from the origin event, so it means whatever it meant there. If the origin carried no actor, the engine-reported acting pid is used, giving actor.process.pid without the enriched name, command line, hash and user.
5.7 Classes with no meaningful actor
| Class | Note |
|---|---|
| 4002 / 6001 / 6002 / 2001 Browser | actor.process is the browser process, enriched from the browser-reported pid |
| 4006 SMB | actor.process is the local process on the network path; the remote identity lives in src_endpoint, dst_endpoint.owner and unmapped.smb |
6. Event Class Catalogue
6.0 Class index
| class_uid | Class name | Category | Source | Telemetry flag | Delivery |
|---|---|---|---|---|---|
| 1001 | File Activity | 1 System | Kernel-mode file system monitoring | TELEMETRY_FILE | Standalone |
| 1005 | Module Activity | 1 System | Kernel-mode module load monitoring | TELEMETRY_IMAGE_LOAD | Standalone |
| 1006 | Scheduled Job Activity | 1 System | Security 4698—4702; TaskScheduler/Operational 102/129/201 | TELEMETRY_SCHEDULED_JOB | Standalone |
| 1007 | Process Activity | 1 System | Kernel-mode process monitoring; Security 4688 correlated with a network logon for remote creation | TELEMETRY_PROCESS / TELEMETRY_REMOTE | Standalone |
| 1009 | Script Activity | 1 System | AMSI provider | TELEMETRY_AMSI | Standalone |
| 1011 | Device Power State Activity | 1 System | Microsoft-Windows-User32 1074/1075 | TELEMETRY_SHUTDOWN | Standalone |
| 2001 | Security Finding | 2 Findings | Browser-threat detectors | TELEMETRY_BROWSER | Standalone |
| 2004 | Detection Finding | 2 Findings | Behaviour rule engine | none | Standalone |
| 3001 | Account Change | 3 IAM | Security 4720/4722—4726/4740/4767; 4741/4743 | TELEMETRY_ACCOUNT_AND_OBJECT | Standalone |
| 3002 | Authentication | 3 IAM | Security 4624/4625; Kerberos 4768—4771 | TELEMETRY_LOGON | Standalone |
| 3005 | User Access Management | 3 IAM | Security 4704, 4717 | TELEMETRY_ACCOUNT_AND_OBJECT | Standalone |
| 3006 | Group Management | 3 IAM | Security 4728/4732/4756 | TELEMETRY_ACCOUNT_AND_OBJECT | Standalone |
| 4001 | Network Activity | 1 System | Network filtering layer | TELEMETRY_NETWORK | Standalone |
| 4002 | HTTP Activity | from browser | Browser extension | TELEMETRY_BROWSER | Standalone |
| 4003 | DNS Activity | 1 System | Network traffic inspection | TELEMETRY_DNS | Standalone |
| 4006 | SMB Activity | 4 Network | SMB protocol inspection | TELEMETRY_SMB | Standalone |
| 6001 | Web Resources Activity | from browser | Browser extension | TELEMETRY_BROWSER | Standalone |
| 6002 | Application Lifecycle | from browser | Browser extension | TELEMETRY_BROWSER | Standalone |
| 201001 | Registry Key Activity | 1 System | Kernel-mode registry monitoring | TELEMETRY_REGISTRY | Standalone |
| 201002 | Registry Value Activity | 1 System | Kernel-mode registry monitoring | TELEMETRY_REGISTRY | Standalone |
| 201003 | Suspicious Behaviour Activity | 1 System | Kernel-mode behaviour detection | none | Standalone |
| 201004 | Windows Service Activity | 1 System | Security 4697; SCM 7000—7045; MS-Services 105/200—205 | TELEMETRY_SERVICE_LIFECYCLE / TELEMETRY_REMOTE | Standalone |
| 201005 | WMI Activity | 1 System | WMI-Activity/Operational 11, 20, 21, 5858, 5860, 5861 | TELEMETRY_WMI_ACTIVITY | Standalone |
| 201007 | Command Activity | 1 System | Shell session monitoring | TELEMETRY_REMOTE | Standalone |
| 201008 | API Telemetry Activity | 1 System | In-process API monitoring | — | Finding context |
| 201009 | Volume Activity | 1 System | Kernel-mode raw volume monitoring | — | Finding context |
| 201010 | On-Write Scan Result Activity | 1 System | On-write scan engine | — | Finding context |
| (see 6.24) | YARA Detection | 1 System | YARA scan engine | none | Standalone |
6.1 Process Activity (1007)
| class_uid / class_name | 1007 / "Process Activity" |
| category | 1 / "System Activity" |
| Source | Kernel-mode process monitoring. Remote creations additionally correlate Security 4688 with a preceding network (type-3) logon. |
| Telemetry flag | TELEMETRY_PROCESS (local), TELEMETRY_REMOTE (remote creation) |
| What it reveals | What ran on the endpoint, with the full command line, the executing user, the real parent, and the ancestry chain. The most fundamental class in the schema. |
Activities
| activity_id | activity_name | type_uid | type_name |
|---|---|---|---|
| 1 | Launch | 100701 | Process Activity: Launch |
| 2 | Terminate | 100702 | Process Activity: Terminate |
Remote process creation is also reported as activity_id = 1 / type_uid = 100701, distinguished by is_remote = true and a populated src_endpoint.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| process.pid | integer | OS process ID. Reused by Windows — use process.uid for correlation. |
| process.uid | string (UUID) | Process-instance key, stamped on both launch and terminate. |
| process.name | string | Executable base name |
| process.cmd_line | string | Highest-value field in the schema. Full command line with arguments. |
| process.created_time | epoch ms | Present on Launch |
| process.terminated_time | epoch ms | Present on Terminate |
| process.lineage_uid | string[] | Up to 5 ancestor UUIDs, nearest first |
| process.file.path | string | Full image path |
| process.file.name | string | Image base name |
| process.file.ext | string | Extension without the dot |
| process.file.sha256 | string | Convenience copy of the SHA-256 digest |
| process.file.hashes[].algorithm_id / .algorithm / .value | int / string / string | 3 / "SHA256" / hex digest |
| process.file.size | integer | Bytes |
| process.file.version | string | Product version from the PE header |
| process.file.company_name | string | Company name from the PE header. A system binary whose company is not Microsoft is worth reviewing. |
| process.file.accessed_time / modified_time / created_time | epoch ms | File timestamps |
| process.file.type_id | integer | 1 Regular File |
| process.user.uid | string | SID |
| process.user.name | string | Username |
| process.user.domain | string | Domain |
| process.user.type_id / .type | int / string | 1 User, 2 Admin (elevated token), 3 System |
| process.parent_process.* | object | pid, uid, name, cmd_line, created_time, file (full), user (full). The claimed parent. |
| actor.process.* | object | pid, uid, name, cmd_line, created_time, file, user. The real initiator. |
| actor.user.* | object | Logged-on user context |
| is_remote | boolean | true on remote process creation |
| src_endpoint.hostname / .ip / .port | string / string / int | Remote origin, on remote creation |
| status_id / status_detail | int / string | 1; "Launch Success" or "Terminate Success" |
| message | string | "Process was launched" / "Process was Terminated" |
On a Terminate event for a process the agent never saw launch (for instance when the agent started mid-life), pid, uid and terminated_time are populated and the cached image, hash, user and hierarchy details are not available.
Hunting
# Office applications spawning a shell or script host
class_uid = 1007 and activity_id = 1
and process.name in "cmd.exe","powershell.exe","wscript.exe","cscript.exe","mshta.exe"
and actor.process.name in "winword.exe","excel.exe","powerpnt.exe","outlook.exe"
# Encoded or obfuscated PowerShell invocations
class_uid = 1007 and activity_id = 1
and process.name = "powershell.exe"
and (process.cmd_line contains "-enc" or process.cmd_line contains "-e "
or process.cmd_line contains "FromBase64String")
# Built-in Windows binaries commonly used to proxy execution
class_uid = 1007 and activity_id = 1
and process.name in "certutil.exe","regsvr32.exe","mshta.exe","wmic.exe",
"rundll32.exe","bitsadmin.exe","msiexec.exe","installutil.exe","regasm.exe"
# Execution from a user-writable directory
class_uid = 1007 and activity_id = 1
and (process.file.path contains "\AppData\" or process.file.path contains "\Temp\"
or process.file.path contains "\Public\" or process.file.path contains "\ProgramData\")
# Remotely initiated process creation
class_uid = 1007 and activity_id = 1 and is_remote = true
# Falsified parent process
class_uid = 1007 and activity_id = 1
and actor.process.pid != process.parent_process.pid
# A system binary name running from the wrong directory
class_uid = 1007 and activity_id = 1
and process.name = "svchost.exe"
and process.file.path notcontains "\System32\"
# Proximity search across command lines
actor.process.cmd_line spanNear ("powershell","hidden",10,false)
actor.process.cmd_line spanNear ("certutil","decode",5,true)6.2 File Activity (1001)
| class_uid / class_name | 1001 / "File Activity" |
| category | 1 / "System Activity" |
| Source | Kernel-mode file system monitoring |
| Telemetry flag | TELEMETRY_FILE, plus the per-process daily limits in 3.5 |
| What it reveals | Files created, written, renamed, deleted; the process responsible; whether the operation arrived over the network; and the file's Windows attributes. |
Activities collected
| activity_id | activity_name | type_uid |
|---|---|---|
| 0 | Unknown | 100100 |
| 6 | Create | 100101 |
| 8 | Update (Write) | 100103 |
| 9 | Delete | 100104 |
| 10 | Rename | 100105 |
| 20 | Directory Create | 100115 |
Mutating operations are collected. The class also defines Read (7 / 100102) and Set Attributes (11 / 100106) for completeness of the schema.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| file.path | string | Full path before the operation |
| file.name | string | Base name |
| file.ext | string | Extension without the dot |
| file.type_id | integer | 1 Regular File |
| file.attributes | integer | Windows attribute bitmask, present when non-zero. 0x1 ReadOnly, 0x2 Hidden, 0x4 System, 0x80 Normal, 0x100 Temporary. Hidden combined with System on a user document is unusual. |
| file_result.path | string | Full path after the operation. Differs from file.path only on Rename; mirrors it otherwise. |
| file_result.name / .ext / .type_id | string / string / int | Post-operation name, extension, type |
| actor.process.* | object | The process performing the operation — pid, uid, name, cmd_line, file, user |
| actor.user.* | object | Logged-on user context |
| is_remote | boolean | true = the operation arrived over the network (SMB). |
| src_endpoint.ip | string | Source IP of a remote file operation |
| status_id / status_detail | int / string | 1; "Create Success", "Write Success", "Delete Success", "Rename Success", "Directory Create Success" |
| message | string | "File was successfully created", and equivalents |
file vs file_result on rename
file.path = "C:\Users\Admin\Documents\report.docx" ← BEFORE
file.ext = "docx"
file_result.path = "C:\Users\Admin\Documents\report.locked" ← AFTER
file_result.ext = "locked"On Create, Write and Delete the two objects hold the same path.
Hunting
# Bulk renames that change the extension
class_uid = 1001 and activity_id = 10
and file.ext in "docx","xlsx","pdf","jpg","png","pptx","txt","csv"
and file_result.ext notin "docx","xlsx","pdf","jpg","png","pptx","txt","csv","tmp"
# group by actor.process.uid and look for high counts in a short window
# Executables written by a script engine
class_uid = 1001 and activity_id in 6,8
and file.ext in "exe","dll","ps1","bat","vbs","js","hta","scr"
and actor.process.name in "powershell.exe","wscript.exe","cscript.exe","cmd.exe","mshta.exe"
# Files placed in a startup folder
class_uid = 1001 and activity_id in 6,8
and file.path contains "\Microsoft\Windows\Start Menu\Programs\Startup"
# Executables written over the network
class_uid = 1001 and activity_id in 6,8 and is_remote = true
and file.ext in "exe","dll","bat","ps1"
# → src_endpoint.ip identifies the source host
# Hidden files created
class_uid = 1001 and activity_id in 6,8 and file.attributes >= 2
# test bit 0x2 in your platform, then confirm by inspecting the value
# Double extensions
class_uid = 1001
and (file.name contains ".pdf.exe" or file.name contains ".doc.exe"
or file.name contains ".jpg.exe")
# Backup and shadow-copy artefacts deleted
class_uid = 1001 and activity_id = 9
and (file.path contains "\System Volume Information" or file.ext in "bak","vhd","vbk")
# Everything one process touched
class_uid = 1001 and actor.process.uid = "<uid>"
# Track a file by hash across the estate
class_uid = 1001 and file.sha256 = "<sha256>"6.3 Module Activity (1005)
| class_uid / class_name | 1005 / "Module Activity" |
| category | 1 / "System Activity" |
| Source | Kernel-mode module load monitoring |
| Telemetry flag | TELEMETRY_IMAGE_LOAD |
| What it reveals | Which DLLs and modules loaded into which processes, with the module's path and hash — the basis for side-loading and unexpected-dependency hunting. |
Activities
| activity_id | activity_name | type_uid | type_name |
|---|---|---|---|
| 601 | Load | 100501 | Module Activity: Load |
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| module.file.path | string | Full module path |
| module.file.name | string | Module base name |
| module.file.ext | string | Extension |
| module.file.sha1 | string | SHA-1 — this class uses SHA-1 rather than SHA-256 |
| module.file.hashes[].algorithm_id / .algorithm / .value | int / string / string | 2 / "SHA-1" / hex digest |
| module.file.type_id | integer | 1 Regular File |
| module.load_type_id | integer | 1 (Standard) |
| module.load_type | string | "Standard" |
| actor.process.* | object | The process the module was loaded into |
| actor.user.* | object | User context |
| observables[0].type | string | "Module"; name = full module path |
| status_id / status_detail | int / string | 1; "Module Load Success" |
| message | string | "A module was loaded into a process" |
For the technique by which a module was loaded — manual mapping, reflective loading, module stomping — see Suspicious Behaviour Activity (6.9) and API Telemetry Activity (6.13).
Hunting
# Modules loaded from a writable directory rather than a system path
class_uid = 1005
and module.file.path notcontains "\System32\"
and module.file.path notcontains "\WinSxS\"
and module.file.path notcontains "\Program Files"
and (module.file.path contains "\AppData\" or module.file.path contains "\Temp\"
or module.file.path contains "\ProgramData\")
# Every module loaded into a process instance of interest
class_uid = 1005 and actor.process.uid = "<uid>"
# A specific module by hash, anywhere in the estate
class_uid = 1005 and module.file.sha1 = "<sha1>"
# Modules loaded by binaries that exist to load them
class_uid = 1005
and actor.process.name in "rundll32.exe","regsvr32.exe","mshta.exe"
# Which processes loaded a given DLL name
class_uid = 1005 and module.file.name = "amsi.dll"6.4 Scheduled Job Activity (1006)
| class_uid / class_name | 1006 / "Scheduled Job Activity" |
| category | 1 / "System Activity" |
| Source | Security 4698 (created), 4699 (deleted), 4700 (enabled), 4701 (disabled), 4702 (updated); TaskScheduler/Operational 102, 129, 201 |
| Telemetry flag | TELEMETRY_SCHEDULED_JOB |
| What it reveals | The full scheduled-task definition — the command it runs, the account it runs as, its triggers, its folder, and whether it is hidden from the Task Scheduler UI. |
Activities (normalised to the OCSF 0—99 range)
| activity_id | activity_name | type_uid | Source EID |
|---|---|---|---|
| 0 | Unknown | 100600 | — |
| 1 | Create | 100601 | Security 4698 |
| 2 | Update | 100602 | Security 4702 |
| 3 | Delete | 100603 | Security 4699 |
| 4 | Enable | 100604 | Security 4700 |
| 5 | Disable | 100605 | Security 4701 |
| 6 | Start | 100606 | TaskScheduler/Operational 102, 129, 201 |
| 99 | Other | 100699 | — |
TaskScheduler/Operational EIDs 100, 110, 200 and 325 are pre-spawn bookkeeping and are not collected. EIDs 106, 140, 141 and 142 duplicate the Security audit events and are not collected.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| job.name | string | Task base name only — the folder path is separated out |
| job.uid | string | Windows TaskInstanceId GUID — joins events for one task instance |
| job.desc | string | Task description as registered |
| job.schedule | string | Trigger start boundary / calendar expression |
| job.cmd_line | string | The command the task runs |
| job.file.path | string | The executable the task launches |
| job.file.name | string | Base name of that executable |
| job.run_as.name | string | Run-as account (4698 supplies DOMAIN\name) |
| job.run_as.uid | string | Run-as SID (4700/4701 supply a raw SID) |
| job.run_as.type_id / .type | int / string | 3/"System" for the well-known service SIDs, otherwise 1/"User" |
| unmapped.scheduled_job.scheduled_job_location | string | Task folder — the "Location" column in taskschd.msc. "\" is the library root. |
| unmapped.scheduled_job.scheduled_job_visibility | string | "Hidden from Task Scheduler UI (stealth indicator)" or "Visible in Task Scheduler". Asserted on 4698/4702, the events that carry the task XML. |
| unmapped.scheduled_job.scheduled_job_privilege | string | "Highest available privileges (will elevate via UAC)", "Least privilege (limited rights)", or the raw RunLevel value |
| unmapped.scheduled_job.scheduled_job_triggers | string[] | One readable sentence per trigger — time, logon, event, boot, and so on |
| actor.process.* | object | The registering caller (schtasks.exe, powershell.exe, a COM client) |
| actor.user.* | object | Subject who registered or changed the task |
| session.uid | string | Subject logon LUID — joins to the Authentication event |
| observables[0] | object | type = "Job", name = "job.name", value = task name |
| status_id / status_code / status_detail | int / string / string | Passed through from the source; left unset when the source reports no outcome |
| message | string | Readable one-liner, e.g. "schtasks.exe (PUUID …) created scheduled task 'Updater' in \" |
Hunting
# All task creation and modification
class_uid = 1006 and activity_id in 1,2
# Tasks hidden from the Task Scheduler UI
class_uid = 1006
and unmapped.scheduled_job.scheduled_job_visibility contains "Hidden"
# Tasks that run as SYSTEM with highest privileges
class_uid = 1006 and activity_id in 1,2
and job.run_as.type_id = 3
and unmapped.scheduled_job.scheduled_job_privilege contains "Highest"
# Tasks launching a script engine, or a binary from a writable directory
class_uid = 1006 and activity_id in 1,2
and (job.file.name in "powershell.exe","cmd.exe","wscript.exe","cscript.exe","mshta.exe","rundll32.exe"
or job.file.path contains "\AppData\" or job.file.path contains "\Temp\"
or job.file.path contains "\ProgramData\")
# Tasks placed outside the library root
class_uid = 1006 and activity_id = 1
and unmapped.scheduled_job.scheduled_job_location != "\"
# Encoded or download-style payloads in the task command
class_uid = 1006
and (job.cmd_line contains "-enc" or job.cmd_line contains "FromBase64String"
or job.cmd_line contains "DownloadString" or job.cmd_line contains "IEX")
# Existing tasks disabled or deleted
class_uid = 1006 and activity_id in 3,5
# Tasks registered by an unexpected caller
class_uid = 1006 and activity_id = 1
and actor.process.name notin "schtasks.exe","taskeng.exe","svchost.exe","msiexec.exe"6.5 Script Activity (1009)
| class_uid / class_name | 1009 / "Script Activity" |
| category | 1 / "System Activity" |
| Source | AMSI (Antimalware Scan Interface) provider |
| Telemetry flag | TELEMETRY_AMSI |
| What it reveals | The script content itself, as submitted to the scripting engine — after any obfuscation the script performed on itself has been undone. |
Why this class is unusually valuable: AMSI sees content at the point the engine is about to execute it. A command line can be obfuscated; what reaches AMSI is the material the interpreter actually runs. Up to 10,000 bytes are captured per scan.
Activities
| activity_id | activity_name | type_uid | type_name |
|---|---|---|---|
| 2101 | Execute | 100901 | Script Activity: Execute |
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| script.type_id | integer | 0 Unknown, 1 Windows Cmd, 2 PowerShell, 3 Python, 4 JavaScript/JScript, 5 VBScript, 6 Unix shell, 7 VBA (Office macros), 99 Other (WMI, VSS, Exchange, .NET) |
| script.type | string | "PowerShell", "VBScript", "JavaScript", "VBA", "WMI", "VSS", "Exchange", "DotNet", "Other" |
| script.content | string | The script text, up to 10,000 bytes. Populated for inline blocks and cmdlets. Search this rather than the command line. |
| script.file.path | string | Script file path, when AMSI scanned a file-based script |
| script.file.name | string | Script file base name |
| script.file.sha256 | string | SHA-256 of the script file |
| script.name | string | Short identifier — the file base name where available |
| script.uid | string | Stable identifier for a repeated block, where available |
| unmapped.amsi_signer_verified | integer | 1 = the script file carries a valid Authenticode signature, 0 = it does not |
| unmapped.amsi_signer_publisher | string | Certificate subject. Populated when verified. |
| unmapped.amsi_signer_issuer | string | Certificate issuer. Populated when verified. |
| unmapped.amsi_signer_thumbprint | string | Certificate SHA-1 thumbprint. Populated when verified. |
| actor.process.* | object | The process that submitted content to AMSI |
| status_id / status | int / string | 1 / "Success" — the scan completed; this is not a verdict |
| message | string | e.g. "powershell.exe submitted PowerShell content to AMSI" |
Hunting
# Download cradles in script bodies
class_uid = 1009
and (script.content contains "DownloadString" or script.content contains "DownloadFile"
or script.content contains "Invoke-WebRequest" or script.content contains "Net.WebClient"
or script.content contains "Start-BitsTransfer")
# In-memory assembly loading and memory allocation
class_uid = 1009
and (script.content contains "Reflection.Assembly" or script.content contains "VirtualAlloc"
or script.content contains "CreateThread" or script.content contains "Add-Type")
# Attempts to tamper with the scan interface itself
class_uid = 1009
and (script.content contains "amsiInitFailed" or script.content contains "AmsiUtils"
or script.content contains "AmsiScanBuffer")
# Encoding and string-construction obfuscation inside the script
class_uid = 1009
and (script.content contains "FromBase64String" or script.content contains "-join"
or script.content contains "char[]" or script.content contains "-bxor")
# Office macro execution
class_uid = 1009 and script.type_id = 7
# Credential-access tooling invoked from a script
class_uid = 1009
and (script.content contains "Invoke-Mimikatz" or script.content contains "sekurlsa"
or script.content contains "MiniDumpWriteDump" or script.content contains "lsass")
# Directory and account enumeration from a script
class_uid = 1009
and (script.content contains "Get-ADUser" or script.content contains "Get-DomainUser"
or script.content contains "net group" or script.content contains "Get-NetGroupMember")
# Unsigned script files executed
class_uid = 1009 and unmapped.amsi_signer_verified = 0 and script.file.path != ""
# Proximity search on the script body
script.content spanNear ("Invoke-Expression","Base64",30,false)6.6 Device Power State Activity (1011)
| class_uid / class_name | 1011 / "Device Power State Activity" |
| category | 1 / "System Activity" |
| Source | Microsoft-Windows-User32 (System channel) 1074 (shutdown or reboot initiated), 1075 (pending shutdown aborted) |
| Telemetry flag | TELEMETRY_SHUTDOWN |
| What it reveals | Who initiated a shutdown or reboot, with which process, for which stated reason, and any operator-supplied comment. |
Activities (normalised to the OCSF 0—99 range)
| activity_id | activity_name | type_uid | Meaning |
|---|---|---|---|
| 0 | Unknown | 101100 | Unrecognised shutdown type |
| 2 | Power Off | 101102 | User32 1074 with type "shutdown" |
| 5 | Reboot | 101105 | User32 1074 with type "restart" |
| 99 | Other | 101199 | Typically User32 1075 — a pending shutdown was aborted |
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| unmapped.device_power_state.shutdown_type | string | Raw type string: "restart", "shutdown", "power off" |
| unmapped.device_power_state.reason_code | string | Shutdown reason code, e.g. "0x800000ff" |
| unmapped.device_power_state.reason_text | string | Readable reason title, e.g. "Other (Unplanned)" |
| unmapped.device_power_state.comment | string | Operator-supplied comment (shutdown /c "..."). Free text chosen by whoever ran the command. |
| unmapped.device_power_state.source_event_id | integer | 1074 or 1075 |
| actor.process.pid | integer | Resolved initiator pid |
| actor.process.file.path | string | Initiator image path — the primary in-event identity |
| actor.process.* | object | Enriched from cache: uid, name, cmd_line, hashes, user |
| actor.user.name / .domain / .uid | string | Initiating user, split from DOMAIN\user; well-known service SIDs are typed as System |
| observables[0] | object | type = "Process" with the initiator image path; on an abort with no initiator, type = "User" with the username |
| status_id / status_detail | int / string | 1 + "System shutdown or restart was initiated", or 99 + "A pending system shutdown or restart was aborted" |
| message | string | e.g. "System restart initiated by shutdown.exe on behalf of CONTOSO\admin" |
Hunting
# All shutdown and reboot activity in the window
class_uid = 1011
# Reboots initiated by an unexpected process
class_uid = 1011 and activity_id in 2,5
and actor.process.name notin "shutdown.exe","explorer.exe","winlogon.exe","svchost.exe"
# A comment was left on the shutdown
class_uid = 1011 and unmapped.device_power_state.comment != ""
# Reboot driven from a script engine
class_uid = 1011
and actor.process.name in "powershell.exe","cmd.exe","wscript.exe","cscript.exe"
# Unplanned shutdowns
class_uid = 1011 and unmapped.device_power_state.reason_text contains "Unplanned"6.7 Registry Key Activity (201001)
| class_uid / class_name | 201001 / "Registry Key Activity" |
| category | 1 / "System Activity" |
| Source | Kernel-mode registry monitoring |
| Telemetry flag | TELEMETRY_REGISTRY, plus the global registry filter allowlist and the per-process daily limits in 3.5 |
| What it reveals | Registry keys created, deleted, renamed, read, and had their security descriptors changed — with the responsible process. |
Activities
| activity_id | activity_name | type_uid | Source operation |
|---|---|---|---|
| 100 | Unknown | 20100100 | unmapped operation |
| 101 | Create | 20100101 | key create |
| 102 | Read | 20100102 | key query, value enumeration, key save |
| 104 | Delete | 20100104 | key delete |
| 105 | Rename | 20100105 | key rename |
| 106 | Set Security | 20100106 | key security descriptor set |
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| reg_key.path | string | Full key path, lowercase, in NT form — e.g. "\registry\machine\software\microsoft\windows\currentversion\run". Match with contains using lowercase fragments; do not anchor on HKLM. |
| prev_reg_key.path | string | Key path before a rename |
| actor.process.* | object | The process performing the operation |
| actor.user.* | object | User context |
| observables[0].type | string | "Registry"; name is one of "Registry Key Create Event", "Registry Key Delete Event", "Registry Key Rename Event", "Registry Key Security Event", "Registry Key Query Event", "Registry Key Save Event", "Registry Value Enumerate Event" |
| status_id / status_detail | int / string | 1; "Create Success", "Delete Success", "Rename Success", "Set Security Success", "Query Key", "Enumerate Values", "Save Key" |
| message | string | e.g. "Registry key information was queried (informationClass 2)" |
Read operations are reported as the request is made, so status_detail describes the attempt ("Query Key") rather than an outcome.
Hunting
# Keys created under a persistence location
class_uid = 201001 and activity_id = 101
and (reg_key.path contains "currentversion\run"
or reg_key.path contains "image file execution options"
or reg_key.path contains "\services\")
# Registry permission changes from an unexpected process
class_uid = 201001 and activity_id = 106
and actor.process.name notin "services.exe","svchost.exe","msiexec.exe","TrustedInstaller.exe"
# A registry hive was saved to a file
class_uid = 201001 and activity_id = 102 and status_detail = "Save Key"
# Enumeration of a sensitive hive
class_uid = 201001 and activity_id = 102
and reg_key.path contains "\securityproviders\"
# Security-product keys deleted
class_uid = 201001 and activity_id = 104
and reg_key.path contains "windows defender"
# Everything one process did in the registry
class_uid in 201001,201002 and actor.process.uid = "<uid>"6.8 Registry Value Activity (201002)
| class_uid / class_name | 201002 / "Registry Value Activity" |
| category | 1 / "System Activity" |
| Source | Kernel-mode registry monitoring |
| Telemetry flag | TELEMETRY_REGISTRY, plus the global registry filter allowlist and the per-process daily limits in 3.5 |
| What it reveals | Registry values written, deleted and read — including the value data itself, typed according to the registry data type. |
Activities
| activity_id | activity_name | type_uid | Source operation |
|---|---|---|---|
| 202 | Read | 20100202 | value query |
| 203 | Modify | 20100203 | value set |
| 204 | Delete | 20100204 | value delete |
A newly created value is reported as Modify (203), so hunt activity_id in 203,204 when you want writes.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| reg_value.name | string | The value name, e.g. "SecurityHealth", "Debugger" |
| reg_value.path | string | Full key path holding the value (lowercase NT form) |
| reg_value.type_id | integer | Windows REG_* type — 0 NONE, 1 SZ, 2 EXPAND_SZ, 3 BINARY, 4 DWORD, 5 DWORD_BE, 6 LINK, 7 MULTI_SZ, 8 RESOURCE_LIST, 9 FULL_RESOURCE_DESCRIPTOR, 10 RESOURCE_REQUIREMENTS_LIST, 11 QWORD |
| reg_value.type | string | Caption, e.g. "REG_SZ", "REG_DWORD" |
| reg_value.reg_string_data | string | Data for REG_SZ / REG_EXPAND_SZ / REG_LINK, decoded to UTF-8. Where a Run-key command line lives. |
| reg_value.reg_integer_data | integer | Data for REG_DWORD / REG_DWORD_BIG_ENDIAN / REG_QWORD |
| reg_value.reg_binary_data | string (base64) | Data for REG_NONE / REG_BINARY and the resource types. A large binary value written and later read back is a recognised payload-storage pattern. |
| reg_value.reg_string_list_data | string[] | Data for REG_MULTI_SZ, split into elements |
| actor.process.* | object | The writing process |
| actor.user.* | object | User context |
| observables[0].type | string | "Registry"; name is "Registry Value Modify Event", "Registry Value Delete Event" or "Registry Value Query Event" |
| status_id / status_detail | int / string | 1; "Modify Success", "Delete Value Success", "Query Value" |
On Read (202) only name and path are populated. The event is reported as the request is made, so the value type and data are not part of it.
Hunting
# Run-key writes, with the payload
class_uid = 201002 and activity_id = 203
and reg_value.path contains "currentversion\run"
# → reg_value.reg_string_data is the command that will execute at logon
# Run-key payload pointing at a writable directory or a script engine
class_uid = 201002 and activity_id = 203
and reg_value.path contains "currentversion\run"
and (reg_value.reg_string_data contains "\AppData\"
or reg_value.reg_string_data contains "\Temp\"
or reg_value.reg_string_data contains "powershell")
# Image File Execution Options debugger hijack
class_uid = 201002 and activity_id = 203
and reg_value.path contains "image file execution options"
and reg_value.name in "Debugger","GlobalFlag","ReportingMode","MonitorProcess"
# Service binary path or worker DLL redirected
class_uid = 201002 and activity_id = 203
and reg_value.path contains "\services\"
and reg_value.name in "ImagePath","ServiceDll"
# Large binary values written by a script engine
class_uid = 201002 and activity_id = 203
and reg_value.type_id = 3
and actor.process.name in "powershell.exe","wscript.exe","cscript.exe","mshta.exe","rundll32.exe"
# Security-product configuration disabled via policy values
class_uid = 201002 and activity_id = 203
and reg_value.path contains "windows defender"
and reg_value.name in "DisableAntiSpyware","DisableRealtimeMonitoring","DisableBehaviorMonitoring"
# Elevation-prompt settings changed
class_uid = 201002 and activity_id = 203
and reg_value.name in "EnableLUA","ConsentPromptBehaviorAdmin","FilterAdministratorToken"
# Registry writes from processes outside the usual system paths
class_uid = 201002 and activity_id = 203
and actor.process.file.path notcontains "System32"
and actor.process.file.path notcontains "Program Files"6.9 Suspicious Behaviour Activity (201003)
| class_uid / class_name | 201003 / "Suspicious Behaviour Activity" |
| category | 1 / "System Activity" |
| Source | Kernel-mode behaviour detection — the verdict is formed on the endpoint |
| Telemetry flag | none; flows whenever collection is on |
| What it reveals | A named, pre-judged behaviour: injection, image tampering, credential access, log clearing, exfiltration, ransomware, and many more. Includes whether the action was blocked or only observed. |
Activities
| activity_id | activity_name |
|---|---|
| 1500 | Suspicious Behaviour Activity |
Filter this class on class_uid = 201003.
Fields
| Field | Type | Description |
|---|---|---|
| actor.process.* | object | The process responsible, enriched from cache |
| actor.user.* | object | User context |
| status_id / status | int / string | 1 / "Success" |
| status_detail | string | "Suspicious behaviour was blocked" or "Suspicious behaviour was detected" — the block-versus-observe distinction |
| message | string | A JSON document containing the full detection record — see below |
| dpid | integer | Chain token |
Reading message — it is a JSON document, not prose. Its keys:
| Key | Meaning |
|---|---|
| driverSuspReason | The detection reason, as a name string (e.g. "PROCESS_HOLLOWING_DETECTION"). This is the field to hunt. |
| processId / processuuid | The process responsible |
| threadId | The thread responsible |
| isBlocked | true = the action was prevented |
| message | Detection detail |
| eventType | The originating raw event type |
| yara_rule | Matching rule name, where a rule match drove the detection |
| isInjector / isInjectee | Which side of an injection pair this record represents |
| severity | Severity as reported with the detection: "critical", "high", "medium", "low" |
| AlternateUuid | Alternate process UUID |
Because driverSuspReason is a name string, substring matching works directly:
class_uid = 201003 and message contains "PROCESS_HOLLOWING_DETECTION"Detection reasons, grouped by theme
| Theme | driverSuspReason values |
|---|---|
| Cross-process injection | CLASSIC_DLL_INJECTION, PE_INJECTION, PE_INJECTION_PATTERN_CHECK, APC_INJECTION, EARLY_BIRD_APC_INJECTION, THREAD_EXECUTION_HIJACK, THREAD_POOL_INJECTION, MODULE_STOMPING_REMOTE, SHELLCODE_INJECTED_AND_STARTED, REMOTE_SECTION_UNMAP, PROCESS_REFLECTION |
| Process image tampering | PROCESS_HOLLOWING_DETECTION, PROCESS_HOLLOWING_WRITE_ACCESS, PROCESS_GHOSTING, PROCESS_DOPPELGANGING, PROCESS_ARGUMENT_SPOOFING |
| Reflective and manual loading | POSSIBLE_REFLECTIVE_LOADING, MANUAL_DLL_LOADING, MEMORY_MAPPED_REGION, CALL_FROM_UNBACKED_REGION, THREAD_STARTED_FROM_UNBACKED_REGION, LOAD_LIBRARY_AS_THREAD_FUNC, STRIPPED_PAYLOAD |
| Shellcode staging patterns | METASPLOIT_VALLOC_OR_VPRO_INIOCTL, METASPLOIT_POSSIBLE_INIOCTL, METASPLOIT_VALLOC_OR_VPRO_INIOCTL_THREAD, MEATSPLOIT_VALLOC_OR_VPRO_INIOCTL_THREAD_MAP, METASPLOIT_VALLOC_OR_VPRO_ALT_INIOCTL, MS_TRIGGER_HIGH_HEAP, MS_TRIGGER_VIRTUAL_PROCTECT, API_TRIGGER_VALLOC_VWRITE_RTHREAD, AMS_TRIGGER_DETECTION, AMS_TRIGGER_RESUME_THREAD, AMS_TRIGGER_ALLOCATEVM, AMS_TRIGGER_WRITEVM_BINARY, AMS_TRIGGER_WRITEVM_BINARY_REMOTE |
| Credential access | LSASS_OPEN_HANDLE, LSASS_REMOTE_THREAD |
| Directory replication | ReplicatingDirectoryChanges, ReplicatingDirectoryChangesAll, ReplicatingDirectoryChangesFiltered |
| Monitoring interference | ETW_PATCHING, EDR_ETW_SESSION_STOPING, APIHook_Patching, DIRECT_SYSCALL, INDICATOR_REMOVAL_FROM_TOOLS, UNAUTHORIZED_ACCESS_BLOCKED, UNAUTHORIZED_MEEDR_PROCESS_LAUNCH |
| Event-log clearing | SECURITY_LOG_CLEARED, SYSTEM_LOG_CLEARED, OTHER_EVENT_LOG_CLEARED |
| Backup interference | VSS_TAMPER_PROTECTION |
| Ransomware and encryption | POSSIBLE_RANSOMWARE_DETECTION, CONFIRMED_RANSOMWARE_DETECTION, COMPRESSION_DETECTION, OBFUSCATED_FILES_COMPRESSION, OBFUSCATED_FILE_ENCRYPTED |
| Collection | CLIPBOARD_DATA, SCREENSHOT, AUTOMATED_COLLECTION, DATA_FROM_LOCAL_SYSTEM, DATA_FROM_NETWORK_DRIVE, DATA_STAGING_LOCAL, ARCHIVE_VIA_UTILITY, ARCHIVE_CUSTOM_METHOD |
| Exfiltration | EXFILTRATION_DETECTION, EXFILTRATION_OVER_C2_CHANNEL, EXFILTRATION_OVER_ALTERNATIVE_PROTOCOL, EXFILTRATION_T1048_001, EXFILTRATION_T1048_002, EXFILTRATION_T1048_003, EXFILTRATION_TO_CLOUD_STORAGE, DATA_TRANSFER_SIZE_LIMIT |
| Tunnelling and outbound protocol use | DNS_TUNNELING, smb_negotiate_outbound |
| Logon anomalies | LOGON_ANOMALY_DETECTION, LOGON_ANAMOLY_POSSIBLE_PTH |
| Account creation | SAMR_CREATE_USER_ATTEMPT — an account-creation call with no matching successful creation event |
| Obfuscation and dynamic resolution | DYNAMIC_API_RESOLUTION, OBFUSCATED_COMMAND |
| Script-engine rule matches | AMSI_YARA_BEHAVIOUR |
Hunting
# Every behaviour judged suspicious in the window
class_uid = 201003
# Only what it actually blocked
class_uid = 201003 and status_detail contains "blocked"
# Injection and image-tampering family
class_uid = 201003
and (message contains "INJECTION" or message contains "HOLLOWING"
or message contains "SHELLCODE_INJECTED" or message contains "THREAD_EXECUTION_HIJACK")
# Access to the credential-store process
class_uid = 201003
and (message contains "LSASS_OPEN_HANDLE" or message contains "LSASS_REMOTE_THREAD")
# Directory replication requests
class_uid = 201003 and message contains "ReplicatingDirectoryChanges"
# Event-log clearing
class_uid = 201003 and message contains "LOG_CLEARED"
# Interference with monitoring
class_uid = 201003
and (message contains "ETW_PATCHING" or message contains "EDR_ETW_SESSION_STOPING"
or message contains "APIHook_Patching" or message contains "DIRECT_SYSCALL")
# Confirmed encryption activity
class_uid = 201003 and message contains "CONFIRMED_RANSOMWARE_DETECTION"
# Logon anomalies
class_uid = 201003 and message contains "LOGON_AN"
# Critical-severity detections
class_uid = 201003 and message contains "\"severity\": \"critical\""
# Both sides of an injection pair
class_uid = 201003 and (message contains "\"isInjector\": true"
or message contains "\"isInjectee\": true")6.10 Windows Service Activity (201004)
| class_uid / class_name | 201004 / "Windows Service Activity" |
| category | 1 / "System Activity" |
| Source | Security 4697; SCM 7000, 7009, 7022, 7023, 7024, 7031, 7034, 7038, 7039, 7040, 7041, 7045; MS-Services 105 (state change) and 200—205 (control, config, start). Remote creation correlates 4697 with a preceding network logon. |
| Telemetry flag | TELEMETRY_SERVICE_LIFECYCLE; remote creation via TELEMETRY_REMOTE |
| What it reveals | The full service definition — binary, run-as account, start type, service type, dependencies — plus who installed, reconfigured, started or stopped it. |
Activities (normalised to the OCSF 0—99 range)
| activity_id | activity_name | type_uid | Typical source |
|---|---|---|---|
| 0 | Unknown | 20100400 | — |
| 1 | Create | 20100401 | Security 4697, SCM 7045 |
| 2 | Reconfigure | 20100402 | SCM 7040, MS-Services 201/202/203 |
| 3 | Start | 20100403 | MS-Services 204/205, 105 running |
| 4 | Stop | 20100404 | MS-Services 200 (stop control), 105 stopped, SCM 7034 |
| 5 | Pause | 20100405 | MS-Services 200, 105 paused |
| 6 | Continue | 20100406 | MS-Services 200, 105 resume |
| 7 | Delete | 20100407 | — |
| 99 | Other | 20100499 | — |
Caller-led versus service-led events — essential to reading this class correctly:
| Source EID | Shape | actor.process |
|---|---|---|
| 4697, 200, 201, 202, 203, 204 | Caller-led — "this caller did X to service Y" | The SCM client (sc.exe, net1.exe, powershell.exe) — who did it |
| 105, 7000, 7031, 7034, 7038, 7041 | Service-led — "service Y did X" | Often absent; there is no caller. win_service.hosting_process.pid is the worker. |
| 7039 | Mismatch — the connected pid differs from the SCM-launched pid | Both are populated; the mismatch is itself the signal |
A single service start produces two records: 204 (the caller that invoked the start) and 105 running (the launched worker). Use 204 for attribution and 105 for confirmation.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| win_service.name | string | SCM short name — the key under HKLM\SYSTEM\CurrentControlSet\Services |
| win_service.cmd_line | string | Full launch command / ImagePath; mirrors service_file.path when no separate command line exists |
| win_service.service_file.path | string | The service binary, verbatim |
| win_service.service_file.name | string | Clean executable base name, with quotes and trailing arguments stripped |
| win_service.service_dll_file.path / .name | string | Worker DLL for shared-host services |
| win_service.service_start_name | string | Run-as account (LocalSystem, NT AUTHORITY\NetworkService, domain\user) |
| win_service.service_start_type_id | integer | 1 Boot, 2 System, 3 Auto, 4 Demand, 5 Disabled |
| win_service.service_start_type | string | Caption of the above |
| win_service.service_type_id | integer | 1 Kernel driver, 2 Filesystem driver, 3 Own process, 4 Share process, 5 Recognizer driver, 6 Adapter |
| win_service.service_type | string | Caption, with modifier flags appended: " [user service]", " [user-service instance]", " [interactive]", " [packaged]" |
| win_service.service_category_id / .service_category | int / string | 1 / "Kernel Mode" for driver types; 2 / "User Mode" for process types |
| win_service.service_dependencies | string[] | SCM load dependencies |
| win_service.hosting_process.pid | integer | The process actually running the service. Distinct from actor.process. |
| unmapped.win_service_lifecycle.display_name | string | SCM display name, separate from the short key |
| unmapped.win_service_lifecycle.persistence_flags | string[] | "runs-as-localsystem", "runs-as-localservice", "runs-as-networkservice", "runs-as-virtual-service-account", "runs-as-user-account", "auto-restart-configured" |
| unmapped.win_service_lifecycle.state_transition | string | e.g. "state: running", "state: stopped" |
| unmapped.win_service_lifecycle.start_type_transition | string | e.g. "set to Auto" |
| unmapped.win_service_lifecycle.recovery | string | e.g. "action=Restart the service, failure count 3" |
| actor.process.* | object | The SCM caller — see the table above |
| actor.user.* | object | Subject who invoked the operation |
| session.uid | string | Subject logon LUID |
| is_remote | boolean | true on remote service creation |
| src_endpoint.hostname / .ip / .port | string / string / int | Remote origin, on remote creation |
| observables[0].type | string | "Service", or "RemoteService" for remote creation; name = service short name |
| status_id / status_code / status_detail | int / string / string | Passed through from the source |
| message | string | Readable one-liner, e.g. "sc.exe (PUUID …) installed service 'Updater' -> runs C:\Temp\svc.exe as LocalSystem (start: Auto)" |
Hunting
# All service installation
class_uid = 201004 and activity_id = 1
# New SYSTEM-level service running from a writable directory
class_uid = 201004 and activity_id = 1
and unmapped.win_service_lifecycle.persistence_flags contains "runs-as-localsystem"
and (win_service.service_file.path contains "\Temp\"
or win_service.service_file.path contains "\AppData\"
or win_service.service_file.path contains "\ProgramData\"
or win_service.service_file.path contains "\Users\")
# Driver services installed
class_uid = 201004 and activity_id = 1 and win_service.service_type_id in 1,2
# Service binary path changed after installation
class_uid = 201004 and activity_id = 2 and win_service.service_file.path != ""
# Start type flipped to automatic
class_uid = 201004 and activity_id = 2
and unmapped.win_service_lifecycle.start_type_transition contains "Auto"
# Security and backup services stopped
class_uid = 201004 and activity_id = 4
and (win_service.name contains "Defender"
or win_service.name in "WinDefend","Sense","MsSecFlt","wuauserv","VSS","BITS","SQLWriter")
# Who stopped services? (caller-led control events carry the caller)
class_uid = 201004 and activity_id = 4
and actor.process.name in "sc.exe","net.exe","net1.exe","powershell.exe","taskkill.exe"
# Shared-host worker DLL outside the system directory
class_uid = 201004 and win_service.service_dll_file.path != ""
and win_service.service_dll_file.path notcontains "\System32\"
# Services configured to restart themselves automatically
class_uid = 201004
and unmapped.win_service_lifecycle.persistence_flags contains "auto-restart-configured"
# An unexpected process answered the service start
class_uid = 201004 and message contains "UNEXPECTED process"
# Remotely created services
class_uid = 201004 and activity_id = 1 and is_remote = true6.11 WMI Activity (201005)
| class_uid / class_name | 201005 / "WMI Activity" |
| category | 1 / "System Activity" |
| Source | Microsoft-Windows-WMI-Activity/Operational 11 (operation start), 20 (object write confirmed), 21 (event delivered to consumer), 5858 (operation failed), 5860 (temporary subscription registered), 5861 (permanent binding activated) |
| Telemetry flag | TELEMETRY_WMI_ACTIVITY |
| What it reveals | WMI event-subscription definitions in full — the WQL trigger, the consumer class, and the actual payload command line or inline script — plus WMI queries and operation failures. |
Activities — the full 1600-block value is reported:
| activity_id | activity_name | type_uid | Source EID | Meaning |
|---|---|---|---|---|
| 1600 | Unknown | 20100500 | — | |
| 1601 | Connect | 20100501 | 11 | Namespace connection |
| 1602 | Query | 20100502 | 11 | WQL query execution |
| 1603 | Create | 20100503 | 11, 20 | An object was written — the subscription install itself |
| 1604 | Delete | 20100504 | 11 | An object was removed |
| 1605 | Binding Activated | 20100505 | 5861 | A filter-to-consumer binding is now live. Severity High. |
| 1606 | Temporary Subscription | 20100506 | 5860 | A session-scoped subscription was registered |
| 1608 | Failure | 20100508 | 5858 | The WMI operation failed. Severity Medium. |
| 1609 | Event Delivered | 20100509 | 21 | The consumer fired — the subscription actually executed. Severity Medium. |
| 1699 | Other | 20100599 | — |
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| unmapped.wmi_activity.wmi_namespace | string | root\subscription for subscriptions, root\CIMV2 for most queries |
| unmapped.wmi_activity.wmi_operation | string | Full operation string, e.g. Start IWbemServices::PutInstance - root\subscription : __EventFilter.Name="Updater" |
| unmapped.wmi_activity.filter_name | string | The event filter's name |
| unmapped.wmi_activity.filter_query | string | The WQL trigger, e.g. SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' |
| unmapped.wmi_activity.filter_query_language | string | Typically WQL |
| unmapped.wmi_activity.filter_event_namespace | string | The namespace the filter watches |
| unmapped.wmi_activity.consumer_name | string | Consumer name from the binding |
| unmapped.wmi_activity.consumer_type | string | CommandLineEventConsumer, ActiveScriptEventConsumer, LogFileEventConsumer, SMTPEventConsumer, NTEventLogEventConsumer |
| unmapped.wmi_activity.consumer_executable | string | The payload binary |
| unmapped.wmi_activity.consumer_command_line | string | The payload command line |
| unmapped.wmi_activity.consumer_script_text | string | Inline VBScript or JScript payload |
| unmapped.wmi_activity.consumer_script_engine | string | VBScript or JScript |
| unmapped.wmi_activity.consumer_script_file | string | Script file the consumer runs |
| unmapped.wmi_activity.raw_mof | string | Raw MOF definition, truncated at 1 KB with "...(truncated)" appended |
| unmapped.wmi_activity.source_event_id | integer | 11, 20, 21, 5858, 5860, 5861 |
| unmapped.wmi_activity.result_code | string | WMI result code, e.g. "0x80041032" |
| unmapped.wmi_activity.possible_cause | string | Failure detail from EID 5858 |
| unmapped.wmi_activity.operation_id | string | Correlation key joining a write-confirm event back to its operation start and to sibling events for the same install |
| unmapped.wmi_activity.delivery_count | integer | How many events were delivered to the consumer |
| unmapped.wmi_activity.consumer_delivery_ref | string | Full consumer path, e.g. //./root/subscription:CommandLineEventConsumer="Updater" |
| unmapped.wmi_activity.subscription_type | string | "Permanent" or "Temporary" |
| actor.user.name / .domain | string | Caller identity, on the operation-start and failure events |
| actor.process.* | object | Caller process. On EID 5861 and EID 21 the payload carries no client pid, so the WMI subscription service is reported. |
| device.hostname | string | Falls back to the WMI client machine name where not already set |
| component | string | The WMI namespace, for categorisation |
| observables[0].type | string | "WMI"; name = consumer name, else namespace, else "WMI Activity" |
| severity_id / severity | int / string | 4 High on EID 5861; 3 Medium on EID 21 and on failures; 1 Informational otherwise |
| status_id / status_code / status_detail | int / string / string | Failure on EID 5858, with the result code and cause surfaced |
| message | string | e.g. "WMI binding activated in root\subscription [op=…] [query=SELECT * FROM …] [cmd=powershell -enc …]" |
Attribution on EID 5861 and EID 21: these events are emitted by the WMI subscription service rather than by the process that created the subscription, so actor.process reflects that service. To attribute the install, correlate back to the Create events (EID 11 / 20) for the same filter or consumer name, or pivot on dpid.
Hunting
# A subscription binding went live — the highest-value WMI query
class_uid = 201005 and activity_id = 1605
# A subscription actually executed
class_uid = 201005 and activity_id = 1609
# Any object written into the subscription namespace
class_uid = 201005 and activity_id = 1603
and unmapped.wmi_activity.wmi_namespace contains "subscription"
# Command-line consumer payloads
class_uid = 201005
and unmapped.wmi_activity.consumer_type = "CommandLineEventConsumer"
and unmapped.wmi_activity.consumer_command_line != ""
# Inline script consumer payloads
class_uid = 201005 and unmapped.wmi_activity.consumer_script_text != ""
# Encoded payload in a consumer
class_uid = 201005
and (unmapped.wmi_activity.consumer_command_line contains "-enc"
or unmapped.wmi_activity.consumer_command_line contains "FromBase64String"
or unmapped.wmi_activity.consumer_script_text contains "FromBase64String")
# Trigger types commonly used for persistence
class_uid = 201005
and (unmapped.wmi_activity.filter_query contains "__InstanceCreationEvent"
or unmapped.wmi_activity.filter_query contains "Win32_LogonSession"
or unmapped.wmi_activity.filter_query contains "__TimerEvent"
or unmapped.wmi_activity.filter_query contains "Win32_ProcessStartTrace")
# Temporary subscriptions
class_uid = 201005 and activity_id = 1606
# Security-product enumeration through WMI
class_uid = 201005 and activity_id = 1602
and (unmapped.wmi_activity.filter_query contains "AntiVirusProduct"
or unmapped.wmi_activity.filter_query contains "FirewallProduct")
# Subscription removal
class_uid = 201005 and activity_id = 1604
# One install, end to end
class_uid = 201005 and unmapped.wmi_activity.operation_id = "<id>"6.12 Command Activity (201007)
| class_uid / class_name | 201007 / "Command Activity" |
| category | 1 / "System Activity" |
| Source | Shell session monitoring — interactive shell input and output |
| Telemetry flag | TELEMETRY_REMOTE |
| What it reveals | Both the commands typed into an interactive shell and the shell's responses, for remote sessions and local sessions alike. For remote sessions it also carries the client IP and port. |
Activities
| activity_id | activity_name |
|---|---|
| 2000 | Command Activity |
Filter this class on class_uid = 201007.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| unmapped.command_activity.input_command | string | The command that was entered. |
| unmapped.command_activity.output_command | string | The shell's response. Proves whether a command returned data. |
| unmapped.command_activity.process_id | integer | Pid hosting the shell session |
| unmapped.command_activity.process_uuid | string | UUID of the shell host — use this to assemble a session transcript |
| unmapped.command_activity.ip_version | integer | 4 or 6; remote sessions only |
| unmapped.command_activity.remote_ip | string | Client IP; remote sessions only |
| unmapped.command_activity.remote_port | integer | Client port; remote sessions only |
| unmapped.command_activity.local_ip | string | Local IP of the shell host; remote sessions only |
| unmapped.command_activity.local_port | integer | Local port; remote sessions only |
| is_remote | boolean | true = remote session; absent or false = local shell |
| src_endpoint.ip / .port | string / int | Remote origin, mirroring remote_ip / remote_port |
| actor.process.* | object | The shell host process |
| observables[0].type | string | "Command"; name = the input command |
Hunting
# Any remote interactive shell session
class_uid = 201007 and is_remote = true
# → unmapped.command_activity.remote_ip is the client address
# Host and domain enumeration typed into a shell
class_uid = 201007
and (unmapped.command_activity.input_command contains "whoami"
or unmapped.command_activity.input_command contains "systeminfo"
or unmapped.command_activity.input_command contains "ipconfig"
or unmapped.command_activity.input_command contains "net user"
or unmapped.command_activity.input_command contains "net group"
or unmapped.command_activity.input_command contains "nltest"
or unmapped.command_activity.input_command contains "arp -a")
# Credential-access commands
class_uid = 201007
and (unmapped.command_activity.input_command contains "lsass"
or unmapped.command_activity.input_command contains "mimikatz"
or unmapped.command_activity.input_command contains "reg save"
or unmapped.command_activity.input_command contains "ntdsutil"
or unmapped.command_activity.input_command contains "vssadmin")
# Commands that weaken defences or destroy recovery points
class_uid = 201007
and (unmapped.command_activity.input_command contains "wevtutil"
or unmapped.command_activity.input_command contains "vssadmin delete"
or unmapped.command_activity.input_command contains "bcdedit"
or unmapped.command_activity.input_command contains "Set-MpPreference"
or unmapped.command_activity.input_command contains "netsh advfirewall")
# Enumeration that actually returned data
class_uid = 201007
and unmapped.command_activity.input_command contains "net group"
and unmapped.command_activity.output_command != ""
# Full transcript of one shell session, in order
class_uid = 201007
and unmapped.command_activity.process_uuid = "<uuid>"
# sort by time6.13 API Telemetry Activity (201008)
| class_uid / class_name | 201008 / "API Telemetry Activity" |
| category | 1 / "System Activity" |
| Source | In-process API monitoring across the ntdll, win32u, kernel32, advapi32, crypt32, bcrypt, cabinet, lz32, iphlpapi and vaultcli surfaces |
| Delivery | Finding context — see below |
| What it reveals | Individual API calls: anti-analysis probes, credential-store reads, cross-process injection primitives, token operations, cryptography, decompression and registry payload storage. |
How to query this class. It is delivered as the context of a Detection Finding rather than as a standalone event:
`
class_uid = 2004 and associated_class_uid = 201008
`
Activities
| activity_id | activity_name | type_uid | type_name |
|---|---|---|---|
| 2301 | Query | 20100801 | "API Telemetry Activity: ApiTelemetry_<ApiName>" |
One activity by design — the API identity travels in unmapped.api_telemetry.api_name and in type_name.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| unmapped.api_telemetry.api_name | string | The API, as a name string — e.g. "ApiTelemetry_NtCreateRemoteThread". The field to hunt. |
| unmapped.api_telemetry.source_api_id | integer | Numeric identifier (0 = Unknown) |
| unmapped.api_telemetry.module_name | string | Source module, e.g. "kernel32.dll" |
| unmapped.api_telemetry.parameter | string | The call's input arguments, pipe-joined. Where paths, key names, sizes, flags and mode names appear. |
| unmapped.api_telemetry.message | string | The raw record segment, including the result slot |
| unmapped.api_telemetry.process_uuid | string | Calling process UUID, consistent with actor.process.uid |
| actor.process.* | object | The calling process — monitoring is in-process, so this is always the caller |
| type_name | string | Carries the API name; a convenient alternative filter |
| status_id / status | int / string | 1 / "Success" — an observation, not a verdict |
| message | string | A JSON document containing the full API record. Substring-searchable. |
Data-handling note that shapes detections: buffer contents are not captured for the cryptography, compression and registry APIs. You get addresses, lengths, algorithm and mode names, and key or value names and types — not key material, plaintext or registry value data. Build detections on the call sequence, not on payload bytes.
Hooked APIs by purpose
| Purpose | API names (ApiTelemetry_ prefix omitted) |
|---|---|
| Debugger and process introspection | NtQueryInformationProcess, NtSetInformationThread, NtCreateThreadEx, GetThreadContext, NtQuerySystemInformation, GetForegroundWindow, NtUserFindWindowEx, DebugActiveProcess, AddVectoredExceptionHandler, NtQueryObject, SetUnhandledExceptionFilter |
| Environment and timing checks | BlockInput, NtDelayExecution, GetAsyncKeyState, GetKeyState, GetKeyboardState, GetDiskFreeSpaceExA/W, GetAdaptersAddresses, GetAdaptersInfo, RtlQueryPerformanceCounter/Frequency, NtQueryPerformanceCounter, GetSystemTimeAsFileTime, GetSystemTime, GetLocalTime, NtQuerySystemTime, timeGetTime, GetLastInputInfo, IsNativeVhdBoot, GetComputerNameA/W/ExW, NtCreateTimer, GetCursorPos, GlobalMemoryStatusEx, GetPhysicallyInstalledSystemMemory, RtlQueryEnvironmentVariable_U, NtWaitForSingleObject, NtWaitForMultipleObjects, NtSignalAndWaitForSingleObject, GetUserNameA/W, EnumWindows, GetSystemInfo, EnumProcessModules, RtlGetVersion, GetVolumeInformationA/W, GetTickCount, GetTickCount64 |
| Credential stores | CredReadW/A, CredEnumerateW/A, CredWriteW, VaultOpenVault, VaultEnumerateItems, VaultGetItem |
| Token operations | NtDuplicateToken, ImpersonateLoggedOnUser, SetThreadToken, NtQueryInformationToken |
| Process creation | NtCreateUserProcess(+Suspended), NtCreateProcessEx(+Suspended), NtCreateProcess(+Suspended), ProcessStartedSuspended |
| Cross-process memory and thread operations — foreign-process target only; self-operations are not reported | NtAllocateVirtualMemoryRemote, NtWriteVirtualMemoryRemote, NtWriteVirtualMemoryRemoteExecutable, NtProtectVirtualMemoryRemote, NtCreateRemoteThread, NtUnmapViewOfSectionRemote |
| Suspend and resume | NtSuspendProcess, NtResumeProcess, ProcessSuspended |
| Security descriptors, files and objects | NtSetSecurityObject, NtQuerySecurityObject, NtCreateFile, NtCreateDirectoryFile, NtQueryAttributesFile, NtSetInformationFile, NtCreateMutant, NtOpenMutant |
| Window visibility | NtUserShowWindow, NtUserShowWindowAsync, NtUserSetWindowPos, NtUserAnimateWindow |
| Error-mode suppression | NtSetInformationProcess — reported for the hard-error-mode class only; the target pid is resolved from the handle, so a cross-process set is distinguishable from a self set |
| Network connection enumeration | GetExtendedTcpTable — the API behind netstat -ano |
| Dynamic resolution | GetModuleFileNameW, GetProcAddress — the name field carries the ordinal when resolution is by ordinal |
| Decompression and unpacking | RtlDecompressBuffer(Ex/Ex2), RtlDecompressFragment(Ex), RtlGetCompressionWorkSpaceSize; CreateDecompressor, Decompress, QueryDecompressorInformation, ResetDecompressor, SetDecompressorInformation, CloseDecompressor; FDICreate, FDICopy (the archive-extraction call), FDIIsCabinet, FDITruncateCabinet, FDIDestroy; LZOpenFileA/W, LZCopy, LZRead, LZSeek, LZInit, LZClose, GetExpandedNameA/W (recovers the original filename from the compressed header) |
| Legacy cryptography — the sequence is the signal | CryptAcquireContextA/W → CryptCreateHash → CryptHashData → CryptDeriveKey → CryptDecrypt; plus CryptImportKey, CryptSetKeyParam, CryptGenKey, CryptDestroyKey, CryptReleaseContext |
| Modern cryptography (CNG) — the sequence is the signal | BCryptOpenAlgorithmProvider → BCryptSetProperty (chaining mode) → BCryptGenerateSymmetricKey / BCryptImportKey / BCryptImportKeyPair / BCryptDeriveKeyPBKDF2 → BCryptDecrypt; plus BCryptDestroyKey, BCryptCloseAlgorithmProvider |
| Encoding, data protection and certificate stores | CryptStringToBinaryA/W, CryptBinaryToStringA/W (in-process encode and decode); CryptProtectData, CryptUnprotectData, CryptProtectMemory, CryptUnprotectMemory; CertOpenStore, CertAddEncodedCertificateToStore, CertEnumCertificatesInStore |
| Registry and event-log payload storage | RegSetValueExA/W, RegQueryValueExA/W, RegGetValueA/W (hive, key, value name, type and size only); ReportEventA/W (a non-empty raw-data attachment is the signal) |
Hunting
# The cross-process memory-and-thread sequence.
# Every hit is genuinely cross-process — self-operations are not reported.
class_uid = 2004 and associated_class_uid = 201008
and unmapped.api_telemetry.api_name in
"ApiTelemetry_NtAllocateVirtualMemoryRemote",
"ApiTelemetry_NtWriteVirtualMemoryRemote",
"ApiTelemetry_NtProtectVirtualMemoryRemote",
"ApiTelemetry_NtCreateRemoteThread"
# group by actor.process.uid and order by time to see the sequence
# A write directly into executable memory in another process
class_uid = 2004
and unmapped.api_telemetry.api_name = "ApiTelemetry_NtWriteVirtualMemoryRemoteExecutable"
# Credential-store reads
class_uid = 2004 and associated_class_uid = 201008
and (unmapped.api_telemetry.api_name contains "Cred"
or unmapped.api_telemetry.api_name contains "Vault")
# Protected-data decryption
class_uid = 2004 and unmapped.api_telemetry.api_name = "ApiTelemetry_CryptUnprotectData"
# Symmetric key derivation and bulk decryption
class_uid = 2004 and associated_class_uid = 201008
and unmapped.api_telemetry.api_name in
"ApiTelemetry_BCryptGenerateSymmetricKey","ApiTelemetry_BCryptDeriveKeyPBKDF2",
"ApiTelemetry_BCryptDecrypt","ApiTelemetry_CryptDeriveKey","ApiTelemetry_CryptDecrypt"
# Unpacking and decoding
class_uid = 2004 and associated_class_uid = 201008
and (unmapped.api_telemetry.api_name contains "Decompress"
or unmapped.api_telemetry.api_name contains "CryptStringToBinary"
or unmapped.api_telemetry.api_name = "ApiTelemetry_FDICopy")
# Environment and anti-analysis probing
class_uid = 2004 and associated_class_uid = 201008
and unmapped.api_telemetry.api_name in
"ApiTelemetry_NtQueryInformationProcess","ApiTelemetry_IsNativeVhdBoot",
"ApiTelemetry_GlobalMemoryStatusEx","ApiTelemetry_GetLastInputInfo",
"ApiTelemetry_NtDelayExecution","ApiTelemetry_BlockInput"
# Token duplication and impersonation
class_uid = 2004 and associated_class_uid = 201008
and unmapped.api_telemetry.api_name in
"ApiTelemetry_NtDuplicateToken","ApiTelemetry_ImpersonateLoggedOnUser",
"ApiTelemetry_SetThreadToken"
# Windows being hidden
class_uid = 2004 and unmapped.api_telemetry.api_name contains "NtUserShowWindow"
# Registry used as a payload store
class_uid = 2004 and associated_class_uid = 201008
and unmapped.api_telemetry.api_name in
"ApiTelemetry_RegSetValueExW","ApiTelemetry_RegQueryValueExW"
# Search the arguments for a value
class_uid = 2004 and associated_class_uid = 201008
and unmapped.api_telemetry.parameter contains "lsass"6.14 Volume Activity (201009)
| class_uid / class_name | 201009 / "Volume Activity" |
| category | 1 / "System Activity" |
| Source | Kernel-mode monitoring of raw volume and physical-disk handles |
| Delivery | Finding context |
| What it reveals | Reads and writes issued directly to a volume or physical disk, bypassing the filesystem and its permissions — with the exact byte offset, length, device type and filesystem. |
Query as class_uid = 2004 and associated_class_uid = 201009. This class carries no file object, so a raw-device access is never confused with a regular file access.
Activities (normalised to the OCSF 0—99 range)
| activity_id | activity_name | type_uid | Meaning |
|---|---|---|---|
| 0 | Unknown | 20100900 | |
| 1 | Open | 20100901 | A raw volume or physical-disk handle was opened |
| 2 | Read | 20100902 | A raw read, bypassing the filesystem and its permissions |
| 3 | Write | 20100903 | A raw write. Offset 0 is the boot record. |
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| unmapped.volume.volume_path | string | Device path, e.g. \Device\HarddiskVolume4, \\.\PhysicalDrive0 |
| unmapped.volume.drive_letter | string | Single drive letter ("C"); empty when the volume has none |
| unmapped.volume.raw_volume_type | string | "PhysicalDisk" (offset 0 is the master boot record), "LogicalVolume" (offset 0 is the volume boot record), "VssShadow" (a shadow copy), "Unknown" |
| unmapped.volume.offset | integer | Byte offset of the read or write; 0 on open. A write at offset 0 targets the boot record. |
| unmapped.volume.length | integer | Bytes requested; 0 on open |
| unmapped.volume.fs_type | string | "NTFS", "REFS", "FAT", "EXFAT", "RAW", "MUP", "CSVFS", "NPFS", "MSFS", and others; "Unknown" where unmapped |
| unmapped.volume.device_characteristics | integer | Bitmask: 0x1 removable media, 0x2 read-only, 0x10 remote/network device, 0x20 mounted, 0x40 virtual volume, 0x800 plug-and-play |
| unmapped.volume.sector_size | integer | Bytes per sector; 0 for a physical-disk handle |
| unmapped.volume.desired_access | integer | Access mask captured at open — read versus write intent |
| unmapped.volume.operation | integer | The operation in un-normalised form: 2501 Open, 2502 Read, 2503 Write |
| actor.process.* | object | The process holding the raw handle |
| observables[0].type | string | "Volume"; name = volume device path |
| status_id / status_detail | int / string | 1; "Raw volume access observed" |
| message | string | e.g. "Raw volume write on \Device\HarddiskVolume2" |
Hunting
# A write to the boot record
class_uid = 2004 and associated_class_uid = 201009
and activity_id = 3 and unmapped.volume.offset = 0
# Any raw write to a physical disk
class_uid = 2004 and associated_class_uid = 201009
and activity_id = 3 and unmapped.volume.raw_volume_type = "PhysicalDisk"
# Raw reads that bypass file permissions
class_uid = 2004 and associated_class_uid = 201009
and activity_id = 2 and unmapped.volume.raw_volume_type = "LogicalVolume"
# Shadow-copy access
class_uid = 2004 and associated_class_uid = 201009
and unmapped.volume.raw_volume_type = "VssShadow"
# Raw access from a process outside the system directory
class_uid = 2004 and associated_class_uid = 201009
and actor.process.file.path notcontains "System32"
# Large raw writes
class_uid = 2004 and associated_class_uid = 201009
and activity_id = 3 and unmapped.volume.length > 1048576
# Raw access to removable media
class_uid = 2004 and associated_class_uid = 201009
and unmapped.volume.device_characteristics >= 1
# test bit 0x1 in your platform6.15 On-Write Scan Result Activity (201010)
| class_uid / class_name | 201010 / "On-Write Scan Result Activity" |
| category | 1 / "System Activity" |
| Source | The scan engine's verdict on a binary a process has just written to disk |
| Delivery | Finding context |
| What it reveals | For every executable written to disk: its signer state, its PE version-info identity, the scan verdict and the model confidence — plus the process that wrote it. |
Query as class_uid = 2004 and associated_class_uid = 201010.
Activities
| activity_id | activity_name | type_uid | type_name |
|---|---|---|---|
| 2601 | Scan | 20101001 | On-Write Scan Result Activity: Scan |
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| file.path | string | The written binary's full path |
| file.name | string | Base name |
| file.sha256 | string | SHA-256 digest |
| file.hashes[] | array | algorithm_id = 3, algorithm = "SHA-256", value = digest |
| file.company_name | string | Company name from the PE header |
| file.type_id | integer | 1 Regular File |
| unmapped.on_write_scan_result.is_signed | integer | 0 = not signed, 1 = signed. Always present. |
| unmapped.on_write_scan_result.publisher | string | Authenticode signer |
| unmapped.on_write_scan_result.original_file_name | string | PE version-info original filename. A mismatch against the on-disk name indicates the file was renamed. |
| unmapped.on_write_scan_result.internal_name | string | PE version-info internal name |
| unmapped.on_write_scan_result.is_malware | integer | Engine verdict: 0 benign, 1 malicious. Always present. |
| unmapped.on_write_scan_result.confidence | float | Model probability, 0.0—1.0. 0 where the model did not score the file. |
| unmapped.on_write_scan_result.source_file_type | integer | 0 Unknown, 1 EXE, 2 DLL, 3 test file, 4 .NET assembly |
| unmapped.on_write_scan_result.rename_process_pid | integer | Second pid on the rename delivery path; 0 where no rename was involved |
| unmapped.on_write_scan_result.process_uuid | string | The writing process's UUID |
| actor.process.* | object | The process that wrote the file |
| status_id / status | int / string | 1 / "Success" — the scan completed. The verdict is is_malware. |
| message | string | e.g. "On-write scan: C:\Temp\payload.exe [unsigned] [malware]" |
Hunting
# Malicious binaries written to disk, with the writing process
class_uid = 2004 and associated_class_uid = 201010
and unmapped.on_write_scan_result.is_malware = 1
# → actor.process.* is the writer; file.path is the payload
# Unsigned executables written by a script engine
class_uid = 2004 and associated_class_uid = 201010
and unmapped.on_write_scan_result.is_signed = 0
and actor.process.name in "powershell.exe","wscript.exe","cscript.exe","mshta.exe","cmd.exe"
# Renamed binaries
class_uid = 2004 and associated_class_uid = 201010
and unmapped.on_write_scan_result.original_file_name != ""
and unmapped.on_write_scan_result.original_file_name != file.name
# High-confidence model detections
class_uid = 2004 and associated_class_uid = 201010
and unmapped.on_write_scan_result.confidence > 0.9
# .NET assemblies written to disk
class_uid = 2004 and associated_class_uid = 201010
and unmapped.on_write_scan_result.source_file_type = 4
# DLLs written outside the system directory
class_uid = 2004 and associated_class_uid = 201010
and unmapped.on_write_scan_result.source_file_type = 2
and file.path notcontains "\System32\"6.16 Network Activity (4001)
| class_uid / class_name | 4001 / "Network Activity" |
| category | 1 / "System Activity" |
| Source | Network filtering layer |
| Telemetry flag | TELEMETRY_NETWORK; 100,000 events per process per day |
| What it reveals | Which process talked to which address and port, in which direction, over which protocol, and how many bytes moved. |
Activities
| activity_id | activity_name | type_uid |
|---|---|---|
| 306 | Traffic | 400106 |
Network events are reported as Traffic. Endpoints, ports, protocol and transferred volume are the fields to build on.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| src_endpoint.ip | string | Source IP — meaning depends on direction, see below |
| src_endpoint.port | integer | Source port |
| dst_endpoint.ip | string | Destination IP |
| dst_endpoint.port | integer | Destination port |
| connection_info.direction_id | integer | 1 Inbound, 2 Outbound, 0 Unknown |
| connection_info.direction | string | "Inbound", "Outbound", "Unknown" |
| connection_info.protocol_num | integer | IANA protocol number: 1 ICMP, 6 TCP, 17 UDP, 58 ICMPv6, 0 HOPOPT |
| connection_info.protocol_name | string | "tcp", "udp", "icmp", "icmpv6", "hopopt", "unknown" |
| connection_info.protocol_ver_id | integer | 4 IPv4, 6 IPv6 |
| connection_info.protocol_ver | string | "IPv4" / "IPv6" |
| traffic.bytes | integer | Bytes transferred |
| url.url_string | string | URL extracted from the payload, where one was detected |
| actor.process.* | object | The process owning the socket |
| actor.user.* | object | User context |
| observables[0] | object | type = "IP Address"; name = "Inbound Network Connection", "Outbound Network Connection" or "Network Connection" |
| status_id / status_detail | int / string | 1; "Network Connection" |
| message | string | "Network traffic observed" |
Direction semantics — source and destination are assigned from the endpoint's point of view:
| Direction | src_endpoint | dst_endpoint |
|---|---|---|
| Outbound (direction_id = 2) | This endpoint (local) | The remote host |
| Inbound (direction_id = 1) | The remote initiator | This endpoint (local) |
Outbound (a browser reaching a website):
connection_info.direction_id = 2
src_endpoint.ip = 192.168.1.100 src_endpoint.port = 52431 ← local
dst_endpoint.ip = 142.250.189.206 dst_endpoint.port = 443 ← remote
Inbound (a remote host reaching local file sharing):
connection_info.direction_id = 1
src_endpoint.ip = 10.0.0.50 src_endpoint.port = 49832 ← remote
dst_endpoint.ip = 192.168.1.100 dst_endpoint.port = 445 ← localFor outbound hunting filter on dst_endpoint.*; for inbound hunting filter on src_endpoint.*.
Hunting
# Outbound TCP to uncommon ports
class_uid = 4001 and connection_info.direction_id = 2
and connection_info.protocol_name = "tcp"
and dst_endpoint.port notin 80,443,53,22,25,587,8080,8443,445,139,135,3389
# Script engines and utility binaries reaching the network
class_uid = 4001 and connection_info.direction_id = 2
and actor.process.name in "powershell.exe","wscript.exe","cscript.exe","mshta.exe",
"rundll32.exe","regsvr32.exe","certutil.exe","bitsadmin.exe"
# Large outbound transfers
class_uid = 4001 and connection_info.direction_id = 2 and traffic.bytes > 50000000
# Inbound connections to a workstation
class_uid = 4001 and connection_info.direction_id = 1
# Connections to a specific address
class_uid = 4001 and dst_endpoint.ip = "203.0.113.42"
# ICMP traffic
class_uid = 4001 and connection_info.protocol_num in 1,58
# Regular small outbound connections — candidate beaconing.
# Group by dst_endpoint.ip + actor.process.uid and look for a high count
# of small, evenly spaced events.
class_uid = 4001 and connection_info.direction_id = 2 and traffic.bytes < 2000
# Outbound connections to administrative ports
class_uid = 4001 and connection_info.direction_id = 2
and dst_endpoint.port in 445,135,139,3389,5985,5986
and actor.process.name notin "svchost.exe","System","lsass.exe"
# Many distinct destination ports from one process — port scanning
class_uid = 4001 and connection_info.direction_id = 2
# group by actor.process.uid, count distinct dst_endpoint.port6.17 DNS Activity (4003)
| class_uid / class_name | 4003 / "DNS Activity" |
| category | 1 / "System Activity" |
| Source | Network traffic inspection |
| Telemetry flag | TELEMETRY_DNS; 100,000 queries per process per day |
| What it reveals | Which process resolved which name, which server answered, the response code, and the resolved value. |
Activities
| activity_id | activity_name | type_uid |
|---|---|---|
| 401 | Query | 400301 |
| 402 | Response | 400302 |
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| query.hostname | string | The queried name. The primary hunting field. |
| query.opcode_id | integer | 0 Query, 1 Inverse Query, 2 Status, 3 Reserved, 4 Notify, 5 Update, 6 DSO Message, 99 Other |
| query.opcode | string | Caption of the above |
| query_time | epoch ms | When the query was issued |
| rcode_id | integer | Response code, on Response events. See 9.9. |
| rcode | string | "NoError", "NXDomain", "ServError", "Refused", and others |
| answers[].rdata | string | The resolved value — an address or a canonical name. Present on Response events. |
| src_endpoint.ip / .port | string / int | Local endpoint on an outbound query |
| dst_endpoint.ip / .port | string / int | The DNS server on an outbound query |
| connection_info.* | object | Direction, protocol and IP version — same shape as Network Activity |
| actor.process.* | object | The querying process |
| actor.user.* | object | User context |
| observables[0] | object | type = "Hostname"; name = the queried name |
| status_id / status_detail | int / string | 1; "DNS query completed" |
Hunting
# Long or high-entropy names, and high query volume per process.
# Both are the practical signals for name-based tunnelling.
class_uid = 4003 and activity_id = 401
# evaluate query.hostname length and entropy in your platform,
# and group by actor.process.uid to find volume outliers
# Bursts of failed resolutions from one process
class_uid = 4003 and activity_id = 402 and rcode_id = 3
# group by actor.process.uid, alert when the count exceeds ~50 in five minutes
# Resolution from a process that does not normally resolve names
class_uid = 4003 and activity_id = 401
and actor.process.name notin "svchost.exe","chrome.exe","firefox.exe","msedge.exe","dns.exe"
# Uncommon top-level domains
class_uid = 4003 and activity_id = 401
and (query.hostname endswith ".xyz" or query.hostname endswith ".top"
or query.hostname endswith ".tk")
# Dynamic-DNS and tunnelling service providers
class_uid = 4003 and activity_id = 401
and (query.hostname contains "ngrok" or query.hostname contains "duckdns"
or query.hostname contains "no-ip" or query.hostname contains "dynu"
or query.hostname contains "trycloudflare")
# Resolution to a specific address
class_uid = 4003 and activity_id = 402 and answers.rdata contains "203.0.113.42"
# DNS over TCP
class_uid = 4003 and connection_info.protocol_name = "tcp"
# Non-standard DNS opcodes
class_uid = 4003 and query.opcode_id notin 0
# Every name one process resolved
class_uid = 4003 and actor.process.uid = "<uid>"6.18 SMB Activity (4006)
| class_uid / class_name | 4006 / "SMB Activity" |
| category | 4 / "Network Activity" |
| Source | SMB protocol inspection |
| Telemetry flag | TELEMETRY_SMB. Loopback and same-host SMB is not collected. |
| What it reveals | SMB session establishment with the authenticating identity, the negotiated dialect, the authentication package, and the client's own GUID and workstation name. |
Activities
| activity_id | activity_name | type_uid | Meaning |
|---|---|---|---|
| 1800 | Unknown | — | |
| 1801 | Negotiate | 400601 | Protocol negotiation |
| 1802 | Session Setup | 400602 | Authentication — the identity-bearing exchange |
| 1803 | Logoff | 400603 | Session logoff |
| 1804 | Session Delete | 400604 | Session teardown |
| 1899 | Other | 400699 |
Endpoint assignment — src_endpoint is always the SMB client (initiator) and dst_endpoint the SMB server (responder), regardless of which side this endpoint is on. The agent determines this from the request/response flag and the packet direction.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| src_endpoint.ip / .port | string / int | The SMB client |
| src_endpoint.hostname | string | The client's claimed workstation name |
| dst_endpoint.ip / .port | string / int | The SMB server |
| dst_endpoint.hostname | string | Server host, parsed from the service principal name where present |
| dst_endpoint.svc_name | string | The service principal name, e.g. cifs/FILESERVER.corp.local |
| dst_endpoint.owner.name | string | The authenticating username |
| dst_endpoint.owner.domain | string | The authenticating domain |
| connection_info.* | object | Direction, protocol, IP version |
| unmapped.smb.command | string | SMB2_NEGOTIATE, SMB2_SESSION_SETUP, SMB2_LOGOFF, SMB2_OTHER, or the SMB1_* equivalents for legacy SMB1 |
| unmapped.smb.is_response | boolean | true = the server-to-client leg |
| unmapped.smb.is_smb1_protocol | boolean | true = legacy SMB1 — deprecated on current Windows |
| unmapped.smb.nt_status | integer | Result status. 0 = success. 0xC0000016 is the normal session-setup challenge leg, not a failure. |
| unmapped.smb.session_id | integer | SMB session identifier |
| unmapped.smb.message_id | integer | SMB message identifier |
| unmapped.smb.dialect_count | integer | Number of dialects the client offered during negotiation |
| unmapped.smb.highest_offered_dialect | string | Highest client-offered dialect as hex, e.g. "0x0311" = SMB 3.1.1 |
| unmapped.smb.selected_dialect | string | Server-selected dialect as hex |
| unmapped.smb.client_guid | string | Client GUID — tracks one client across sessions and addresses |
| unmapped.smb.server_guid | string | Server GUID |
| unmapped.smb.auth_protocol | string | "Negotiate", "NTLMSSP", "Kerberos", "SPNEGO", "Other", "Unspecified" |
| unmapped.smb.session_uuid | string | Correlation UUID for the remote session |
| unmapped.smb.is_session_create | boolean | true = this event establishes a new remote session |
| actor.process.* | object | The local process on the network path |
| observables[] | array | type = "IP Address" with name = "SMB Session Remote Endpoint" and value = remote IP; plus type = "User" with the username |
| status_id / status_code / status_detail | int / string / string | status_code is the result status as 0x%08X. 0xC0000016 maps to status 99 Other with "Authentication in progress (more processing required)". |
| message | string | e.g. "SMB2_SESSION_SETUP request" |
Hunting
# Who authenticated to this host over SMB, and as whom?
class_uid = 4006 and activity_id = 1802 and unmapped.smb.nt_status = 0
# → src_endpoint.ip = source host, dst_endpoint.owner.name = the account used
# New remote sessions established
class_uid = 4006 and unmapped.smb.is_session_create = true
# NTLM authentication where Kerberos would be expected
class_uid = 4006 and activity_id = 1802 and unmapped.smb.auth_protocol = "NTLMSSP"
# Legacy SMB1
class_uid = 4006 and unmapped.smb.is_smb1_protocol = true
# A downgraded dialect was selected
class_uid = 4006 and activity_id = 1801
and unmapped.smb.selected_dialect notin "0x0311","0x0302","0x0300"
# Failed SMB authentication, excluding the normal challenge leg
class_uid = 4006 and activity_id = 1802
and unmapped.smb.nt_status != 0 and unmapped.smb.nt_status != 3221225494
# Service principal names requested over SMB
class_uid = 4006 and dst_endpoint.svc_name != ""
# One client across sessions and addresses
class_uid = 4006 and unmapped.smb.client_guid = "<guid>"
# Full transcript of one remote session
class_uid = 4006 and unmapped.smb.session_uuid = "<uuid>"
# One host reaching many others over SMB — share discovery
class_uid = 4006 and connection_info.direction_id = 2
# group by src_endpoint.ip, count distinct dst_endpoint.ip6.19 Authentication (3002)
| class_uid / class_name | 3002 / "Authentication" |
| category | 3 / "Identity & Access Management" |
| Source | Security 4624 (logon success), 4625 (logon failure); Kerberos 4768 (ticket-granting ticket requested), 4769 (service ticket requested), 4770 (ticket renewed), 4771 (pre-authentication failed) |
| Telemetry flag | TELEMETRY_LOGON; no per-process limit |
| What it reveals | Every logon and Kerberos ticket operation, with the logon type, authentication package, source address, session identifier, decoded failure reason and — for Kerberos — the requested service and the ticket's encryption type and option flags. |
Activities
| activity_id | activity_name | type_uid | Source EID | Meaning |
|---|---|---|---|---|
| 501 | Logon | 300201 | 4624 / 4625 | Interactive or network logon |
| 503 | AuthTicket | 300203 | 4768 | A ticket-granting ticket was requested — the authentication itself |
| 504 | ServiceTicket | 300204 | 4769 | A service ticket was requested for a named service |
| 505 | TicketRenew | 300205 | 4770 | A service ticket was renewed |
| 506 | Preauth | 300206 | 4771 | Kerberos pre-authentication failed — the Kerberos equivalent of a bad password |
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| user.name | string | The target account — who was authenticated |
| user.domain | string | Target domain. Omitted on failed network logons, where the value is client-supplied. |
| user.uid | string | Target SID. Omitted on failed network logons, where Windows reports a null SID. |
| user.type_id / .type | int / string | 1 User, 2 Admin (elevated token), 3 System |
| actor.user.name / .domain | string | The subject — the account that initiated the logon |
| actor.process.* | object | The logon handler (lsass.exe, winlogon.exe), where a pid is available |
| logon_type_id | integer | Windows logon type. See 9.7. |
| logon_type | string | "Interactive", "Network", "Batch", "Service", "Unlock", "NetworkCleartext", "NewCredentials", "RemoteInteractive", "CachedInteractive", and others |
| auth_protocol_id | integer | 0 Unknown, 1 NTLM, 2 Kerberos, 3 Digest, 12 LDAP. The Negotiate package is reported as 2. |
| auth_protocol | string | The raw authentication package name as reported by the source |
| session.uid | string | Windows logon session identifier ("0x3e7" SYSTEM, "0x3e4" NETWORK SERVICE, "0x3e5" LOCAL SERVICE). Joins to actions performed in the same session. |
| is_remote | boolean | true for logon types 3, 8, 10 and 12 |
| src_endpoint.ip | string | Source address of the logon; "-" for local logons |
| src_endpoint.name | string | Claimed workstation name; omitted where the source reports "-" |
| dst_endpoint.svc_name | string | The requested service principal name on ticket events. krbtgt/... for a ticket-granting ticket; the target service for a service ticket. |
| unmapped.kerberos_ticket.ticket_encryption_type | string | Decoded encryption type: "AES256-CTS-HMAC-SHA1-96", "AES128-CTS-HMAC-SHA1-96", "RC4-HMAC", "RC4-HMAC-EXP", "DES-CBC-CRC", "DES-CBC-MD5", "None", "Unknown"; the raw value where unrecognised |
| unmapped.kerberos_ticket.ticket_options | string | Decoded option flags, comma-joined: "Forwardable", "Forwarded", "Proxiable", "Proxy", "Allow-Postdate", "Postdated", "Renewable", "Initial", "Pre-Authent", "Opt-Hardware-Auth", "Ok-As-Delegate", "Canonicalize", "Disable-Transited-Check", "Renewable-OK", "Enc-Tkt-In-Skey" |
| unmapped.kerberos_ticket.pre_auth_type | string | Decoded pre-authentication type: "None", "PA-ENC-TIMESTAMP", "PA-ETYPE-INFO", "PA-ETYPE-INFO2", "PA-PK-AS-REQ (PKINIT/Smartcard)", "PA-PK-AS-REP (PKINIT/Smartcard)", "PA-ENCRYPTED-CHALLENGE" |
| unmapped.is_local | boolean | true = a local account |
| status_id / status | int / string | 1 Success / 2 Failure |
| status_code | string | "0" / "1" for logons; the raw Kerberos result code for ticket events, e.g. "0x18" |
| status_detail | string | Decoded reason. Logon failures: "Unknown username or bad password", "Account is currently disabled", "The specified account's password has expired", "Account logon time restriction violation", "User not allowed to logon at this computer", "An error occurred during logon". Kerberos: "Pre-authentication failed (bad password)", "Client credentials revoked, disabled, expired or locked out", "Clock skew too great", "Ticket has expired", "Client not found in Kerberos database (bad username)", "Policy restriction (workstation/time)", and others. |
| observables[0] | object | type = "User"; name = target username |
Network logon note: inbound network connections have no existing session context on the receiving side, so the subject fields arrive empty or as a null SID. On failed network logons the agent omits user.domain and user.uid rather than reporting those placeholder values.
Hunting
# Repeated authentication failures against one account
class_uid = 3002 and status_id = 2
# group by user.name + src_endpoint.ip, alert on high counts in a short window
# One source failing against many accounts
class_uid = 3002 and status_id = 2 and logon_type_id = 3
# group by src_endpoint.ip, count distinct user.name
# A success following a run of failures from the same source
class_uid = 3002 and status_id = 1 and src_endpoint.ip = "<ip from the failures>"
# Remote desktop sessions
class_uid = 3002 and activity_id = 501 and logon_type_id = 10
# NTLM on a network logon where Kerberos is expected
class_uid = 3002 and activity_id = 501
and logon_type_id = 3 and auth_protocol_id = 1
# Service tickets issued with weak encryption
class_uid = 3002 and activity_id = 504
and unmapped.kerberos_ticket.ticket_encryption_type in
"RC4-HMAC","RC4-HMAC-EXP","DES-CBC-CRC","DES-CBC-MD5"
# One account requesting tickets for many distinct services
class_uid = 3002 and activity_id = 504
# group by user.name, count distinct dst_endpoint.svc_name
# Ticket-granting tickets issued without pre-authentication
class_uid = 3002 and activity_id = 503
and unmapped.kerberos_ticket.pre_auth_type = "None"
# Kerberos password-guessing
class_uid = 3002 and activity_id = 506
and status_detail contains "Pre-authentication failed"
# Delegation-capable tickets
class_uid = 3002 and activity_id in 503,504
and unmapped.kerberos_ticket.ticket_options contains "Forwardable"
and unmapped.kerberos_ticket.ticket_options contains "Ok-As-Delegate"
# Clock-skew anomalies on ticket operations
class_uid = 3002 and status_detail contains "Clock skew"
# Machine accounts logging on interactively
class_uid = 3002 and activity_id = 501
and logon_type_id in 2,10 and user.name endswith "$"
# Logons using explicitly supplied alternate credentials
class_uid = 3002 and logon_type_id = 9
# What did that session go on to do?
session.uid = "<the logon's session.uid>"6.20 Account Change (3001)
| class_uid / class_name | 3001 / "Account Change" |
| category | 3 / "Identity & Access Management" |
| Source | Security 4720 (user created), 4722 (enabled), 4723 (password change attempt), 4724 (password reset attempt), 4725 (disabled), 4726 (deleted), 4740 (locked out), 4767 (unlocked); computer accounts 4741 (created), 4743 (deleted) |
| Telemetry flag | TELEMETRY_ACCOUNT_AND_OBJECT |
| What it reveals | Account lifecycle changes, who made them, and — on creation — the account's primary group, logon script, SID history and dial-in parameters. |
Activities
| activity_id | activity_name | type_uid | Source EID |
|---|---|---|---|
| 1000 | Unknown | 300100 | — |
| 1001 | Create | 300101 | 4720 |
| 1002 | Enable | 300102 | 4722 |
| 1003 | Disable | 300103 | 4725 |
| 1004 | Delete | 300104 | 4726 |
| 1005 | Lock | 300105 | 4740 |
| 1006 | Reset Password | 300106 | 4724 |
| 1007 | Unlock | 300107 | 4767 |
| 1008 | Change Password | 300108 | 4723 |
| 1099 | Other | 300199 | 4741 / 4743 (computer accounts) |
Computer-account events use activity_id = 1099 with activity_name = "Computer Object Created" or "Computer Object Deleted", and type_name = "Account Change: Computer Object Created" / "... Deleted". Filter on activity_name to separate them.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| user.name | string | The target account. For computer accounts, the SAM name. |
| user.domain | string | Target domain |
| user.uid | string | Target SID |
| actor.user.name / .domain / .uid | string | The subject who made the change |
| session.uid | string | Subject logon session identifier |
| actor.process.* | object | Generating process, typically lsass.exe |
| unmapped.is_local | boolean | true = a local account |
| On account creation | ||
| unmapped.primary_group_id | string | Relative identifier of the primary group (e.g. 513 = Domain Users) |
| unmapped.script_path | string | Logon script assigned to the account |
| unmapped.sid_history | string[] | Previous SIDs associated with the account. A populated SID history on a newly created account means the account inherits another account's access. |
| unmapped.user_parameters | string | Dial-in and remote-access parameters |
| On computer-account events | ||
| unmapped.sam_account_name | string | Computer account SAM name, ending in $ |
| unmapped.dns_host_name | string | Computer account fully qualified name |
| observables[0] | object | type = "User", or "ComputerAccount" for computer-account events; name = target account |
| status_id / status_detail | int / string | 2 Failure with "Account operation failed" where the source audit result was a failure; otherwise 1 with "Account operation succeeded" |
| message | string | "A user account was created", "An attempt was made to reset an account password", "A computer account was created", and equivalents |
Hunting
# Accounts created
class_uid = 3001 and activity_id = 1001
# → actor.user.name is the creator, user.name is the new account
# Local accounts created
class_uid = 3001 and activity_id = 1001 and unmapped.is_local = true
# Accounts created by a script engine or command-line tool
class_uid = 3001 and activity_id = 1001
and actor.process.name in "powershell.exe","cmd.exe","wscript.exe","cscript.exe","net.exe","net1.exe"
# A new account carrying another account's SID history
class_uid = 3001 and activity_id = 1001 and unmapped.sid_history != ""
# A logon script assigned at creation
class_uid = 3001 and activity_id = 1001 and unmapped.script_path != ""
# Password reset performed by somebody other than the account owner
class_uid = 3001 and activity_id = 1006 and actor.user.name != user.name
# Accounts disabled or deleted
class_uid = 3001 and activity_id in 1003,1004
# Dormant accounts re-enabled
class_uid = 3001 and activity_id = 1002
# Lockout bursts
class_uid = 3001 and activity_id = 1005
# Computer accounts created
class_uid = 3001 and activity_id = 1099 and activity_name = "Computer Object Created"
# Attempted but denied account operations
class_uid = 3001 and status_id = 2
# What else happened in the same session?
session.uid = "<session identifier>"6.21 User Access Management (3005)
| class_uid / class_name | 3005 / "User Access Management" |
| category | 3 / "Identity & Access Management" |
| Source | Security 4704 (user right assigned), 4717 (system security access granted) |
| Telemetry flag | TELEMETRY_ACCOUNT_AND_OBJECT |
| What it reveals | Which privileges and logon rights were granted to which account, by whom. |
Activities
| activity_id | activity_name | type_uid |
|---|---|---|
| 1400 | Unknown | 300500 |
| 1401 | Assign Privileges | 300501 |
| 1499 | Other | 300599 |
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| privileges | string[] | The rights assigned, one per element. Examples: SeDebugPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeTakeOwnershipPrivilege, SeLoadDriverPrivilege, SeImpersonatePrivilege, SeServiceLogonRight, SeRemoteInteractiveLogonRight |
| user.name / .domain / .uid | string | The target account receiving the privilege |
| actor.user.name / .domain / .uid | string | The subject granting it |
| session.uid | string | Subject logon session identifier |
| observables[0] | object | type = "User"; name = target username |
| status_id / status_detail | int / string | Success or failure, from the source audit result |
| message | string | "A user right was assigned" or "System security access was granted to an account" |
Hunting
# All privilege assignment
class_uid = 3005 and activity_id = 1401
# Privileges that permit reading another process's memory
class_uid = 3005 and privileges contains "SeDebugPrivilege"
# Privileges that permit driver loading, ownership changes or full impersonation
class_uid = 3005
and (privileges contains "SeTcbPrivilege"
or privileges contains "SeLoadDriverPrivilege"
or privileges contains "SeTakeOwnershipPrivilege"
or privileges contains "SeImpersonatePrivilege")
# Backup and restore rights, which bypass file permissions entirely
class_uid = 3005
and (privileges contains "SeBackupPrivilege" or privileges contains "SeRestorePrivilege")
# The right to run as a service
class_uid = 3005 and privileges contains "SeServiceLogonRight"
# The right to log on remotely
class_uid = 3005 and privileges contains "SeRemoteInteractiveLogonRight"
# A privilege granted to an account created in the same window
class_uid = 3005 and user.name = "<account from an Account Change event>"6.22 Group Management (3006)
| class_uid / class_name | 3006 / "Group Management" |
| category | 3 / "Identity & Access Management" |
| Source | Security 4728 (member added to a global group), 4732 (local group), 4756 (universal group) |
| Telemetry flag | TELEMETRY_ACCOUNT_AND_OBJECT |
| What it reveals | Which account was added to which group, by whom, and what kind of group it was. |
Activities
| activity_id | activity_name | type_uid |
|---|---|---|
| 1100 | Unknown | 300600 |
| 1103 | Add Member | 300603 |
| 1199 | Other | 300699 |
Member additions are collected.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| group.name | string | The target group, e.g. "Administrators", "Domain Admins" |
| group.domain | string | The group's domain |
| group.type | string | "Security-enabled Global Group" (4728), "Security-enabled Local Group" (4732), "Security-enabled Universal Group" (4756), or "Security-enabled Group" |
| user.uid | string | The member's SID — always present |
| user.name | string | Member username, where resolvable |
| user.domain | string | Member domain, where resolvable |
| actor.user.name / .domain / .uid | string | The subject who added the member |
| session.uid | string | Subject logon session identifier |
| actor.process.* | object | Generating process |
| unmapped.is_local | boolean | true = a local group |
| observables[0] | object | type = "Group"; name = target group name |
| status_id / status_detail | int / string | 1; "Member added to group successfully" |
| message | string | "A member was added to a security-enabled local group", and equivalents |
Hunting
# All group membership additions
class_uid = 3006 and activity_id = 1103
# Additions to privileged groups
class_uid = 3006 and activity_id = 1103
and group.name in "Administrators","Domain Admins","Enterprise Admins",
"Schema Admins","Backup Operators","Account Operators","Server Operators",
"Print Operators","Remote Desktop Users","DnsAdmins","Group Policy Creator Owners"
# A local administrator added on a workstation
class_uid = 3006 and activity_id = 1103
and group.name = "Administrators" and unmapped.is_local = true
# Group changes made from a command line rather than a management console
class_uid = 3006 and activity_id = 1103
and actor.process.name in "powershell.exe","cmd.exe","net.exe","net1.exe","wscript.exe"
# The full sequence — account created, added to a group, granted privileges.
# Pivot on the logon session or on the account name.
session.uid = "<session identifier>"6.23 Detection Finding (2004)
| class_uid / class_name | 2004 / "Detection Finding" |
| category | 2 / "Findings" |
| Source | The behaviour rule engine — one finding per fired rule |
| Telemetry flag | none; emitted whenever collection is on and a rule fires, independent of the origin class's telemetry flag |
| What it reveals | Which rule fired, what it detects, the ATT&CK mapping the rule carries, and the complete context of the activity that triggered it. |
Activities
| activity_id | activity_name | type_uid | type_name |
|---|---|---|---|
| 1901 | Create | 200401 | Detection Finding: Create |
How a finding is assembled — this shapes how you query it:
- The origin event's OCSF form is built.
- That entire event is copied, so every context field travels with the finding: actor, process, file, file_result, reg_key, reg_value, src_endpoint, dst_endpoint, connection_info, traffic, url, query, answers, module, job, win_service, script, unmapped.*, device, metadata.
- The origin's class is captured into associated_class_uid / associated_class_name.
- The finding taxonomy is applied: class_uid = 2004, category_uid = 2, type_uid = 200401, activity_id = 1901.
- finding_info is populated from the rule definition.
- The same dpid as the origin event is applied.
A finding is self-contained: you do not need the origin event to understand what happened. You do need associated_class_uid to know which context fields to read.
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| finding_info.uid | string | The rule's unique identifier. Pivot on this to find every firing of one rule. |
| finding_info.title | string | Readable rule name, e.g. "PowerShell Encoded Command Detected" |
| finding_info.created_time | epoch ms | When the finding was created |
| finding_info.types | string[] | ["behaviour", "detection"] |
| finding_info.src_url | string | Reference URL for the technique the rule describes, where the rule supplies one |
| finding_info.analytic.uid | string | Same value as finding_info.uid |
| finding_info.analytic.name | string | Same value as finding_info.title |
| finding_info.analytic.type_id | integer | 1 (Rule) |
| finding_info.analytic.type | string | "Rule" |
| finding_info.analytic.category | string | "behaviour" |
| finding_info.analytic.version | string | Rule version — use this to track detection-content changes over time |
| finding_info.analytic.desc | string | Rule description — what the rule detects and why |
| finding_info.attacks[].tactic.uid / .name | string | The ATT&CK tactic the rule is mapped to, e.g. "TA0002" / "Execution" |
| finding_info.attacks[].technique.uid / .name / .url | string | The technique, e.g. "T1059" / "Command and Scripting Interpreter" |
| finding_info.attacks[].sub_technique.uid / .name | string | The sub-technique, e.g. "T1059.001" / "PowerShell" |
| finding_info.attacks[].version | string | ATT&CK framework version the mapping targets |
| associated_class_uid | integer | The origin event's class. Tells you which context fields are populated. |
| associated_class_name | string | e.g. "Module Activity", "API Telemetry Activity" |
| severity_id / severity | int / string | 2 / "Low" |
| status_id / status | int / string | 1 / "Success" |
| message | string | The engine's message where it supplied one, otherwise the origin event's message |
| dpid | integer | Same value as the origin event — the chain pivot |
| (all origin context) | — | Whatever the origin class populated |
finding_info is populated from the rule definition held on the endpoint. Where the definition is not present locally, the finding is still emitted — carrying severity_id = 2 and the origin context — with finding_info empty.
Findings that ride on the origin event: two rules — identifiers 90001 and 2156622 — attach finding_info to the origin event and keep that event's own class, rather than producing a separate finding. A complete finding sweep is therefore:
class_uid = 2004 or finding_info.uid != "" or type_name = "yara_detection_event"Hunting
# The triage entry query
class_uid = 2004
and device.hostname = "WORKSTATION-01"
and time >= <start ms> and time <= <end ms + 60000>
# Read: finding_info.title, finding_info.analytic.desc, associated_class_name, dpid
# Findings for a specific rule, across the estate
finding_info.uid = "<rule uid>"
# Findings by rule name
class_uid = 2004 and finding_info.title contains "Encoded"
# Which findings came from WMI activity?
class_uid = 2004 and associated_class_uid = 201005
# Findings whose evidence is an API call
class_uid = 2004 and associated_class_uid = 201008
# Findings mapped to a given technique or tactic
class_uid = 2004 and finding_info.attacks.technique.uid = "T1055"
class_uid = 2004 and finding_info.attacks.tactic.name = "Persistence"
# What is firing most, and from which activity classes?
class_uid = 2004
# group by finding_info.title, then by associated_class_name
# Findings without a rule definition attached
class_uid = 2004 and finding_info.uid = ""
# Findings attached to their origin event
class_uid != 2004 and finding_info.uid != ""
# From a finding to the whole chain (keep the host filter — dpid is per-endpoint)
device.hostname = "WORKSTATION-01" and dpid = <the finding's dpid>6.24 YARA Detection
| Identify by | type_name = "yara_detection_event" |
| class_name | "Detection Finding" |
| category_name | "Software & Configuration Checks" |
| Source | YARA rule match on a scanned file or process image |
| Telemetry flag | none |
| What it reveals | Which rule matched, the threat and category the rule names, the rule's authorship and scope metadata, the matched file and hash, and the byte offset of the match. |
How to filter this event. YARA detections are identified by their type_name; the numeric classification fields (class_uid, type_uid, activity_id) are not used for this event, and severity is carried in the severity string and in yara_detection.severity. Filter on type_name or on a yara_detection.* field:
`
type_name = "yara_detection_event"
`
Fields
| Field | Type | Description / hunting note |
|---|---|---|
| type_name | string | "yara_detection_event" — the filter to use |
| class_name | string | "Detection Finding" |
| activity_name | string | "Create" |
| severity | string | "High", or the rule's declared severity where it supplies one |
| yara_detection.rule_name | string | The matched rule's identifier |
| yara_detection.rule_id | string | Rule identifier from the rule metadata |
| yara_detection.category_name | string | Rule category metadata |
| yara_detection.threat_name | string | Threat or family name the rule declares |
| yara_detection.severity | string | Rule severity metadata |
| yara_detection.author | string | Rule author |
| yara_detection.creation_date | string | Rule creation date |
| yara_detection.last_modified | string | Rule last-modified date |
| yara_detection.arch_context | string | Architecture context the rule targets |
| yara_detection.scan_context | string | Scan context the rule applies to |
| yara_detection.os | string | Operating system the rule targets |
| yara_detection.pattern_offset | integer | Byte offset of the match within the scanned file |
| yara_detection.detection_mode | integer | The scan mode the detection ran under |
| file.path | string | The scanned file |
| file.hashes[] | array | algorithm_id = 3, algorithm = "SHA256", value = digest |
| actor.process.pid | integer | Associated process pid |
| actor.process.uid | string | Associated process UUID |
| message | string | The matched rule name |
Each matched rule produces its own event, so one file matching three rules yields three events. Every rule metadata attribute is a separately indexed field rather than a single concatenated description, so any of them can be filtered directly.
Hunting
# All YARA detections in the window
type_name = "yara_detection_event"
# By threat or family name
type_name = "yara_detection_event" and yara_detection.threat_name contains "Agent"
# By a specific rule
yara_detection.rule_name = "<rule name>"
# High-severity rule matches
type_name = "yara_detection_event" and yara_detection.severity in "critical","high"
# By rule category
type_name = "yara_detection_event" and yara_detection.category_name contains "ransomware"
# Every rule that matched one file
type_name = "yara_detection_event" and file.path = "C:\Temp\sample.exe"
# The same file across the estate, by hash
type_name = "yara_detection_event" and file.hashes.value = "<sha256>"
# Pivot to what the associated process did
actor.process.uid = "<uid from the YARA event>"6.25 Browser classes: HTTP (4002), Web Resources (6001), App Lifecycle (6002), Security Finding (2001)
| Source | The browser extension / browser security provider. The payload is converted to JSON and mapped into the OCSF event by field name. |
| Telemetry flag | TELEMETRY_BROWSER |
| What it reveals | Browsing, downloads and uploads; browser extension lifecycle with permissions; and browser-side threat findings including clipboard content planted by a page. |
Envelope differences from other classes:
- category_uid, category_name, severity_id, severity, status_id, status, time, timezone_offset, type_uid and type_name come from the browser payload rather than from the agent's defaults.
- No observables array is added.
- metadata is supplied by the browser payload, so metadata.product may describe the browser or the extension.
- actor.process is the browser process, enriched from the browser-reported pid and UUID.
Activity offsets — the browser reports a small activity identifier and the agent applies a class-specific offset:
| class_uid | Class | Offset | Reported activity_id |
|---|---|---|---|
| 4002 | HTTP Activity | +600 | 601 Open, 602 Close, 603 Connect |
| 6001 | Web Resources Activity | +700 | 701 Access, 702 Create, 703 Update, 704 Delete, 799 Other |
| 6002 | Application Lifecycle | +800 | 801 Install, 802 Remove, 803 Start, 804 Stop, 899 Other |
| 2001 | Security Finding | +2200 | 2201 Create, 2299 Other |
type_uid and type_name pass through from the browser payload, e.g. 400201 with "HTTP Activity: Open".
6.25.1 HTTP Activity (4002)
| Field | Type | Description |
|---|---|---|
| http_request.url.url_string | string | The full requested URL |
| http_request.url.hostname / .path / .scheme / .port / .query_string / .domain / .subdomain | string / int | Parsed URL components |
| http_response.status_code | integer | HTTP response status |
| url.* | object | URL details for the traffic |
| user_agent | string | Full user-agent string |
| action | string | "WebsiteAccessed", "Download", "Upload", "WebFilterBlocked", "UploadBlocked", "DownloadBlocked" |
| http_activity_fields.domain | string | Domain |
| http_activity_fields.file_name | string | File name on download and upload events |
| http_activity_fields.file_size | integer | Size in bytes |
| http_activity_fields.file_type | string | Content type |
| http_activity_fields.category | string | Blocked category, on web-filter events |
| http_activity_fields.referrer | string | Referrer URL |
| src_endpoint.* / dst_endpoint.* | object | Endpoints as reported by the browser |
| unmapped.action, unmapped.domain, unmapped.file_name, unmapped.file_size, unmapped.file_type, unmapped.category, unmapped.referrer, unmapped.process_id, unmapped.process_time | mixed | Flat duplicates of the above |
# Executables downloaded through the browser
class_uid = 4002 and action = "Download"
and (http_activity_fields.file_name endswith ".exe"
or http_activity_fields.file_name endswith ".dll"
or http_activity_fields.file_name endswith ".ps1"
or http_activity_fields.file_name endswith ".hta"
or http_activity_fields.file_name endswith ".scr")
# Large uploads
class_uid = 4002 and action = "Upload" and http_activity_fields.file_size > 10000000
# Blocked by the web filter — the attempt still happened
class_uid = 4002 and action in "WebFilterBlocked","DownloadBlocked","UploadBlocked"
# Downloads from a bare address rather than a domain name
class_uid = 4002 and action = "Download"
and http_request.url.domain = ""6.25.2 Web Resources Activity (6001)
| Field | Type | Description |
|---|---|---|
| web_resources[].url.* | object | Resource URL details |
| web_resources[].name | string | Resource name; the file name for downloads and uploads |
| web_resources[].type | string | Content type |
| web_resources[].size | integer | Size in bytes |
| web_resources[].category | string | Categorisation |
| web_resources[].referrer | string | Referrer URL |
| web_resources_result[] | array | Resulting resources after the activity, same shape |
6.25.3 Application Lifecycle (6002) — browser extensions
| Field | Type | Description / hunting note |
|---|---|---|
| app.name | string | Extension name |
| app.uid | string | Extension identifier |
| app.version | string | Extension version |
| app.vendor_name | string | Vendor |
| app.url_string | string | Web-store listing URL |
| app.type | string | e.g. "Browser Extension" |
| ext_lifecycle_fields.ext_event | string | "Install", "Uninstall", "Enable", "Disable" |
| ext_lifecycle_fields.ext_id | string | Extension identifier |
| ext_lifecycle_fields.ext_state | string | "Enabled" / "Disabled" |
| ext_lifecycle_fields.ext_type | string | Extension type |
| ext_lifecycle_fields.ext_install_type | string | Install type — distinguishes a store install from a development or sideloaded install |
| ext_lifecycle_fields.ext_may_disable | boolean | Whether the extension can be disabled; force-installed extensions cannot |
| ext_lifecycle_fields.ext_permissions | string[] | Requested API permissions |
| ext_lifecycle_fields.ext_host_perms | string[] | Host permissions. <all_urls> grants access to every page. |
| ext_lifecycle_fields.ext_disabled_reason | string | Reason the extension is disabled |
| ext_lifecycle_fields.ext_update_url | string | Update URL — a non-store URL indicates a sideloaded extension |
| ext_lifecycle_fields.ext_offline | boolean | Whether the extension functions offline |
| unmapped.ext_* | mixed | Flat duplicates of the above |
# Extensions installed
class_uid = 6002 and ext_lifecycle_fields.ext_event = "Install"
# Extensions able to read every page
class_uid = 6002 and ext_lifecycle_fields.ext_host_perms contains "<all_urls>"
# Extensions updating from outside an official store
class_uid = 6002 and ext_lifecycle_fields.ext_event = "Install"
and ext_lifecycle_fields.ext_update_url notcontains "google.com"
and ext_lifecycle_fields.ext_update_url notcontains "microsoft.com"
# High-impact permission requests
class_uid = 6002
and (ext_lifecycle_fields.ext_permissions contains "webRequest"
or ext_lifecycle_fields.ext_permissions contains "cookies"
or ext_lifecycle_fields.ext_permissions contains "clipboardRead"
or ext_lifecycle_fields.ext_permissions contains "nativeMessaging"
or ext_lifecycle_fields.ext_permissions contains "debugger")6.25.4 Security Finding (2001) — browser-threat findings
Two related events are produced: the detection itself, and — where the page placed a command on the clipboard — a follow-up carrying that content. Both share unmapped.detection_time, which correlates them.
| Field | Type | Description / hunting note |
|---|---|---|
| unmapped.threat_type | string | The detector family that fired |
| unmapped.score_clickfix / score_pastejacking / score_clickjacking | integer | Weighted score per family; 0 where that family did not fire |
| unmapped.threat_count | integer | Number of detector signals that fired |
| unmapped.detection_time | epoch ms | Shared by the detection and its follow-up — the correlation key |
| unmapped.copied_command | string | The content the page wrote to the clipboard, verbatim and not decoded. Present on the follow-up event. |
| unmapped.page_url | string | The page the threat was detected on |
| unmapped.page_title | string | The page title |
| unmapped.domain | string | The domain; empty for local files |
| unmapped.analytic_steps[].name | string | The detector signal that fired, e.g. dom_overlay_with_action, fake_captcha_no_provider, clipboard_command_content, clipboard_early_write |
| unmapped.analytic_steps[].description | string | What the signal observed |
| unmapped.analytic_steps[].data | string | Signal evidence, e.g. overlayCount=6, time=1596ms |
| unmapped.analytic_steps[].version | string | Detector tier, e.g. T1:Behavioral, T2:Structural |
| browser_threat.* | object | Structured equivalent of the flat unmapped fields |
| finding_info.* | object | Standard finding info; finding_info.analytic.data_sources lists the sources evaluated ("Browser DOM", "Clipboard API", "Content Analysis") |
| message | string | Readable summary with the threat family and score |
# All browser-threat findings
class_uid = 2001
# Findings that captured clipboard content
class_uid = 2001 and unmapped.copied_command != ""
# Clipboard content that would run a command interpreter
class_uid = 2001
and (unmapped.copied_command contains "powershell"
or unmapped.copied_command contains "-enc"
or unmapped.copied_command contains "mshta"
or unmapped.copied_command contains "curl")
# Did the content actually run? Take a distinctive fragment of
# copied_command and look for it in execution telemetry:
class_uid = 1007 and activity_id = 1 and process.cmd_line contains "<fragment>"
class_uid = 1009 and script.content contains "<fragment>"
# High-scoring detections only
class_uid = 2001 and unmapped.score_clickfix > 150
# By detector family
class_uid = 2001 and unmapped.threat_type = "pastejacking"
# Correlate a detection with its clipboard follow-up
class_uid = 2001 and unmapped.detection_time = <value>7. Hunting Index — What You Want to Find → Where to Look
Use this when you know the behaviour you are looking for and need the class and field that record it.
Where a rule already covers the behaviour, class_uid = 2004 gives you the verdict and the evidence in one row. This index is what you use when no rule fired, when you are hunting proactively, or when you want the raw activity behind a finding.
7.1 Execution — what ran and how
| Looking for | Class(es) | Fields |
|---|---|---|
| Any program execution | 1007 | process.name, process.cmd_line, process.file.path |
| Command-line arguments | 1007 | process.cmd_line, actor.process.cmd_line |
| Script content, deobfuscated | 1009 | script.content, script.type_id, script.file.path |
| Interactive shell commands and their output | 201007 | unmapped.command_activity.input_command, .output_command |
| Commands run by a scheduled task | 1006 | job.cmd_line, job.file.path |
| Commands run by a service | 201004 | win_service.cmd_line, win_service.service_file.path |
| Commands run by a WMI subscription | 201005 | unmapped.wmi_activity.consumer_command_line, .consumer_script_text |
| Native API used to create processes | 201008 | unmapped.api_telemetry.api_name = NtCreateUserProcess, NtCreateProcessEx |
| Remotely initiated execution | 1007, 201004 | is_remote = true, src_endpoint.ip |
| Built-in binaries used to proxy execution | 1007 | process.name in certutil.exe, regsvr32.exe, mshta.exe, rundll32.exe, wmic.exe, bitsadmin.exe, msiexec.exe |
| Office documents launching child processes | 1007 | actor.process.name in winword.exe, excel.exe, powerpnt.exe, outlook.exe |
| Office macro execution | 1009 | script.type_id = 7 |
7.2 Persistence — what will run again later
| Looking for | Class(es) | Fields |
|---|---|---|
| Scheduled tasks | 1006 | activity_id in 1,2; job.cmd_line; unmapped.scheduled_job.scheduled_job_visibility, .scheduled_job_privilege, .scheduled_job_triggers, .scheduled_job_location |
| Services | 201004 | activity_id in 1,2; win_service.service_file.path; unmapped.win_service_lifecycle.persistence_flags |
| WMI event subscriptions | 201005 | activity_id in 1603,1605,1609; unmapped.wmi_activity.filter_query, .consumer_command_line |
| Registry autostart values | 201002 | reg_value.path contains currentversion\run; reg_value.reg_string_data |
| Registry autostart keys | 201001 | activity_id = 101; reg_key.path |
| Debugger / execution-option hijacks | 201002 | reg_value.path contains image file execution options; reg_value.name = "Debugger" |
| Service binary or worker DLL redirection | 201002, 201004 | reg_value.name in "ImagePath","ServiceDll"; activity_id = 2 |
| Startup-folder files | 1001 | file.path contains \Start Menu\Programs\Startup |
| Driver services | 201004 | win_service.service_type_id in 1,2 |
| Modules loaded from non-system paths | 1005 | module.file.path |
| New accounts | 3001 | activity_id = 1001 |
| Logon scripts assigned to accounts | 3001 | unmapped.script_path |
| Browser extensions | 6002 | ext_lifecycle_fields.ext_event = "Install" |
7.3 Privilege and access changes
| Looking for | Class(es) | Fields |
|---|---|---|
| Privileges and logon rights granted | 3005 | privileges, user.name, actor.user.name |
| Privileged group membership added | 3006 | group.name, user.name, actor.user.name |
| Account enabled, disabled or deleted | 3001 | activity_id in 1002,1003,1004 |
| Password reset by another account | 3001 | activity_id = 1006 with actor.user.name != user.name |
| Accounts inheriting another account's SID history | 3001 | unmapped.sid_history |
| Elevated-token processes | 1007 | process.user.type_id = 2 |
| Token duplication and impersonation | 201008 | api_name in NtDuplicateToken, ImpersonateLoggedOnUser, SetThreadToken |
| Elevation-prompt settings changed | 201002 | reg_value.name in "EnableLUA","ConsentPromptBehaviorAdmin" |
| Registry or object permission changes | 201001, 201008 | activity_id = 106; api_name = NtSetSecurityObject |
7.4 Evasion and interference with monitoring
| Looking for | Class(es) | Fields |
|---|---|---|
| Detected evasion behaviour | 201003 | message contains ETW_PATCHING, EDR_ETW_SESSION_STOPING, APIHook_Patching, DIRECT_SYSCALL, INDICATOR_REMOVAL_FROM_TOOLS |
| Event logs cleared | 201003, 201007 | message contains LOG_CLEARED; input_command contains wevtutil |
| Security services stopped | 201004 | activity_id = 4 with win_service.name matching security products |
| Security configuration disabled via registry | 201002 | reg_value.path contains windows defender |
| Scan-interface tampering in a script | 1009 | script.content contains amsiInitFailed, AmsiUtils, AmsiScanBuffer |
| Falsified parent process | 1007 | actor.process.pid != process.parent_process.pid |
| System binary names in the wrong location | 1007 | process.name versus process.file.path |
| Renamed binaries | 201010 | unmapped.on_write_scan_result.original_file_name != file.name |
| Hidden files | 1001 | file.attributes (bit 0x2) |
| Hidden windows | 201008 | api_name contains NtUserShowWindow, NtUserSetWindowPos |
| Obfuscated commands and scripts | 1007, 1009, 201003 | process.cmd_line; script.content; message contains OBFUSCATED_COMMAND |
| Decoding and decompression in-process | 201008 | api_name contains Decompress, CryptStringToBinary, FDICopy, LZ |
| Dynamic API resolution | 201008, 201003 | api_name = GetProcAddress; message contains DYNAMIC_API_RESOLUTION |
| Environment and timing probes | 201008 | the environment-check API list in 6.13 |
| Debugger detection | 201008 | api_name in NtQueryInformationProcess, DebugActiveProcess, NtSetInformationThread |
7.5 Cross-process memory and image manipulation
| Looking for | Class(es) | Fields |
|---|---|---|
| Detected injection behaviour | 201003 | message contains INJECTION, HOLLOWING, SHELLCODE_INJECTED, THREAD_EXECUTION_HIJACK, MODULE_STOMPING, REFLECTIVE |
| The injection API sequence | 201008 | api_name in NtAllocateVirtualMemoryRemote, NtWriteVirtualMemoryRemote, NtProtectVirtualMemoryRemote, NtCreateRemoteThread |
| Writes straight into executable memory | 201008 | api_name = NtWriteVirtualMemoryRemoteExecutable |
| Section unmapping in another process | 201008, 201003 | api_name = NtUnmapViewOfSectionRemote; message contains REMOTE_SECTION_UNMAP |
| Processes created suspended | 201008 | api_name contains Suspended |
| Suspend and resume of another process | 201008 | api_name in NtSuspendProcess, NtResumeProcess |
| Modules loaded into a target after injection | 1005 | actor.process.uid = the target |
| In-memory assembly loading from a script | 1009 | script.content contains Reflection.Assembly, VirtualAlloc |
7.6 Credential and secret access
| Looking for | Class(es) | Fields |
|---|---|---|
| Access to the credential-store process | 201003 | message contains LSASS_OPEN_HANDLE, LSASS_REMOTE_THREAD |
| Credential vault and manager reads | 201008 | api_name contains Cred or Vault |
| Protected-data decryption | 201008 | api_name = CryptUnprotectData |
| Registry hives saved to file | 201001 | activity_id = 102 with status_detail = "Save Key" |
| Raw volume reads that bypass file permissions | 201009 | activity_id = 2; unmapped.volume.raw_volume_type |
| Shadow-copy access | 201009 | unmapped.volume.raw_volume_type = "VssShadow" |
| Directory replication requests | 201003 | message contains ReplicatingDirectoryChanges |
| Credential tooling in a script | 1009 | script.content contains sekurlsa, MiniDumpWriteDump, Invoke-Mimikatz |
| Credential commands typed into a shell | 201007 | input_command contains lsass, reg save, ntdsutil, vssadmin |
| Memory-dump files written | 1001 | file.ext in "dmp","dit","hive"; file.name contains lsass |
| Repeated authentication failures | 3002 | status_id = 2 grouped by user.name / src_endpoint.ip |
| Account lockout bursts | 3001 | activity_id = 1005 |
| Weak Kerberos ticket encryption | 3002 | unmapped.kerberos_ticket.ticket_encryption_type |
| Tickets issued without pre-authentication | 3002 | unmapped.kerberos_ticket.pre_auth_type = "None" |
| Many service tickets for distinct services | 3002 | activity_id = 504, distinct dst_endpoint.svc_name per user.name |
| Privileges that enable credential access | 3005 | privileges contains SeDebugPrivilege, SeBackupPrivilege |
7.7 Discovery and enumeration
| Looking for | Class(es) | Fields |
|---|---|---|
| Registry reads and enumeration | 201001, 201002 | activity_id = 102 / 202 |
| Network connection enumeration | 201008, 201007 | api_name = GetExtendedTcpTable; input_command contains netstat |
| Process enumeration | 201008, 201007 | api_name in NtQuerySystemInformation, EnumProcessModules; input_command contains tasklist |
| Host information queries | 201008, 201007 | api_name in GetSystemInfo, RtlGetVersion, GetVolumeInformationW; input_command contains systeminfo |
| User and group enumeration | 201007, 1009 | input_command contains net user, net group; script.content contains Get-ADUser, Get-NetGroupMember |
| Current-user queries | 201008, 201007 | api_name in GetUserNameW, NtQueryInformationToken; input_command contains whoami |
| Network adapter queries | 201008, 201007 | api_name in GetAdaptersInfo, GetAdaptersAddresses; input_command contains ipconfig |
| Port scanning | 4001 | many distinct dst_endpoint.port from one actor.process.uid |
| Share enumeration | 4006, 201007 | many distinct dst_endpoint.ip on port 445; input_command contains net view |
| Security-product enumeration | 201005, 201007 | unmapped.wmi_activity.filter_query contains AntiVirusProduct; input_command contains Get-MpComputerStatus |
| File and directory enumeration | 201008 | api_name in NtQueryAttributesFile, NtCreateDirectoryFile |
| Window enumeration | 201008 | api_name in EnumWindows, NtUserFindWindowEx |
7.8 Lateral movement
| Looking for | Class(es) | Fields |
|---|---|---|
| Inbound authentication | 3002 | is_remote = true; logon_type_id; src_endpoint.ip; user.name |
| SMB session establishment with identity | 4006 | activity_id = 1802; dst_endpoint.owner.name; unmapped.smb.auth_protocol; src_endpoint.ip |
| Remote desktop sessions | 3002 | logon_type_id = 10 |
| Remote management ports | 4001 | dst_endpoint.port in 5985,5986,135,445,3389 |
| Remotely created processes | 1007 | activity_id = 1 with is_remote = true |
| Remotely created services | 201004 | activity_id = 1 with is_remote = true |
| Remote WMI operations | 201005 | activity_id in 1601,1602,1603 |
| Files written over the network | 1001 | is_remote = true with activity_id in 6,8 |
| Legacy or downgraded SMB | 4006 | unmapped.smb.is_smb1_protocol; unmapped.smb.selected_dialect |
| One client across multiple sessions | 4006 | unmapped.smb.client_guid |
| Alternate-credential logons | 3002 | logon_type_id = 9 |
7.9 Collection, staging and exfiltration
| Looking for | Class(es) | Fields |
|---|---|---|
| Detected collection behaviour | 201003 | message contains CLIPBOARD_DATA, SCREENSHOT, AUTOMATED_COLLECTION, DATA_FROM_LOCAL_SYSTEM, DATA_FROM_NETWORK_DRIVE, DATA_STAGING_LOCAL |
| Archiving of collected data | 201003 | message contains ARCHIVE_VIA_UTILITY, ARCHIVE_CUSTOM_METHOD, COMPRESSION_DETECTION |
| Detected exfiltration behaviour | 201003 | message contains EXFILTRATION_, DATA_TRANSFER_SIZE_LIMIT |
| Large outbound transfers | 4001 | connection_info.direction_id = 2 with traffic.bytes above a threshold |
| Uploads through the browser | 4002 | action = "Upload"; http_activity_fields.file_size |
| Archive files created | 1001 | file.ext in "zip","7z","rar","cab","tar","gz" |
| Staging directories filling up | 1001 | activity_id in 6,8 grouped by directory prefix |
7.10 Network activity and outbound command channels
| Looking for | Class(es) | Fields |
|---|---|---|
| Outbound connections by process | 4001 | connection_info.direction_id = 2; actor.process.name; dst_endpoint.* |
| Uncommon destination ports | 4001 | dst_endpoint.port outside the expected set |
| Regular small outbound connections | 4001 | group by dst_endpoint.ip + actor.process.uid, look for even spacing |
| Name resolution by process | 4003 | query.hostname; actor.process.name |
| Failed-resolution bursts | 4003 | rcode_id = 3 grouped by actor.process.uid |
| Long or high-entropy names | 4003 | query.hostname |
| Name resolution over TCP | 4003 | connection_info.protocol_name = "tcp" |
| Detected tunnelling behaviour | 201003 | message contains DNS_TUNNELING |
| Non-TCP/UDP protocols | 4001 | connection_info.protocol_num in 1,58 |
| URLs seen in traffic | 4001, 4002 | url.url_string; http_request.url.url_string |
| Inbound connections to a workstation | 4001 | connection_info.direction_id = 1 |
| Remote shell sessions | 201007 | is_remote = true; unmapped.command_activity.remote_ip |
7.11 Destructive and disruptive activity
| Looking for | Class(es) | Fields |
|---|---|---|
| Detected encryption behaviour | 201003 | message contains RANSOMWARE_DETECTION, OBFUSCATED_FILE_ENCRYPTED |
| Bulk renames changing extensions | 1001 | activity_id = 10 with file.ext != file_result.ext, grouped by actor.process.uid |
| Bulk deletions | 1001 | activity_id = 9 grouped by actor.process.uid |
| Cryptography key derivation and bulk decryption | 201008 | api_name in BCryptGenerateSymmetricKey, BCryptDeriveKeyPBKDF2, BCryptDecrypt, CryptDeriveKey, CryptDecrypt |
| Boot-record writes | 201009 | activity_id = 3 with unmapped.volume.offset = 0 |
| Large raw disk writes | 201009 | activity_id = 3; unmapped.volume.length |
| Backup interference | 201003, 201007, 201004 | message contains VSS_TAMPER_PROTECTION; input_command contains vssadmin delete, wbadmin delete, bcdedit; service activity_id = 4 |
| Shadow-copy and backup files deleted | 1001 | activity_id = 9; file.path contains System Volume Information; file.ext in "bak","vhd","vbk" |
| Shutdown and reboot | 1011 | activity_id in 2,5; unmapped.device_power_state.comment |
| Service stops | 201004 | activity_id = 4 |
| Accounts disabled or deleted | 3001 | activity_id in 1003,1004 |
| Note or ransom files dropped | 1001 | file.name contains README, DECRYPT, RECOVER |
7.12 Files and binaries
| Looking for | Class(es) | Fields |
|---|---|---|
| A binary by hash, anywhere | 1007, 1001, 1005, 201010 | process.file.sha256, file.sha256, module.file.sha1, file.hashes.value |
| Unsigned binaries written to disk | 201010 | unmapped.on_write_scan_result.is_signed = 0 |
| Scan verdicts on written binaries | 201010 | unmapped.on_write_scan_result.is_malware, .confidence |
| Signer identity of a written binary | 201010 | unmapped.on_write_scan_result.publisher |
| Rule matches on files | (YARA) | yara_detection.rule_name, .threat_name |
| Signer identity of a script file | 1009 | unmapped.amsi_signer_verified, .amsi_signer_publisher |
| Executables in user-writable locations | 1001, 1007 | file.path / process.file.path contains \AppData\, \Temp\, \ProgramData\, \Users\Public\ |
| Publisher of a running executable | 1007 | process.file.company_name, process.file.version |
8. Hunting Playbooks
Each playbook assumes you have already scoped to a host and window:
device.hostname = "WORKSTATION-01" and time >= <start> and time < <end + 60000>8.1 Profiling a suspicious process
You have a process name, pid, hash or UUID and want to know everything it did.
# 1. Find the launch event and capture process.uid
class_uid = 1007 and activity_id = 1
and process.name = "<name>" # or process.file.sha256 = "<hash>"
# 2. Everything that process instance did, across all classes
actor.process.uid = "<process.uid from step 1>"
# 3. Break it down by class
class_uid = 1001 and actor.process.uid = "<uid>" # files
class_uid = 201002 and actor.process.uid = "<uid>" # registry values
class_uid = 4001 and actor.process.uid = "<uid>" # network
class_uid = 4003 and actor.process.uid = "<uid>" # name resolution
class_uid = 1005 and actor.process.uid = "<uid>" # modules loaded
class_uid = 1009 and actor.process.uid = "<uid>" # script content
# 4. Where did it come from? Read process.parent_process.* and
# actor.process.* on the launch event, then walk upward:
class_uid = 1007 and process.uid = "<the parent's uid>"
# 5. What did its children do?
actor.process.lineage_uid contains "<uid>"
# 6. Any verdicts against it?
class_uid in 2004,201003 and actor.process.uid = "<uid>"
# 7. The whole chain it belongs to
<scope> and dpid = <the dpid from any of its events>8.2 Investigating persistence on a host
# 1. Sweep every persistence-bearing class at once
class_uid in 1006,201004,201005,201002 and <scope>
# 2. Scheduled tasks
class_uid = 1006 and activity_id in 1,2
# read: job.name, job.cmd_line, job.file.path, job.run_as.name,
# unmapped.scheduled_job.scheduled_job_visibility,
# unmapped.scheduled_job.scheduled_job_privilege,
# unmapped.scheduled_job.scheduled_job_triggers,
# actor.process.name (who registered it)
# 3. Services
class_uid = 201004 and activity_id in 1,2
# read: win_service.name, win_service.service_file.path,
# win_service.service_start_name, win_service.service_start_type,
# win_service.service_type_id,
# unmapped.win_service_lifecycle.persistence_flags,
# actor.process.name (the SCM caller)
# 4. WMI subscriptions — check the install and the execution
class_uid = 201005 and activity_id in 1603,1605,1609
# read: unmapped.wmi_activity.filter_query (the trigger)
# unmapped.wmi_activity.consumer_type
# unmapped.wmi_activity.consumer_command_line (the payload)
# unmapped.wmi_activity.consumer_script_text
# 1605 = the binding went live; 1609 = it actually ran
# 5. Registry autostart values, with the payload
class_uid = 201002 and activity_id = 203
and reg_value.path contains "currentversion\run"
# read: reg_value.name, reg_value.reg_string_data
# 6. Startup-folder files
class_uid = 1001 and activity_id in 6,8
and file.path contains "\Start Menu\Programs\Startup"
# 7. Who did all of this, and what else did they do?
<scope> and dpid = <from any of the above>
session.uid = "<from any event that carries one>"Checklist
- [ ] Is the payload captured (job.cmd_line / reg_value.reg_string_data / consumer_command_line)?
- [ ] Is the registering caller attributed (actor.process.name)?
- [ ] For WMI, did you get both the install and the delivery event?
- [ ] Does the persistence run as a privileged account (job.run_as, win_service.service_start_name)?
- [ ] Does session.uid join back to a logon?
8.3 Investigating credential access
# 1. Behaviour verdicts
class_uid = 201003
and (message contains "LSASS_OPEN_HANDLE" or message contains "LSASS_REMOTE_THREAD"
or message contains "ReplicatingDirectoryChanges")
# 2. API-level evidence
class_uid = 2004 and associated_class_uid = 201008
and (unmapped.api_telemetry.api_name contains "Cred"
or unmapped.api_telemetry.api_name contains "Vault"
or unmapped.api_telemetry.api_name = "ApiTelemetry_CryptUnprotectData")
# 3. Registry hive saved to file
class_uid = 201001 and activity_id = 102 and status_detail = "Save Key"
# 4. Raw volume or shadow-copy reads
class_uid = 2004 and associated_class_uid = 201009
and unmapped.volume.raw_volume_type in "VssShadow","LogicalVolume"
# 5. Prerequisite privileges granted
class_uid = 3005
and (privileges contains "SeDebugPrivilege" or privileges contains "SeBackupPrivilege")
# 6. Commands typed
class_uid = 201007
and (unmapped.command_activity.input_command contains "lsass"
or unmapped.command_activity.input_command contains "reg save"
or unmapped.command_activity.input_command contains "vssadmin"
or unmapped.command_activity.input_command contains "ntdsutil")
# 7. Scripted access
class_uid = 1009
and (script.content contains "MiniDumpWriteDump" or script.content contains "sekurlsa"
or script.content contains "lsass")
# 8. Output artefacts written
class_uid = 1001 and activity_id in 6,8
and (file.ext in "dmp","dit","hive","bin" or file.name contains "lsass")
# 9. Authentication anomalies that follow
class_uid = 3002 and <scope>8.4 Investigating cross-process memory activity
# 1. Behaviour verdicts
class_uid = 201003
and (message contains "INJECTION" or message contains "HOLLOWING"
or message contains "SHELLCODE_INJECTED" or message contains "REFLECTIVE"
or message contains "THREAD_EXECUTION_HIJACK" or message contains "MODULE_STOMPING")
# 2. The API sequence — every hit is against a foreign process
class_uid = 2004 and associated_class_uid = 201008
and unmapped.api_telemetry.api_name in
"ApiTelemetry_NtAllocateVirtualMemoryRemote",
"ApiTelemetry_NtWriteVirtualMemoryRemote",
"ApiTelemetry_NtWriteVirtualMemoryRemoteExecutable",
"ApiTelemetry_NtProtectVirtualMemoryRemote",
"ApiTelemetry_NtCreateRemoteThread",
"ApiTelemetry_NtUnmapViewOfSectionRemote"
# order by time, group by actor.process.uid — you should see
# allocate → write → protect → create-thread
# 3. Processes created suspended
class_uid = 2004 and associated_class_uid = 201008
and unmapped.api_telemetry.api_name contains "Suspended"
# 4. Both sides of the pair
class_uid = 201003
and (message contains "\"isInjector\": true" or message contains "\"isInjectee\": true")
# 5. Modules that appeared in the target afterwards
class_uid = 1005 and actor.process.uid = "<target uid>"
# 6. What the target process then did
actor.process.uid = "<target uid>"
# 7. The whole chain
<scope> and dpid = <from step 1 or 2>8.5 Investigating lateral movement into a host
# 1. Who authenticated in, as whom, and how?
class_uid = 3002 and activity_id = 501 and is_remote = true
# read: user.name, src_endpoint.ip, logon_type_id, auth_protocol_id, session.uid
# 2. SMB session detail — protocol and identity
class_uid = 4006 and activity_id = 1802
# read: src_endpoint.ip, dst_endpoint.owner.name,
# unmapped.smb.auth_protocol, unmapped.smb.is_smb1_protocol,
# unmapped.smb.client_guid
# 3. Files that arrived over the network
class_uid = 1001 and is_remote = true and activity_id in 6,8
# read: file.path, src_endpoint.ip
# 4. Execution mechanisms
class_uid = 1007 and activity_id = 1 and is_remote = true # remote process creation
class_uid = 201004 and activity_id = 1 and is_remote = true # remote service creation
class_uid = 201005 and activity_id in 1602,1603 # remote WMI operations
# 5. Interactive shell that followed
class_uid = 201007 and is_remote = true
# 6. Everything done in that logon session
session.uid = "<from step 1>"
# 7. Where did they go next?
class_uid = 4001 and connection_info.direction_id = 2
and dst_endpoint.port in 445,135,139,3389,5985,5986
and actor.process.uid = "<uid of what they ran>"8.6 Investigating destructive or encryption activity
# 1. Behaviour verdict
class_uid = 201003
and (message contains "RANSOMWARE_DETECTION" or message contains "OBFUSCATED_FILE_ENCRYPTED")
# 2. Bulk renames that changed the extension
class_uid = 1001 and activity_id = 10 and file.ext != file_result.ext
# group by actor.process.uid, count — a sharp spike is the signal
# 3. Cryptography sequence
class_uid = 2004 and associated_class_uid = 201008
and unmapped.api_telemetry.api_name in
"ApiTelemetry_BCryptGenerateSymmetricKey","ApiTelemetry_BCryptDeriveKeyPBKDF2",
"ApiTelemetry_BCryptDecrypt","ApiTelemetry_CryptDeriveKey","ApiTelemetry_CryptDecrypt"
# 4. Recovery interference
class_uid = 201003 and message contains "VSS_TAMPER_PROTECTION"
class_uid = 201007
and (unmapped.command_activity.input_command contains "vssadmin delete"
or unmapped.command_activity.input_command contains "wbadmin delete"
or unmapped.command_activity.input_command contains "bcdedit")
class_uid = 201004 and activity_id = 4 and win_service.name in "VSS","SQLWriter","BITS"
# 5. Boot-record or bulk raw writes
class_uid = 2004 and associated_class_uid = 201009
and activity_id = 3 and unmapped.volume.offset = 0
# 6. Reboot, and any comment left on it
class_uid = 1011 and unmapped.device_power_state.comment != ""
# 7. Note files dropped
class_uid = 1001 and activity_id in 6,8
and (file.name contains "README" or file.name contains "DECRYPT"
or file.name contains "RECOVER")
# 8. The full chain and the entry point
<scope> and dpid = <from step 1 or 2>8.7 Building a coverage picture
Useful when validating a control, reviewing detection quality, or sanity-checking a quiet window.
# Which classes produced data on this host?
<scope>
# group by class_uid — cross-check the result against the
# collection scope in Section 3
# What is firing, and from which activity classes?
class_uid = 2004 and <scope>
# group by finding_info.title, then by associated_class_name
# How many distinct activity chains were identified?
class_uid = 2004 and <scope> and dpid != 0
# count distinct dpid
# Rule versions in play — useful when comparing two time periods
class_uid = 2004 and <scope>
# group by finding_info.analytic.version
# Delivery batches covering the window
<scope>
# group by batch_name, order by time9. Complete Enum Reference
9.1 activity_id — by class
Always pair activity_id with class_uid.
| Class | Reported activity_id values |
|---|---|
| 1001 File | 0 Unknown, 6 Create, 8 Update, 9 Delete, 10 Rename, 20 Directory Create |
| 1005 Module | 601 Load |
| 1006 Scheduled Job | 0 Unknown, 1 Create, 2 Update, 3 Delete, 4 Enable, 5 Disable, 6 Start, 99 Other |
| 1007 Process | 1 Launch, 2 Terminate |
| 1009 Script | 2101 Execute |
| 1011 Device Power State | 0 Unknown, 2 Power Off, 5 Reboot, 99 Other |
| 2001 Security Finding | 2201 Create, 2299 Other |
| 2004 Detection Finding | 1901 Create |
| 3001 Account Change | 1000 Unknown, 1001 Create, 1002 Enable, 1003 Disable, 1004 Delete, 1005 Lock, 1006 Reset Password, 1007 Unlock, 1008 Change Password, 1099 Other |
| 3002 Authentication | 501 Logon, 503 AuthTicket, 504 ServiceTicket, 505 TicketRenew, 506 Preauth |
| 3005 User Access Management | 1400 Unknown, 1401 Assign Privileges, 1499 Other |
| 3006 Group Management | 1100 Unknown, 1103 Add Member, 1199 Other |
| 4001 Network | 306 Traffic |
| 4002 HTTP | 601 Open, 602 Close, 603 Connect |
| 4003 DNS | 401 Query, 402 Response |
| 4006 SMB | 1800 Unknown, 1801 Negotiate, 1802 Session Setup, 1803 Logoff, 1804 Session Delete, 1899 Other |
| 6001 Web Resources | 701 Access, 702 Create, 703 Update, 704 Delete, 799 Other |
| 6002 Application Lifecycle | 801 Install, 802 Remove, 803 Start, 804 Stop, 899 Other |
| 201001 Registry Key | 100 Unknown, 101 Create, 102 Read, 104 Delete, 105 Rename, 106 Set Security |
| 201002 Registry Value | 202 Read, 203 Modify, 204 Delete |
| 201003 Suspicious Behaviour | 1500 |
| 201004 Windows Service | 0 Unknown, 1 Create, 2 Reconfigure, 3 Start, 4 Stop, 5 Pause, 6 Continue, 7 Delete, 99 Other |
| 201005 WMI | 1600 Unknown, 1601 Connect, 1602 Query, 1603 Create, 1604 Delete, 1605 Binding Activated, 1606 Temporary Subscription, 1608 Failure, 1609 Event Delivered, 1699 Other |
| 201007 Command | 2000 |
| 201008 API Telemetry | 2301 Query |
| 201009 Volume | 0 Unknown, 1 Open, 2 Read, 3 Write |
| 201010 On-Write Scan Result | 2601 Scan |
Two numbering conventions are in use. Classes whose activity vocabulary maps onto the OCSF canonical list report the OCSF 0—99 identifier: 1001, 1006, 1007, 1011, 201004 and 201009. The remaining classes report a namespaced identifier drawn from a per-class block. Both are stable; read the values from the table above and always qualify them with class_uid.
9.2 class_uid — event class
| Value | Class |
|---|---|
| 1001 | File Activity |
| 1005 | Module Activity |
| 1006 | Scheduled Job Activity |
| 1007 | Process Activity |
| 1009 | Script Activity |
| 1011 | Device Power State Activity |
| 2001 | Security Finding |
| 2004 | Detection Finding |
| 3001 | Account Change |
| 3002 | Authentication |
| 3005 | User Access Management |
| 3006 | Group Management |
| 4001 | Network Activity |
| 4002 | HTTP Activity |
| 4003 | DNS Activity |
| 4006 | SMB Activity |
| 6001 | Web Resources Activity |
| 6002 | Application Lifecycle |
| 201001 | Registry Key Activity |
| 201002 | Registry Value Activity |
| 201003 | Suspicious Behaviour Activity |
| 201004 | Windows Service Activity |
| 201005 | WMI Activity |
| 201007 | Command Activity |
| 201008 | API Telemetry Activity |
| 201009 | Volume Activity |
| 201010 | On-Write Scan Result Activity |
YARA detections are identified by type_name = "yara_detection_event" — see 6.24.
9.3 category_uid — event category
| Value | Category | Classes |
|---|---|---|
| 0 | Unknown | — |
| 1 | System Activity | 1001, 1005, 1006, 1007, 1009, 1011, 201001—201010 |
| 2 | Findings | 2001, 2004 |
| 3 | Identity & Access Management | 3001, 3002, 3005, 3006 |
| 4 | Network Activity | 4006 |
Network Activity (4001) and DNS Activity (4003) are categorised as System Activity; SMB Activity (4006) is categorised as Network Activity. Filter on class_uid rather than category_uid when selecting network telemetry.
9.4 type_uid — composite event type
type_uid = class_uid × 100 + ocsf_activity_id.
| Class | type_uid values |
|---|---|
| 1001 File | 100100 Unknown, 100101 Create, 100102 Read, 100103 Update, 100104 Delete, 100105 Rename, 100106 Set Attributes, 100115 Directory Create |
| 1005 Module | 100501 Load |
| 1006 Scheduled Job | 100600, 100601 Create, 100602 Update, 100603 Delete, 100604 Enable, 100605 Disable, 100606 Start, 100699 Other |
| 1007 Process | 100701 Launch, 100702 Terminate |
| 1009 Script | 100901 Execute |
| 1011 Device Power State | 101100, 101102 Power Off, 101105 Reboot, 101199 Other |
| 2001 Security Finding | 200101 Create, 200199 Other |
| 2004 Detection Finding | 200401 Create |
| 3001 Account Change | 300100, 300101 Create, 300102 Enable, 300103 Disable, 300104 Delete, 300105 Lock, 300106 Reset Password, 300107 Unlock, 300108 Change Password, 300199 Other |
| 3002 Authentication | 300201 Logon, 300203 AuthTicket, 300204 ServiceTicket, 300205 TicketRenew, 300206 Preauth |
| 3005 User Access Management | 300500, 300501 Assign Privileges, 300599 Other |
| 3006 Group Management | 300600, 300603 Add Member, 300699 Other |
| 4001 Network | 400106 Traffic |
| 4002 HTTP | 400201 Open, 400202 Close, 400203 Connect, 400299 Upload |
| 4003 DNS | 400301 Query, 400302 Response |
| 4006 SMB | 400600, 400601 Negotiate, 400602 Session Setup, 400603 Logoff, 400604 Session Delete, 400699 Other |
| 6001 Web Resources | 600100, 600101 Access, 600102 Create, 600103 Update, 600104 Delete, 600199 Other |
| 6002 Application Lifecycle | 600200, 600201 Install, 600202 Remove, 600203 Start, 600204 Stop, 600299 Other |
| 201001 Registry Key | 20100100, 20100101 Create, 20100102 Read, 20100104 Delete, 20100105 Rename, 20100106 Set Security |
| 201002 Registry Value | 20100202 Read, 20100203 Modify, 20100204 Delete |
| 201004 Windows Service | 20100400, 20100401 Create, 20100402 Reconfigure, 20100403 Start, 20100404 Stop, 20100405 Pause, 20100406 Continue, 20100407 Delete, 20100499 Other |
| 201005 WMI | 20100500, 20100501 Connect, 20100502 Query, 20100503 Create, 20100504 Delete, 20100505 Binding Activated, 20100506 Temporary Subscription, 20100508 Failure, 20100509 Event Delivered, 20100599 Other |
| 201008 API Telemetry | 20100801 Query |
| 201009 Volume | 20100900, 20100901 Open, 20100902 Read, 20100903 Write |
| 201010 On-Write Scan Result | 20101001 Scan |
Suspicious Behaviour Activity (201003) and Command Activity (201007) are filtered by class_uid; they do not carry a type_uid.
9.5 severity_id — event severity
| Value | Meaning | Where it appears |
|---|---|---|
| 0 | Unknown | — |
| 1 | Informational | Raw telemetry |
| 2 | Low | Detection Findings, and findings attached to an origin event |
| 3 | Medium | WMI event-delivered events and WMI failures |
| 4 | High | WMI binding-activated events |
| 5 | Critical | — |
| 6 | Fatal | — |
| 99 | Other | — |
YARA detections carry their severity in the severity string and in yara_detection.severity.
9.6 status_id — activity status
| Value | Meaning |
|---|---|
| 0 | Unknown |
| 1 | Success |
| 2 | Failure |
| 99 | Other |
9.7 logon_type_id — Windows logon type
Authentication (3002) only.
| Value | Meaning | Relevance |
|---|---|---|
| 0 | Unknown | |
| 1 | System | System account at startup |
| 2 | Interactive | Local console logon |
| 3 | Network | Logon from the network. On failures the subject fields are supplied by the client. |
| 4 | Batch | Scheduled task or batch job |
| 5 | Service | Service or daemon startup |
| 7 | Unlock | Workstation unlock |
| 8 | NetworkCleartext | Network logon with an unhashed password |
| 9 | NewCredentials | Alternate credentials supplied explicitly |
| 10 | RemoteInteractive | Remote desktop |
| 11 | CachedInteractive | Cached domain credentials |
| 12 | CachedRemoteInteractive | Internal audit variant of 10 |
| 13 | CachedUnlock | Cached unlock |
| 99 | Other | Not mapped |
is_remote = true is set for types 3, 8, 10 and 12. Windows does not use logon type 6.
9.8 auth_protocol_id — authentication protocol
| Value | Meaning |
|---|---|
| 0 | Unknown |
| 1 | NTLM |
| 2 | Kerberos — also reported when the package is Negotiate |
| 3 | Digest |
| 12 | LDAP |
Read the raw string in auth_protocol when you need to distinguish Negotiate from Kerberos proper.
9.9 rcode_id — DNS response code
| Value | Meaning |
|---|---|
| 0 | NoError — successful resolution |
| 1 | FormError — query format error |
| 2 | ServError — server failure |
| 3 | NXDomain — the name does not exist |
| 4 | NotImp |
| 5 | Refused |
| 6 | YXDomain |
| 7 | YXRRSet |
| 8 | NXRRSet |
| 9 | NotAuth |
| 10 | NotZone |
| 11 | DSOTYPENI |
| 99 | Other |
9.10 query.opcode_id — DNS operation code
| Value | Meaning |
|---|---|
| 0 | Query (standard) |
| 1 | Inverse Query |
| 2 | Status |
| 3 | Reserved |
| 4 | Notify |
| 5 | Update |
| 6 | DSO Message |
| 99 | Other |
9.11 connection_info enums
direction_id: 0 Unknown, 1 Inbound, 2 Outbound, 3 Lateral, 4 Local.
protocol_num (IANA): 0 HOPOPT, 1 ICMP, 6 TCP, 17 UDP, 58 ICMPv6.
protocol_ver_id: 4 IPv4, 6 IPv6.
9.12 user.type_id — account type
Applies to user, actor.user, process.user, actor.process.user, process.parent_process.user, job.run_as and dst_endpoint.owner.
| Value | Meaning | How it is determined |
|---|---|---|
| 0 | Unknown | Username empty or unresolvable |
| 1 | User | Regular account |
| 2 | Admin | The process held an elevated token |
| 3 | System | The username or SID identifies a built-in system account |
9.13 file.type_id — file type
| Value | Meaning |
|---|---|
| 0 | Unknown |
| 1 | Regular File |
| 2 | Folder |
| 3 | Character Device |
| 4 | Block Device |
| 5 | Local Socket |
| 6 | Named Pipe |
| 7 | Symbolic Link |
| 99 | Other |
To identify directory creation specifically, use File Activity activity_id = 20.
9.14 hashes[].algorithm_id — hash algorithm
| Value | Meaning | Where used |
|---|---|---|
| 0 | Unknown | |
| 1 | MD5 | |
| 2 | SHA-1 | Module Activity (1005) |
| 3 | SHA-256 | Process, File, On-Write Scan Result, YARA, Script |
| 4 | SHA-512 | |
| 5 | CTPH | |
| 6 | TLSH | |
| 7 | quickXorHash | |
| 99 | Other |
9.15 reg_value.type_id — registry value type
| Value | Meaning | Data appears in |
|---|---|---|
| 0 | REG_NONE | reg_binary_data |
| 1 | REG_SZ | reg_string_data |
| 2 | REG_EXPAND_SZ | reg_string_data |
| 3 | REG_BINARY | reg_binary_data (base64) |
| 4 | REG_DWORD | reg_integer_data |
| 5 | REG_DWORD_BIG_ENDIAN | reg_integer_data |
| 6 | REG_LINK | reg_string_data |
| 7 | REG_MULTI_SZ | reg_string_list_data |
| 8 | REG_RESOURCE_LIST | reg_binary_data |
| 9 | REG_FULL_RESOURCE_DESCRIPTOR | reg_binary_data |
| 10 | REG_RESOURCE_REQUIREMENTS_LIST | reg_binary_data |
| 11 | REG_QWORD | reg_integer_data |
9.16 script.type_id — script type
| Value | Meaning | Source |
|---|---|---|
| 0 | Unknown | |
| 1 | Windows Cmd | |
| 2 | PowerShell | PowerShell / CoreCLR |
| 3 | Python | |
| 4 | JavaScript / JScript | JScript |
| 5 | VBScript | VBScript |
| 6 | Unix shell | |
| 7 | VBA | Office VBA / Excel |
| 99 | Other | WMI, VSS, Exchange, .NET |
9.17 observables[].type_id — observable type
| Value | Meaning |
|---|---|
| 0 | Unknown |
| 1 | Hostname |
| 2 | IP Address |
| 10 | Endpoint |
| 24 | File |
| 25 | Process |
| 99 | Other |
9.18 device.type_id and device.os.type_id
device.type_id: 0 Unknown, 1 Server, 2 Desktop, 3 Laptop, 4 Tablet, 5 Mobile, 6 Virtual, 7 IoT, 8 Browser, 9 Firewall, 10 Switch, 11 Hub, 12 Router, 13 IDS, 14 IPS, 15 Load Balancer, 99 Other.
device.os.type_id: 0 Unknown, 99 Other, 100 Windows, 101 Windows Mobile, 200 Linux, 201 Android, 300 macOS, 301 iOS, 302 iPadOS, 400 Solaris, 401 AIX, 402 HP-UX.
To segment an estate by platform, device.os.version and your asset inventory are the most reliable inputs.
9.19 module.load_type_id — module load type
| Value | Meaning |
|---|---|
| 0 | Unknown |
| 1 | Standard — the value reported for image-load events |
| 2 | Non-Standard |
| 3 | ShellCode |
| 4 | Mapped |
| 5 | NonStandard_Backed |
| 99 | Other |
For the technique behind a load, use Suspicious Behaviour Activity (201003) and API Telemetry Activity (201008).
9.20 win_service enums
service_start_type_id: 0 Unknown, 1 Boot, 2 System, 3 Auto, 4 Demand, 5 Disabled, 99 Other.
service_type_id: 0 Unknown, 1 Kernel driver, 2 Filesystem driver, 3 Own process, 4 Share process, 5 Recognizer driver, 6 Adapter, 99 Other. Caption modifiers appended to service_type: " [user service]", " [user-service instance]", " [interactive]", " [packaged]".
service_category_id: 0 Unknown, 1 Kernel Mode (types 1, 2, 5, 6), 2 User Mode (types 3, 4), 99 Other.
9.21 unmapped.volume enums
raw_volume_type (string): "PhysicalDisk", "LogicalVolume", "VssShadow", "Unknown".
fs_type (string): "RAW", "NTFS", "FAT", "EXFAT", "REFS", "CDFS", "UDFS", "LANMAN", "WEBDAV", "RDPDR", "NFS", "MUP", "CSVFS", "NPFS", "MSFS", "GPFS", "PSFS", "OPENAFS", "CIMFS", and others; "Unknown" where unmapped.
device_characteristics (bitmask): 0x1 removable media, 0x2 read-only, 0x4 floppy, 0x8 write-once, 0x10 remote/network device, 0x20 mounted, 0x40 virtual volume, 0x80 autogenerated name, 0x100 secure open, 0x800 plug-and-play, 0x1000 terminal-services device, 0x2000 WebDAV device.
operation (un-normalised): 2500 Unknown, 2501 Open, 2502 Read, 2503 Write.
9.22 unmapped.on_write_scan_result.source_file_type
| Value | Meaning |
|---|---|
| 0 | Unknown |
| 1 | EXE |
| 2 | DLL |
| 3 | Test file |
| 4 | .NET assembly |
9.23 finding_info.analytic.type_id
| Value | Meaning |
|---|---|
| 1 | Rule |
| 2 | ML |
| 3 | Fingerprinting |
10. Field Types and Search Operators
10.1 Field types
| Type | Description | Operators | Group-by |
|---|---|---|---|
| String | Single text value | All operators | Yes |
| Long | 64-bit integer; not compatible with string operators | =, !=, <, <=, >, >=, in, notin | Yes |
| DateTime | Long storing epoch milliseconds | =, !=, <, <=, >, >=, in, notin | Yes |
| Boolean | true / false | =, != | Yes |
| JSONObject | Container; navigate to a leaf field to filter | container only | No |
| JSONArray | Array of objects; a condition matches if any element satisfies it | container only | No |
| String[] | Flat string array; matches if any element matches | contains, notcontains, spanNear | No |
| Long[] | Flat integer array | =, !=, <, <=, >, >= | No |
String[] fields: process.lineage_uid, actor.process.lineage_uid, privileges, unmapped.sid_history, unmapped.scheduled_job.scheduled_job_triggers, unmapped.win_service_lifecycle.persistence_flags, win_service.service_dependencies, finding_info.types, finding_info.analytic.data_sources, reg_value.reg_string_list_data, ext_lifecycle_fields.ext_permissions, ext_lifecycle_fields.ext_host_perms, unmapped.emails.
JSONArray fields: observables, answers, finding_info.attacks, unmapped.analytic_steps, web_resources, web_resources_result, and every hashes array.
10.2 Search operators
| Operator | Applies to | Description | Example |
|---|---|---|---|
| = / != | String, Long, DateTime, Boolean | Exact match / not equal | class_uid = 201005 |
| < <= > >= | Long, DateTime, String (lexicographic) | Range comparison | traffic.bytes >= 5000000 |
| in / notin | String, Long | List membership | activity_id in 1,2,3 |
| contains / notcontains | String, String[] | Substring, or array-element match | file.path contains "AppData" |
| startswith / notstartswith | String | Prefix match | file.path startswith "C:\Users\" |
| endswith / notendswith | String | Suffix match | file.name endswith ".ps1" |
| spanNear | String, String[] | Proximity — terms appear near each other | process.cmd_line spanNear ("powershell","hidden") |
spanNear syntax:
field spanNear ("term1","term2"[,distance[,ordered]])
process.cmd_line spanNear ("powershell","hidden",10,false)
script.content spanNear ("Invoke-Expression","Base64",30,false)
process.cmd_line spanNear ("certutil","decode",5,true)10.3 Boolean logic
Combine with and, or, not; use parentheses to control precedence.
class_uid = 1007
and activity_id = 1
and actor.process.user.type_id = 3
and process.name = "powershell.exe"
class_uid = 1001
and (file.ext = "exe" or file.ext = "ps1")
and file.path contains "Temp"
class_uid = 3002
and status_id = 2
and not src_endpoint.ip = "192.168.1.10"10.4 Time-range patterns
Every timestamp is epoch milliseconds.
# A specific 24-hour window
time >= 1704067200000 and time < 1704153600000
# A window with a short tail so trailing findings are included
time >= 1704067200000 and time <= 1704070860000
# Scope by process creation time
actor.process.created_time >= 1704067200000
and actor.process.created_time < 1704153600000
# Name-resolution events in a range
class_uid = 4003 and query_time >= 1704067200000 and query_time < 1704153600000DateTime fields by class:
| Field | Present in |
|---|---|
| time | All |
| metadata.original_time | All |
| actor.process.created_time | Every class with an actor process |
| process.created_time | 1007, on Launch |
| process.terminated_time | 1007, on Terminate |
| process.parent_process.created_time | 1007 |
| query_time | 4003 |
| finding_info.created_time | 2004, 2001, and origin-attached findings |
| file.accessed_time / modified_time / created_time | Where a File object is populated |
| unmapped.detection_time | 2001 |
| unmapped.capture_time | Browser capture events |
Schema: OCSF — metadata.version reports 1.3.0, with OCSF 1.7/1.8 object shapes and nine private extension classes in the 201xxx range Product:Endpoint CentralEvent classes documented: 27, plus YARA detections