Study guide

9.3 Event Correlation Rules with Event Query Language (EQL)

Elastic Certified SIEM Analyst Exam

Track your progress as you read

Finished sections get a check mark.

1 Chapter 1: Exam Overview & Study Strategy

1.1 Elastic Certified SIEM Analyst Exam Facts, Objectives & Study Plan

2 Chapter 2: Elastic Stack Architecture & SIEM Foundations

2.1 Elastic Stack Architecture for Security Operations 2.2 Telemetry Ingestion Architecture & Data Pipelines 2.3 Security Data Storage, Data Streams & ILM

3 Chapter 3: Elastic Common Schema (ECS) & Ingestion Normalization

3.1 ECS Structure, Core Principles & Essential Field Sets 3.2 Ingest Pipelines, Processors & Normalization Workflows 3.3 Fleet Server & Elastic Agent Integration Management

4 Chapter 4: Discover, Data Views & Security Query Languages

4.1 Kibana Discover, Security Data Views & Runtime Fields 4.2 Kibana Query Language (KQL) & Lucene for SecOps 4.3 ES|QL for Multi-Stage Security Analysis

5 Chapter 5: Security Visualizations & Threat Analytics

5.1 Metric, Aggregation & Histogram Visualizations for SOC 5.2 Data Tables, Heatmaps & Specialized Security Charts 5.3 Elastic Maps & Geospatial Telemetry Analysis

6 Chapter 6: Kibana Lens for Security Workflows

6.1 Lens Architecture & Multi-Layer Telemetry Visualizations 6.2 Lens Formulas, Ratios & Anomaly Baseline Metrics 6.3 Operationalizing Lens in SOC Triage & Drilldowns

7 Chapter 7: Security Dashboards & SOC Operations

7.1 Security Dashboard Architecture & SOC Layout Design 7.2 Interactive Controls, Time Sync & Cross-Filtering 7.3 Dashboard Exporting, Reporting & Spaces Sharing

8 Chapter 8: The Elastic Security App: Capabilities, Explore & Dashboards

8.1 Security App Capabilities & the Explore Pages (Hosts, Network, Users) 8.2 Monitoring with the Security App Dashboards

9 Chapter 9: Elastic Security Detection Engine & Core Rules

9.1 Detection Engine Architecture & Prebuilt Rule Management 9.2 Custom Query & Threshold Detection Rules 9.3 Event Correlation Rules with Event Query Language (EQL)

10 Chapter 10: Advanced Detection Rules, ML & Rule Tuning

10.1 Threat Intelligence & Indicator Match Rules 10.2 New Terms, ES|QL & Machine Learning Detection Rules 10.3 Detection Rule Tuning, Exceptions & Alert Suppression

11 Chapter 11: Alert Triage, Timelines & Investigation Workflows

11.1 Alert Triage Workflow & the Alert Details Flyout 11.2 Elastic Security Timeline & Timeline Templates 11.3 Visual Event Analyzer & Session View Forensics

12 Chapter 12: Case Management, Integrations & AI Assistant

12.1 Elastic Security Case Management & Triage Workflows 12.2 Case Connectors & External Incident Escalation 12.3 Elastic AI Assistant for Security & Attack Discovery

13 Chapter 13: Security Administration, RBAC & Kibana Spaces

13.1 Kibana Spaces for SOC Multitenancy & Segmentation 13.2 Role-Based Access Control, Feature Privileges & Index Security 13.3 Elastic Defend Administration & Endpoint Policy Controls

14 Chapter 14: End-to-End Threat Hunting & Incident Investigation Capstone

14.1 Hypothesis-Driven Threat Hunting & Baselining in Elastic 14.2 Investigating Lateral Movement & Credential Access Campaigns 14.3 Data Exfiltration, C2 Detection & Incident Reconstruction

9.3 Event Correlation Rules with Event Query Language (EQL)

Key Takeaways Explain This Topic AI

Event Query Language (EQL) is an event-oriented declarative correlation language purpose-built for threat hunting and detecting multi-stage adversary behaviors across chronological event streams.

EQL sequence queries correlate distinct event categories (such as process execution, file creation, registry modification, and network connections) that occur in a specific temporal order within a constrained time span (maxspan).

