Learn

Reading the Telemetry

Knowing a data source exists isn't the same as reading it

How Our Ranges Work covered what telemetry you have: Windows Event Logs, Sysmon, Zeek, and the rest. That's necessary but it isn't sufficient. Knowing Sysmon logs process creation doesn't help you if you've never actually looked at a Sysmon event and worked out what each field is telling you. This page is the missing step: reading a real event, field by field, until the format stops looking like noise.

The five examples below, Windows and Linux endpoint telemetry, then Zeek and Suricata network telemetry, are real event shapes you'll see directly in Elastic once you're in a scenario, not simplified stand-ins.

A Windows Event Log, field by field

Windows Security Event ID 4769, "A Kerberos service ticket was requested," looks like this once it lands in Elastic:

event.code: "4769" winlog.event_data.TargetUserName: "svc_sql" winlog.event_data.ServiceName: "svc_sql" winlog.event_data.TicketEncryptionType: "0x17" winlog.event_data.IpAddress: "10.1.10.21"

Read it the way you'd read any Windows Security event: the event.code tells you which event this is, full stop, before anything else matters. TargetUserName and ServiceName here both point at the same account, that's specific to how ticket requests work, not universal. TicketEncryptionType is the field worth knowing cold for this event: 0x17 is RC4, the weaker, crackable encryption, and it's the single strongest signal in this entire event. IpAddress tells you where the request actually came from, the workstation, not the domain controller processing it.

Nothing here is exotic. It's five fields, and once you know what each one means for this specific event type, the whole thing reads in about two seconds instead of looking like an opaque block of key-value pairs.

Index: mr-winlog-* (domain-controller side). A workstation-side Windows Security event, like a plain logon, lands in mr-endpoint-* instead.

A Sysmon event, field by field

Sysmon Event ID 1, process creation, is the one you'll read more than any other:

event.code: "1" process.name: "powershell.exe" process.command_line: "powershell.exe -enc <base64>" process.parent.name: "winword.exe" process.parent.command_line: ""WINWORD.EXE" /n invoice_macro.docm" user.name: "jdoe"

The pair that matters most here is process.name and process.parent.name together, not either alone. powershell.exe running by itself tells you almost nothing, it runs constantly for entirely normal reasons. powershell.exe with parent.name: winword.exe is a different story: Word does not normally launch PowerShell. That parent-child relationship is the actual signal, and it's why Sysmon logs the full process tree instead of just the process that ran. command_line is where intent usually shows up directly, an encoded (-enc) PowerShell command is a well-known way to disguise a malicious script as a harmless-looking string.

Read Sysmon process events as a chain, not an isolated fact: what ran, what launched it, and what that launcher itself was doing at the time.

Index: mr-endpoint-*

An auditd event, field by field

Linux's auditd gives you the closest equivalent to the Sysmon example above, tracking process execution through the kernel's own audit framework:

event.action: "executed" event.module: "auditd" process.executable: "/usr/bin/whoami" process.args: ["whoami"] user.name: "jdoe" auditd.data.auid: "1000"

The shape is different from Sysmon but the reading approach is the same. process.executable and process.args tell you what actually ran, the same role process.name and command_line played above. auditd.data.auid, the audit user ID, is worth knowing specifically: it's the original login user, preserved even if the process later changes privilege level, which makes it more reliable for tracing who actually started a chain of activity than a field that could reflect an elevated identity partway through. One real gap worth knowing up front: a bare execution event like this doesn't include a parent-process link the way Sysmon does by default, so tracing lineage on Linux often means correlating this event against the syscall entry immediately preceding it, rather than reading lineage off a single event the way you can with Sysmon.

One more trap worth knowing, from a different auditd context: a file-integrity rule's audit key (the -k tag on the rule that fired) lands in the tags field, not auditd.data.key as ECS convention would suggest. auditd.data.key isn't populated on this platform; tags:"<your-key>" is the query that actually works.

Index: mr-linux-*

A Zeek log line, field by field

Zeek's DNS log for a single query looks like this:

query: "a8f3e91c2b7d4f0e.attacker-c2.net" qtype_name: "TXT" id.orig_h: "10.1.10.13" proto: "udp"

Read this one differently than the endpoint events above, because there's no process or user attached, just traffic. query is the actual query, and the shape of it matters as much as the content: a long, effectively random-looking subdomain is not what a normal DNS lookup looks like, real domains are short and pronounceable. qtype_name: TXT is worth noticing on its own: TXT records carry more data than a standard A record, which is exactly why they're disproportionately abused for tunneling. id.orig_h tells you which host on your network actually made the query, that's your starting point for further investigation.

Network events reward pattern recognition over reading any single line closely: one query like this means little, a hundred of them from the same host in a short window means a great deal.

Index: mr-zeek-*

A Suricata alert, field by field

Where Zeek gives you passive metadata to hunt through, Suricata gives you a signature match, a direct alert the moment traffic hits a known-bad pattern:

event_type: "alert" alert.signature: "ET TROJAN Suspicious DNS Query to Tunneling Domain" alert.severity: 1 src_ip: "10.1.10.13" dest_ip: "203.0.113.44" dest_port: 443

Read this one starting from alert.signature, not the network fields, since the signature is the entire reason this event exists: Suricata matched traffic against a specific rule, and the signature name usually tells you in plain language what that rule looks for. severity, on a 1 to 3 scale where lower is more severe, is your first triage signal before you look at anything else. The src_ip/dest_ip/dest_port fields tell you exactly what traffic tripped it, the same role they'd play in any network event, but here they're confirming a specific match rather than something you have to notice yourself. That's the practical difference from Zeek: a Suricata alert already did the pattern-matching for you, so your job shifts from finding the needle to confirming it's real and figuring out what to do about it.

Index: mr-suricata-* (the same raw index carries both the alert doc above and plain connection-level metadata for the same traffic: one index, two document shapes).

What to look for, regardless of format

Every telemetry source you'll encounter has its own field names and its own quirks, but the same handful of questions apply to all of them: What actually happened (the event type itself)? Who or what triggered it (a user, a process, a host)? What's the relationship to whatever came immediately before it (a parent process, a preceding request)? And does this match a pattern you'd expect from this specific account or host, or does it stand out?

That last question is the one that actually takes practice. Nothing in this page substitutes for spending real time in the data. It's meant to get you past the format itself so the actual investigative thinking can start sooner.

Where to go from here

Reading an individual event is the foundation. Using Elastic Security walks through the interface itself: how to actually find events like these, filter and pivot between them, and build the kind of query that turns "I know what this field means" into "I can find every event where it looks like this."

Where to go from here