Events section syntax
The events
section of a YARA-L query is required for rules, search, and dashboards and must immediately follow the meta
section in a rule. It defines what kind of events the query should be looking for and what specific attributes those events should possess to be considered relevant for a potential detection.
In rules and some more complex search and dashboard queries you can use event variables. Event variables represent a specific event or a group of events that match certain criteria. To use event variables you add the variable, such as $e. as a prefix to all of the events in the events section of your query. You can then use that variable in other sections of the query to reference back to those groups of events.
Define events section
In the events
section, you use event variables to define what types of events you want to filter. Queries that are focused on only one event type, can include a single event variable, such as:
events:
$e.metadata.event_type = "USER_LOGIN" // 'e' is the common convention for a single event
Queries that require correlation between two or more distinct types of events (such as a user login followed by a file modification), require a variable for each type of event:
events:
$login.metadata.event_type = "USER_LOGIN" // Event 1: User Login
$file_op.metadata.event_type = "FILE_MODIFICATION" // Event 2: File Modification
Once an event variable is declared, you use it as a prefix to access specific fields from that event type. For example, the following event
section filters failed login events from Okta:
events:
$e.metadata.vendor_name = "Okta"
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"
Variables are fundamental to writing YARA-L queries, especially for complex multi-event correlation. They are used to reference events, capture field values, group events over time, and output information in detections. All variables in YARA-L are prefixed with $
.
When a variable is used, the variable must be declared through variable declaration. If a variable is used without any declaration, it is regarded as a compilation error. For variable declarations, use the following syntax:
<EVENT_FIELD> = <VAR>
<VAR> = <EVENT_FIELD>
Both are equivalent, as shown in the following examples:
$e.source.hostname = $hostname
$userid = $e.principal.user.userid
This declaration indicates that the variable represents the specified field for the event variable. When the event field is a repeated field, the match variable can represent any value in the array. It is also possible to assign multiple event fields to a single match or placeholder variable. This is a transitive join condition.
For example, the following:
$e1.source.ip = $ip
$e2.target.ip = $ip
Are equivalent to:
$e1.source.ip = $ip
$e1.source.ip = $e2.target.ip
The events
section of a query can include event variables and placeholder variables. You can also define match
variables and outcome
variables to be used in the optional match
and outcome
sections of the query.
For more information about variables, see Expressions, operators, and other constructs.
Event variables are used to represent a specific event or a group of events that match certain criteria, such as user login success or failure. They act as logical groupings of filters and are prefixed with $e
.
Their role in a query is to filter the incoming log data (UDM events) to a relevant set. Each line of criteria in the events
section is tied to an event variable.
In this example rule, we want to find failed logins from a new location:
rule failed_logins_from_new_location
{
meta:
author = "Security Team"
description = "Detects multiple failed logins for a user from a new, never-before-seen IP address within 10 minutes."
severity = "HIGH"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"
$user = $e.target.user.userid
$ip = $e.principal.ip
condition:
#e >= 5
}
The events
section defines the variables to be tracked: user logins, failed user logins (event variables) user and ip (placeholder variables):
events:
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"
$user = $e.target.user.userid
$ip = $e.principal.ip
match:
$userid over 10m
condition:
#e1 >= 5
In the condition
section, you can refer to event variables to define the match criteria. For example, you can specify that a match occurs whenever a single event described by the event variable is found, such as $e1
. Or, a match only occurs if a specified count of events (matching the event variable) are found, such as #e1 >= 5
.
You can also specify multiple event variables in the condition. For example, a match can be defined to occur only if events that look like $e1
and $e2
, where both must occur.
Placeholder variables
Placeholder variables capture a specific value from a UDM field so that it can be used for correlation or matching across different events, such as who performed an action ($user
) or where an action happened ($hostname
). They allow you to define common linkage points for multi-event, and are declared by equating them to a UDM field.
A placeholder variable that finds the number of failed logins that share a userid or source IP address might look like this:
$user = $e.target.user.userid
$ip = $e.principal.ip
For more information, see Variables.
Event variable filters
An event variable filter is a condition applied directly to an event variable to refine the events it includes. These filters are typically expressed as comparisons or checks against the values of UDM fields associated with that event variable.
A boolean expression that acts on a single event variable is considered a filter.
Example: event variable filter
rule ExampleRule { meta: author = "user@example.com" events: $e.metadata.event_type = "NETWORK_DNS" // This is an event variable filter $e.principal.hostname = "malicious_host" // This is another event variable filter condition: $e }
where:
$e
is an event variable.- $e.metadata.event_type = "NETWORK_DNS" is an event variable filter that ensures the event represented by
$e
has an event_type of "NETWORK_DNS". - $e.principal.hostname = "malicious_host" is another event variable filter that further refines
$e
to include only events where the principal.hostname is "malicious\_host".
Event variable joins
Variables are joined in YARA-L to establish a common point of reference, such as a specific hostname or user ID, between different events. All event variables used in the query must be joined with every other event variable in either of the following ways:
Directly through an equality comparison between event fields of the two joined event variables (the expression must not include arithmetic), such as
$e1.field = $e2.field
Indirectly through a transitive join involving only an event field. The expression must not include arithmetic.
For more information, see Multiple event rules.
Examples: valid and invalid event variable joins
Valid events sections
Assuming $e1
, $e2
, and $e3
are used in the query, the following events
sections are valid:
events: $e1.principal.hostname = $e2.src.hostname // $e1 joins with $e2 $e2.principal.ip = $e3.src.ip // $e2 joins with $e3
events: // $e1 joins with $e2 using function to event comparison re.capture($e1.src.hostname, ".*") = $e2.target.hostname
events:
// $e1 joins with $e2 using an or
expression
$e1.principal.hostname = $e2.src.hostname
or $e1.principal.hostname = $e2.target.hostname
or $e1.principal.hostname = $e2.principal.hostname
events: // all of $e1, $e2 and $e3 are transitively joined using the placeholder variable $ip $e1.src.ip = $ip $e2.target.ip = $ip $e3.about.ip = $ip
events: // $e1 and $e2 are transitively joined using function to event comparison re.capture($e2.principal.application, ".*") = $app $e1.principal.hostname = $app
Note: If your sole join condition is an or
chain, a function to event
comparison, or a combination of both, then the rule may perform poorly.
Invalid events sections
Assuming $e1
, $e2
, and $e3
are used in the rule, the following are examples of invalid events sections:
events: // Event to arithmetic comparison is an invalid join condition for $e1 and $e2. $e1.principal.port = $e2.src.port + 1
events: $e1.src.ip = $ip $e2.target.ip = $ip $e3.about.ip = "192.1.2.0" //$e3 is not joined with $e1 or $e2.
events: $e1.src.port = $port // Arithmetic to placeholder comparison is an invalid transitive join condition. $e2.principal.port + 800 = $port
What's next
Additional information
- Expressions, operators, and constructs used in YARA-L 2.0
- Functions in YARA-L 2.0
- Build composite detection rules
- Examples: YARA-L 2.0 queries
Need more help? Get answers from Community members and Google SecOps professionals.