Correlation keys defined via the by keyword bind events across the sequence to shared entity identities (e.g., by host.id, process.entity_id), ensuring that multi-stage actions are correlated to the exact same host, user, or process lineage.

The until clause acts as a sequence cancellation constraint, terminating correlation matching if a benign or expected intervening event occurs before subsequent attack steps execute.

EQL missing-event clauses (written ![ ... ] and requiring with maxspan) alert when an expected event fails to occur within the sequence window.

Last updated: September 2026

The Necessity of Stateful Correlation in Modern Threat Detection

Single-event detection rules (such as Custom Query and Threshold rules) evaluate documents in isolation. However, sophisticated adversaries rarely execute an entire attack in a single command. Real-world cyber attacks unfold as a progressive sequence of actions across the cyber kill chain: an initial exploit or phishing email triggers process execution, which drops a payload to disk, modifies a persistence registry key, and ultimately establishes an encrypted outbound network beacon to a Command and Control (C2) server.

Evaluating any one of these events in isolation frequently leads to either false positives or false negatives. For example, running powershell.exe is common administrative behavior. Creating a file in C:\Users\Public\ may be benign. Establishing an outbound HTTPS connection is normal web traffic. But when the same PowerShell process drops an executable file and immediately opens an external network socket , the sequence represents a high-confidence attack. Event Query Language (EQL) is Elastic's purpose-built declarative query language designed specifically to correlate chronological event sequences across diverse ECS telemetry categories.

EQL Syntax Fundamentals: Event Types and Conditions

EQL is native to Elasticsearch and operates directly on ECS-compliant documents. Unlike KQL or Lucene, which operate on broad document fields, EQL queries begin by specifying the event category followed by a conditional expression enclosed in a where block: category where condition +-------------------------------------------------------------+

  • | EQL Event Anatomy |
  • | |
  • | process where event.type == "start" and |
  • | process.name == "cmd.exe" and |
  • | process.parent.name == "winword.exe" |
  • | \_____/ \______________________________________/ |
  • | | | |
  • | Event Category Boolean Conditions |
  • +-------------------------------------------------------------+
  • 1. ECS Event Categories

EQL maps directly to the ECS event.category field. Common EQL event categories include:

process : Process creation, start, and termination events ( event.category: "process" ).

file : File creation, modification, and deletion events ( event.category: "file" ).

network : Inbound and outbound network connections, DNS queries, and flow records ( event.category: "network" ).

registry : Windows registry key and value modifications ( event.category: "registry" ).

authentication : User logons, Kerberos ticket grants, and logoffs ( event.category: "authentication" ).

2. Operators and Functions

EQL supports rich comparison operators and string evaluation functions:

Comparison Operators : equality ( == ), inequality ( != ), and relational numeric comparisons (less than, less than or equal to, greater than, greater than or equal to).

  • Logical Operators : and , or , not
  • Set Membership : process.name in ("powershell.exe", "pwsh.exe", "cmd.exe")

Wildcard and Case-Insensitive Matching :

== is an exact, case-sensitive comparison; : is a case-insensitive comparison that also accepts * and ? wildcards: process.name : "POWERSHELL.EXE"

like matches wildcards case-sensitively and like~ case-insensitively: process.command_line like~ "*downloadstring*"

in checks a list case-sensitively and in~ case-insensitively: process.name in~ ("powershell.exe", "pwsh.exe")

Strings : Always use double quotes. EQL does not accept single-quoted strings.

  • String Functions : concat() , stringContains() , length() , startsWith() , endsWith()
  • Sequence Queries and Temporal Constraints: sequence with maxspan

The true power of EQL lies in sequence queries . A sequence specifies two or more chronological steps that must occur in an exact temporal order. sequence with maxspan=5m

  • [process where event.type == "start" and process.name == "mshta.exe"]
  • [network where event.type == "start" and destination.port in (80, 443)]
  • 1. The maxspan Parameter

The maxspan clause defines the maximum allowable time window between the first matching event and the final matching event in the sequence:

Format: maxspan=5m (5 minutes), maxspan=1h (1 hour), maxspan=30s (30 seconds).

If Step 1 occurs at 10:00:00 and Step 2 occurs at 10:06:00 with maxspan=5m , no alert is generated because the elapsed time (6 minutes) exceeds the constraint.

2. Strict Chronological Ordering

