Conditions in UDM search and dashboards using YARA-L 2.0
The condition section defines criteria for including data in search results.
These conditions are evaluated against event and placeholder
variables defined in the events section. You can combine these conditions
using the and keyword.
Limitations
Conditions in search have the following limitations:
Required: The
matchsection is mandatory. Alternatively, you can define ungrouped filters directly within theeventssection.Required: Event and placeholder variables must be aggregated within the
conditionsection.Only integer and float comparison expressions are supported. These expressions must have a variable on the left and an integer or float on the right (for example,
#c > 1,$port = 80). Supported operators are<,>, and=.The order of variables and clauses within the
conditionsection doesn't affect the results.To use outcome variables in the
conditionsection, define and aggregate them. You can filter unaggregated outcome variables in theeventssection.Direct mathematical operations with variables are not supported (for example,
#e1 + 5 > 6,$o1.sum($pl) > 0).There are no additional restrictions if the
ORconditions apply to the same base events. The following restrictions apply whenORis used across different events:Nonexistence comparisons are not supported with
OR. For example,math.log($outcome1_sent_bytes) > 5 OR (#placeholder2) < 10is not supported.Non-UDM variables are not supported in
ORclauses that span different events. However,ORis supported within a single event context or when grouped withAND. For example,$entity and ($udm_event_1 or $placeholder_derived_from_udm_event_1). Here's another example,$entity and ($udm_event_1 or $outcome_udm_event_1_bytes > 1000).
Count character (#)
The # character, when preceding an event or placeholder variable name (for
example, #c), represents the number of distinct occurrences of that event or
the number of distinct values satisfying all the conditions in the events
section associated with that variable. For example, #c > 1 implies that the
event or placeholder c must occur more than once.
Sample query:
$e1.principal.hostname = $hostname
$e1.target.hostname = "fedex.com"
$e1.target.port = 3042 // tcp/udp
$e2.principal.hostname = $hostname
$e2.target.hostname = "homedepot.com"
$e2.target.port = 3042 // tcp/udp
match:
$hostname over 1h
condition:
#e1 > 0 or #e2 > 1
Value character ($)
The $ character's function depends on the context.
Outcome variable: When placed before an outcome variable name (for example,
$risk_score), it represents the variable's value.Event or placeholder variable: When placed before an event or placeholder variable name (for example,
$event), it's equivalent to#event > 0and implies that at least one occurrence of that event must exist.
Event and placeholder conditions
You can combine multiple condition predicates for events and placeholder
variables using the and keyword.
or usage example (single event):
condition:
$ph2 and $ph3
Important: When writing logic in the events or condition sections, use
! for negation. Use the not keyword only in the outcome section.
Bounded and unbounded conditions
Event variable conditions can be bounded or unbounded.
Bounded conditions require the associated event variable to exist. This means that at least one occurrence of the event must appear in any detection.
Examples:
$var(equivalent to#var > 0)#var > n(wheren >= 0)#var >= m(wherem > 0)
Sample query:
$e1.principal.hostname = $hostname
$e1.target.hostname = "fedex.com"
match:
$hostname over 1h
condition:
#e1 > 0
Unbounded conditions allow the associated event variable to not exist. This means that it is possible that no occurrence of the event appears in a detection. Any reference to fields on the event variable yields a zero value. Use these for non-existence searches.
Examples:
!$var(equivalent to#var = 0)#var >= 0#var < n(wheren > 0)#var <= m(wherem >= 0)
Sample query:
$e1.principal.hostname = $hostname
$e1.target.hostname = "fedex.com"
$e1.target.port = 3042 // tcp/udp
match:
$hostname over 1h
outcome:
$bytes_sent = sum($e1.network.sent_bytes)
condition:
$bytes_sent >= 0
Note: For non-existence search queries (using unbounded conditions), the detection engine adds a 1-hour delay to the expected latency.
Search queries with unbounded conditions must meet the following criteria:
At least one UDM event must have a bounded condition; that is, at least one UDM event must exist.
Placeholders with unbounded conditions must associate with at least one bounded UDM event.
Entities with unbounded conditions must associate with at least one bounded UDM event.
Outcome conditions
You can define outcome conditions using outcome variables, and combine them with
logical operators (and, or, not). The comparison syntax depends on the
outcome variable's data type.
- integer and float: Use
=,>,>=,<,<=,!=(for example,$risk_score > 10,$risk_score <= 5.5). - string: Use
=or!=(for example,$severity = "HIGH"). - list of integers or arrays: Use
arrays.contains()(for example,arrays.contains($event_ids, "id_1234")).
Sample query:
$e1.principal.hostname = $hostname
$e1.target.hostname = "fedex.com"
$e1.target.port = 3042 // tcp/udp
match:
$hostname over 1h
outcome:
$bytes_sent = sum($e1.network.sent_bytes)
condition:
$e1
N of X conditions in UDM search
UDM search conditions support "N of X" syntax, which gives a flexible evaluation of
multiple criteria. This syntax lets you specify that a condition is met if N
(a specific number) of X (a list of boolean expressions) evaluate to true.
Example: Consider a scenario where you want to identify processes exhibiting several suspicious behaviors, but not necessarily all of them, from a predefined list of tags provided by VirusTotal (VT) enrichment. The "N of X" syntax addresses this by letting you specify a minimum number of conditions that must be met.
The following UDM search query looks for processes where at least three of the conditions are true:
$e.metadata.event_type = "PROCESS_LAUNCH"
$e.target.process.file.full_path = $process
match:
$process
outcome:
$first_seen = earliest($e.metadata.event_timestamp)
$last_seen = latest($e.metadata.event_timestamp)
$total_events = count($e.metadata.id)
// Collect all unique tags associated with this process from all its launch events
$tags = array_distinct($e.target.process.file.tags)
condition:
// Trigger if at least 3 of the following conditions (tag checks) are true
3 of [
arrays.contains($tags, "malware"),
arrays.contains($tags, "detect-debug-environment"),
arrays.contains($tags, "checks-disk-space"),
arrays.contains($tags, "checks-cpu-name"),
arrays.contains($tags, "invalid-signature"),
arrays.contains($tags, "self-delete")
]
order:
$total_events desc
ANY of and ALL of operators
ANY of [expressions] evaluates to true if at least one of the listed boolean
expressions is true. ALL of [expressions] requires every listed expression to
be true. Combine these operators with other conditions using keywords like AND.
Example:
$e.metadata.event_type = "PROCESS_LAUNCH"
$e.target.process.file.full_path = $process
match:
$process
outcome:
$first_seen = timestamp.get_timestamp(min($e.metadata.event_timestamp.seconds))
$last_seen = timestamp.get_timestamp(max($e.metadata.event_timestamp.seconds))
$total = count($e.metadata.id)
$tags = array_distinct($e.target.process.file.tags)
$vt_first_seen_time = max(if((timestamp.current_seconds() - $e.target.process.file.first_seen_time.seconds) < 86400, 1 , 0))
$vt_last_analysis_time = max(if((timestamp.current_seconds() - $e.target.process.file.last_analysis_time.seconds) < 86400, 1 , 0))
$vt_last_modification_time = max(if((timestamp.current_seconds() - $e.target.process.file.last_modification_time.seconds) < 86400, 1 , 0))
$vt_last_seen_time = max(if((timestamp.current_seconds() - $e.target.process.file.last_seen_time.seconds) < 86400, 1 , 0))
condition:
3 of [
arrays.contains($tags, "malware"),
arrays.contains($tags, "detect-debug-environment"),
arrays.contains($tags, "checks-disk-space"),
arrays.contains($tags, "checks-cpu-name"),
arrays.contains($tags, "invalid-signature"),
arrays.contains($tags, "self-delete")
]
and ANY of [
$vt_first_seen_time = 1,
$vt_last_analysis_time = 1,
$vt_last_modification_time = 1,
$vt_last_seen_time = 1
]
order:
$total desc
unselect:
$vt_first_seen_time,
$vt_last_analysis_time,
$vt_last_modification_time,
$vt_last_seen_time
Need more help? Get answers from Community members and Google SecOps professionals.