Issue with YARA L

Hi 

I am trying to build the below yara rule and it throws the following error message .

Not sure where i am going wrong . As a work around i do know i can remove the user field and keep it in outcome section but i would like to know if this is feasible 

rule Login_from_BAD_ASN {  

  meta:   
    author = "rahul"
    description = "Triggers an alert when a user login is observed from a BAD ASN(Autonomous System Number ) "
    severity = "Medium"
    priority = "Medium"
    ruleset = "Adversary Behavior: Credential Access" 
    usecase = "Credential Access: Brute Force"
    mitre_tactic = "TA0006"
    mitre_technique = " T1110.001"

  events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.ip = $src_ip
$e.principal.ip_geo_artifact.network.asn = $asn

($e.metadata.product_name = "Fortigate" and
$e.principal.user.userid = $user) or 

($e.metadata.product_name = "Azure AD" and 
$e.target.user.userid =$user) or 

($e.metadata.product_name = "Fireware" and 
$e.principal.user.user_display_name =$user) or 

($e.metadata.product_name = "Office 365" and 
$e.target.user.userid =$user)


//$asn in %Malicious_ASN

match:
$src_ip over 15m

outcome:
$risk_score = 60
$product = array_distinct($e.metadata.product_name)
$source_ip = array_distinct($src_ip)
$user_name = array_distinct($user)
$country = array_distinct($e.principal.location.country_or_region)
$carrier = array_distinct($e.principal.ip_geo_artifact.network.carrier_name)

condition:
$e
}

rahul7514_0-1733232497224.png

 

Solved Solved
0 1 446
1 ACCEPTED SOLUTION

You're getting the error "Placeholder variable user is not assigned to an event field" because the placeholder variable $user is used in the match and outcome sections, but it is only defined within conditional or statements in the events section. This means that $user might not be assigned a value for all events, leading to the error.

Here's a breakdown of the issue and how to fix it:

Problem:

  • Conditional Assignment: The $user variable is assigned a value only when certain conditions based on the product name are met. If an event comes from a product other than "Fortigate", "Azure AD", "Fireware", or "Office 365", the $user variable will not be assigned a value.
  • Use in match and outcome: The rule uses $user in both the match and outcome sections. These sections require all variables to have a defined value for every event that contributes to a match. Because $user might be undefined for some events, the rule engine throws the error.

Solution:

To fix this, you need to ensure that $user is consistently assigned a value for all relevant events, regardless of the product name. Here are two possible approaches:

1. Use a Default Value:

Assign a default value to $user outside the conditional or statements. This ensures it always has a value, even if none of the or conditions are met. For example:

events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.principal.ip = $src_ip
    $e.principal.ip_geo_artifact.network.asn = $asn

    $user = "" // Assign a default empty string value

    ($e.metadata.product_name = "Fortigate" and $e.principal.user.userid = $user) or   
    ($e.metadata.product_name = "Azure AD" and  $e.target.user.userid =$user) or   
    ($e.metadata.product_name = "Fireware" and  $e.principal.user.user_display_name =$user) or   
    ($e.metadata.product_name = "Office 365" and  $e.target.user.userid =$user)

By assigning $user = "", the variable will hold an empty string if none of the product-specific conditions are true.

2. Use strings.coalesce:

The strings.coalesce function returns the first non-null value from a list of arguments. You can use this function to prioritize the user ID fields from different products, ensuring $user always has a value:

events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.principal.ip = $src_ip
    $e.principal.ip_geo_artifact.network.asn = $asn

    $user = strings.coalesce(
        $e.principal.user.userid,  // Fortigate
        $e.target.user.userid,      // Azure AD, Office 365
        $e.principal.user.user_display_name // Fireware
    )

This approach tries to assign the userid from "Fortigate" first. If that's null, it tries the userid from "Azure AD" and "Office 365". If both are null, it uses the user_display_name from "Fireware." This ensures that $user always gets a value from one of the available fields.

Additional Considerations:

  • Log Normalization: Ideally, logs from different sources should be normalized into a consistent format before being ingested into Chronicle. This would make writing rules much simpler and avoid the need for product-specific logic.
  • Unintended Matches: If using the default value approach, be aware that setting $user to an empty string might lead to unintended matches. You might need to adjust your condition or other filtering logic to account for these cases.

By implementing either of these solutions, you ensure that the $user variable is consistently assigned a value, resolving the "Placeholder variable user is not assigned to an event field" error. Choose the approach that best suits your data and rule logic.

View solution in original post

1 REPLY 1

You're getting the error "Placeholder variable user is not assigned to an event field" because the placeholder variable $user is used in the match and outcome sections, but it is only defined within conditional or statements in the events section. This means that $user might not be assigned a value for all events, leading to the error.

Here's a breakdown of the issue and how to fix it:

Problem:

  • Conditional Assignment: The $user variable is assigned a value only when certain conditions based on the product name are met. If an event comes from a product other than "Fortigate", "Azure AD", "Fireware", or "Office 365", the $user variable will not be assigned a value.
  • Use in match and outcome: The rule uses $user in both the match and outcome sections. These sections require all variables to have a defined value for every event that contributes to a match. Because $user might be undefined for some events, the rule engine throws the error.

Solution:

To fix this, you need to ensure that $user is consistently assigned a value for all relevant events, regardless of the product name. Here are two possible approaches:

1. Use a Default Value:

Assign a default value to $user outside the conditional or statements. This ensures it always has a value, even if none of the or conditions are met. For example:

events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.principal.ip = $src_ip
    $e.principal.ip_geo_artifact.network.asn = $asn

    $user = "" // Assign a default empty string value

    ($e.metadata.product_name = "Fortigate" and $e.principal.user.userid = $user) or   
    ($e.metadata.product_name = "Azure AD" and  $e.target.user.userid =$user) or   
    ($e.metadata.product_name = "Fireware" and  $e.principal.user.user_display_name =$user) or   
    ($e.metadata.product_name = "Office 365" and  $e.target.user.userid =$user)

By assigning $user = "", the variable will hold an empty string if none of the product-specific conditions are true.

2. Use strings.coalesce:

The strings.coalesce function returns the first non-null value from a list of arguments. You can use this function to prioritize the user ID fields from different products, ensuring $user always has a value:

events:
    $e.metadata.event_type = "USER_LOGIN"
    $e.principal.ip = $src_ip
    $e.principal.ip_geo_artifact.network.asn = $asn

    $user = strings.coalesce(
        $e.principal.user.userid,  // Fortigate
        $e.target.user.userid,      // Azure AD, Office 365
        $e.principal.user.user_display_name // Fireware
    )

This approach tries to assign the userid from "Fortigate" first. If that's null, it tries the userid from "Azure AD" and "Office 365". If both are null, it uses the user_display_name from "Fireware." This ensures that $user always gets a value from one of the available fields.

Additional Considerations:

  • Log Normalization: Ideally, logs from different sources should be normalized into a consistent format before being ingested into Chronicle. This would make writing rules much simpler and avoid the need for product-specific logic.
  • Unintended Matches: If using the default value approach, be aware that setting $user to an empty string might lead to unintended matches. You might need to adjust your condition or other filtering logic to account for these cases.

By implementing either of these solutions, you ensure that the $user variable is consistently assigned a value, resolving the "Placeholder variable user is not assigned to an event field" error. Choose the approach that best suits your data and rule logic.