EQL enforces temporal ordering based on @timestamp , with an optional tiebreaker field (such as event.sequence ) set in the rule's EQL settings for events with identical timestamps. In the sequence above, the network event must occur after the process start event. If the network event occurred at 10:00:00 and mshta.exe started at 10:01:00 , the sequence does not match.

Correlation Keys: The by Keyword and Entity Binding

In an enterprise generating millions of events across thousands of endpoints, simply verifying that Step 1 and Step 2 occurred within 5 minutes across the organization is insufficient. An mshta.exe process executing on Workstation A and a network connection occurring on Server B within 5 minutes are completely unrelated.

EQL solves this using correlation keys defined via the by keyword. Correlation keys bind sequence steps to shared entity identifiers: sequence with maxspan=5m

[process where event.type == "start" and process.name == "mshta.exe"] by host.id, process.entity_id

[network where event.type == "start" and destination.port in (80, 443)] by host.id, process.entity_id Timeline:

  • T0: Host A (PID 1024 / mshta.exe) Starts
  • | [Correlation Key: host.id = A, process.entity_id = 1024]
  • v
  • T1: Host B (PID 9988 / curl.exe) Connects Outbound
  • | [Correlation Key: host.id = B, process.entity_id = 9988] -> NO MATCH (Wrong Host/PID)
  • v
  • T2: Host A (PID 2048 / svchost.exe) Connects Outbound
  • | [Correlation Key: host.id = A, process.entity_id = 2048] -> NO MATCH (Wrong PID)
  • v
  • T3: Host A (PID 1024 / mshta.exe) Connects Outbound to Port 443

| [Correlation Key: host.id = A, process.entity_id = 1024] -> EXACT MATCH!

  • v
  • [ ALERT SIGNAL GENERATED: Full Attack Path Correlated ]
  • Why process.entity_id is Mandatory

In Windows and Linux operating systems, OS Process IDs (PIDs) are recycled over time. Furthermore, two different machines frequently run processes with the exact same numerical PID. Elastic Defend generates a globally unique identifier for every running process stored in process.entity_id .

Binding by by host.id, process.entity_id guarantees that the network connection was initiated by the exact same running process instance that spawned mshta.exe on that specific host.

Cross-Field Relationship Binding

Correlation keys are not restricted to identical field names. EQL allows binding parent and child relationships across sequence steps: sequence with maxspan=1m

  • [process where event.type == "start" and process.name == "cmd.exe"] by host.id, process.entity_id
  • [process where event.type == "start" and process.name == "whoami.exe"] by host.id, process.parent.entity_id

Here, the sequence binds the process.entity_id of Step 1 to the process.parent.entity_id of Step 2, mathematically verifying that cmd.exe directly spawned whoami.exe .

  • Real-World Threat Scenarios with EQL
  • Scenario 1: Living off the Land Binaries (LOLBins) & In-Memory Execution

Adversaries frequently use trusted system binaries to download and execute malicious code, bypassing traditional application allow-listing. sequence with maxspan=5m

  • [process where event.type == "start" and
  • process.name in~ ("powershell.exe", "pwsh.exe", "cmd.exe") and
  • process.args in~ ("-enc", "-encodedcommand", "-e")] by host.id, process.entity_id
  • [file where event.action in ("creation", "modification") and
  • file.extension in ("exe", "dll", "vbs", "ps1")] by host.id, process.entity_id
  • [network where event.type == "start" and
  • not cidrmatch(destination.ip, "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16")] by host.id, process.entity_id

Analysis : Detects an encoded PowerShell or command script that drops an executable or script to disk and establishes an outbound non-RFC1918 internet connection, all within 5 minutes and executed by the same process.

Scenario 2: LSASS Memory Dumping for Credential Theft

Adversaries target the Local Security Authority Subsystem Service ( lsass.exe ) to extract plaintext passwords, NTLM hashes, and Kerberos tickets. sequence with maxspan=3m

  • [process where event.type == "start" and
  • process.name in~ ("rundll32.exe", "procdump.exe", "procdump64.exe")] by host.id, process.entity_id
  • [file where event.action in ("creation", "modification") and
  • file.extension in ("dmp", "dump") and
  • file.path : ("*\\AppData\\Local\\Temp\\*", "*\\Users\\Public\\*")] by host.id, process.entity_id

