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 conditionsrequire 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 conditionsallow 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.