Analysis : Correlates the execution of common memory dumping utilities ( rundll32 calling comsvcs.dll or Sysinternals procdump ) with the creation of a .dmp file in temporary directories.

Scenario 3: Persistence Mechanism Creation via Scheduled Tasks

Adversaries establish persistence by scheduling recurring tasks after staging malicious scripts. sequence with maxspan=10m

  • [file where event.action == "creation" and
  • file.path : "C:\\Users\\*\\AppData\\Roaming\\*.bat"] by host.id
  • [process where event.type == "start" and
  • process.name == "schtasks.exe" and
  • process.args : "/create"] by host.id

Analysis : Correlates the staging of a batch file in user AppData with an immediate schtasks /create invocation on the same host.

Advanced Sequence Modifiers: The until Cancellation Clause

In complex operational environments, a sequence of events might look suspicious only if an expected authorizing or terminating event fails to occur. The until keyword defines a cancellation condition that terminates sequence matching. sequence with maxspan=15m

  • [process where event.type == "start" and process.name == "vpn_client.exe"] by host.id, user.name
  • [network where event.type == "start" and destination.port == 22] by host.id, user.name
  • until
  • [authentication where event.action == "mfa_success"] by host.id, user.name

How until Operates:

If vpn_client.exe starts, the Detection Engine enters a pending sequence state for that (host.id, user.name) tuple.

If an mfa_success authentication event occurs before the network connection to port 22, the pending sequence state is immediately discarded and reset .

If the network connection occurs without any intervening MFA validation within 15 minutes, the sequence completes and generates an alert.

Operational Benefit : Drastically reduces false positives by factoring in expected administrative validation steps.

EQL Missing Events: Detecting Non-Occurrences

Traditional detection rules identify when a bad event happens. EQL missing event clauses detect when an expected event does not happen inside a time-bounded sequence. Prefix a clause with ! : sequence by host.name, user.name with maxspan=5s

  • [ authentication where event.code : "4624" ]
  • ![ authentication where event.code : "4647" ]

This example from Elastic's EQL reference finds logons that are not followed by a logoff within 5 seconds. The rules are:

with maxspan is mandatory whenever a sequence contains a missing-event clause.

Missing-event clauses can appear at the beginning, in the middle, or at the end of a sequence, and a sequence can have several, but it needs at least one positive clause.

Event correlation rules support this syntax, so you can alert on absences directly.

SecOps Use Cases for Missing-Event Sequences:

Endpoint Tampering : A security service stops and is not restarted within a few minutes: sequence by host.id with maxspan=5m

  • [process where event.type == "end" and process.name : "elastic-agent.exe"]
  • ![process where event.type == "start" and process.name : "elastic-agent.exe"]

Backup Pipeline Failure : A snapshot job starts, but no completion event follows within the expected window.

Missing-event sequences give proactive alerting on stealthy defense evasion, such as adversaries terminating logging daemons or suppressing reporting agents.

EQL Syntax and Construction Reference

The following reference table summarizes the essential syntax elements and keywords of Event Query Language in Elastic Security:

EQL Construct Syntax Example Behavioral Function SecOps Detection Application

Event Query process where event.type == "start" Evaluates single-event categories Baseline signature detection for malicious utilities.

sequence sequence with maxspan=5m [step1] [step2] Chronological multi-event correlation Multi-stage attack chain tracking (e.g. drop + execute).

maxspan with maxspan=10m Defines maximum duration between steps Restricts correlation window to realistic attack speeds.

by by host.id, process.entity_id Binds steps to shared entity keys Eliminates cross-host and cross-process false matches.

until until [event where condition] Cancels pending sequence match Suppresses alerts if authorized or remediating actions occur.

in process.name in ("cmd.exe", "pwsh.exe") Set membership matching Efficiently matches multiple authorized or suspicious binaries.

: / like~ / in~ file.path : "*\\Temp\\*" Case-insensitive match; : and like~ accept wildcards Flexible path matching across heterogeneous OS environments.

![ ] ![process where event.type == "start"] Missing event (requires with maxspan ) Alerts when an expected event never arrives.

cidrmatch not cidrmatch(destination.ip, "10.0.0.0/8") Subnet membership evaluation Distinguishes internal lateral movement from external C2.

Loading diagram... EQL Multi-Stage Attack Sequence Correlation with Entity Binding