Variable Within Yara L 2.0

 

 

I'm currently building a detection that needs to extract data from one field and pass it to a variable to match events for that particular user over 30 days and add the user to the outcome section.
Essentially this rule should look for LDAP users who have not received vault temp credits over the last 30 days. 

here's the error message 

semantic analysis: match variable event is not assigned to an event field

 

rule auth0_anomaly_ldap_vault_creds { 

  events:
    // Retrieve all Auth0 events regarding the issuance of vault temp creds for ldap users
    $event.metadata.log_type = "AUTH_ZERO"
    $event.principal.hostname = /^Temp Vault Client auth=ldap/

    // Extract LDAP user
     $ldap_user_extract = re.regex($event.principal.hostname, "auth=([^ ]+) expires")
     $ldap_user = $ldap_user_extract
     
  match:
   $ldap_user over 30d   
    
  outcome:
    // Alert Meta
    $alert_severity = array_distinct("HIGH")

    // Alert Details
    $principal_ip = array_distinct($event.principal.ip)
    $auth0_event_type = array_distinct($event.metadata.product_event_type)
    $auth0_signup_email = array_distinct($event.additional.fields["email"])
    $auth0_user_id = array_distinct($event.target.user.userid)
    $auth0_user_full_name = array_distinct($event.principal.user.userid)
    $user = array_distinct($ldap_user)
    $network_org_name = array_distinct($event.principal.ip_geo_artifact.network.organization_name)
    $source_state = array_distinct($event.principal.location.state)
    $source_country = array_distinct($event.principal.location.country_or_region)
    $user_agent = array_distinct($event.network.http.user_agent)
    $referrer = array_distinct($event.network.http.referral_url)
    $principal_ip_asn = array_distinct($event.principal.ip_geo_artifact.network.asn)

    // Alert Risk Score
    $risk_score = max(
        // Base score for High Severity
        75 + 
        // Increase Risk if SRE, CloudOps, or IT Support
        if ( $event.principal.user.department = "IT Technical Operations", 20) +
        if ( $event.principal.user.department = "IT Support", 10) +
        // Increase Risk in cases of elevated Risk_Level (Okta Logs)
        if ( $event.security_result.outcomes["Risk_Level"] = "MEDIUM" nocase, 10) +
        if ( $event.security_result.outcomes["Risk_Level"] = "HIGH" nocase, 20) +
        // Increase Risk if an Identity Threat is detected (Okta Logs)
        if ( $event.security_result.outcomes["threatSuspected"] = "true" nocase, 10) +
        // Increase Risk if user is an Admin or Delegated Admin
        if ( $event.target.user.attribute.labels["is_admin"] = "true", 10) +
        if ( $event.target.user.attribute.labels["is_delegated_admin"] = "true", 10)
    )

  condition:
    $event
}

 

 

 

Solved Solved
0 6 869
2 ACCEPTED SOLUTIONS

There are a couple of syntax issues here that I'd like to call out.

Line 9 is using the regex function which would be evaluating if the field contains a regex match to what you are looking for. It should not have a placeholder variable associated with it. I mean it could be you are getting a true/false, that is does it match or doesn't it.
Line 10 has a placeholder variable written to another placeholder variable which isn't allowed as match variables need to be associated with a field. I think in this specific area would want another line of criteria that is creating the $ldap_user placeholder variable but using the re.capture function to grab the value you want (which can then be used for the match variable).
Finally, the match variable accepts values over a 2 day window. The match is taking all events that meet the criteria in the events section and aggregates them based on the match variables(s) across a time range of 1 minute to 2 days.

Looking back over 30 days is more of a search function at the moment, though with some of the work we have underway, we may have some other ways to solve for things like this.

If you are looking for additional help on rule writing in Chronicle, here are some additional resources to assist.
Video shorts on tips when building rules: https://www.googlecloudcommunity.com/gc/Chronicle-Best-Practices/tkb-p/chronicle-best-practices
New to Chronicle Blog Series (new posts coming soon to SecOpsCommunity): https://chronicle.security/blog/?filters=new-to-chronicle-series

 

View solution in original post

The maximum time window within a match statement is 48 hours, therefore creating a rule to detect this (if you are trying to capture an even extended period of time) is not currently feasible unfortunately.

However, if you are happy with matching over a 48 hour window, then this modification may work?

rule auth0_anomaly_ldap_vault_creds {
 meta:
   author = "Ayman C"

 events:
    // Retrieve all Auth0 events regarding the issuance of vault temp creds for ldap users
    $event.metadata.log_type = "AUTH_ZERO"
    $event.principal.hostname = /^Temp Vault Client auth=ldap/

    // Extract LDAP user
     $ldap_user_extract = re.capture($event.principal.hostname, "auth=([^ ]+) expires")
     
  match:
   $ldap_user_extract over 48h  
    
  outcome:
    // Alert Meta
    $alert_severity = array_distinct("HIGH")

    // Alert Details
    $principal_ip = array_distinct($event.principal.ip)
    $auth0_event_type = array_distinct($event.metadata.product_event_type)
    $auth0_signup_email = array_distinct($event.additional.fields["email"])
    $auth0_user_id = array_distinct($event.target.user.userid)
    $auth0_user_full_name = array_distinct($event.principal.user.userid)
    $network_org_name = array_distinct($event.principal.ip_geo_artifact.network.organization_name)
    $source_state = array_distinct($event.principal.location.state)
    $source_country = array_distinct($event.principal.location.country_or_region)
    $user_agent = array_distinct($event.network.http.user_agent)
    $referrer = array_distinct($event.network.http.referral_url)
    $principal_ip_asn = array_distinct($event.principal.ip_geo_artifact.network.asn)

    // Alert Risk Score
    $risk_score = max(
        // Base score for High Severity
        75 + 
        // Increase Risk if SRE, CloudOps, or IT Support
        if ( $event.principal.user.department = "IT Technical Operations", 20) +
        if ( $event.principal.user.department = "IT Support", 10) +
        // Increase Risk in cases of elevated Risk_Level (Okta Logs)
        if ( $event.security_result.outcomes["Risk_Level"] = "MEDIUM" nocase, 10) +
        if ( $event.security_result.outcomes["Risk_Level"] = "HIGH" nocase, 20) +
        // Increase Risk if an Identity Threat is detected (Okta Logs)
        if ( $event.security_result.outcomes["threatSuspected"] = "true" nocase, 10) +
        // Increase Risk if user is an Admin or Delegated Admin
        if ( $event.target.user.attribute.labels["is_admin"] = "true", 10) +
        if ( $event.target.user.attribute.labels["is_delegated_admin"] = "true", 10)
    )

  condition:
    $event
}

 

View solution in original post

6 REPLIES 6

I think the problem might be having the "$event" variable in the match section. 

The event variables are not allowed in the match condition. Here in the above example, since the rule is triggered in a single event.

I receive this error when removing $event from the match section. It seems
its not passing the regex data into the variable

There are a couple of syntax issues here that I'd like to call out.

Line 9 is using the regex function which would be evaluating if the field contains a regex match to what you are looking for. It should not have a placeholder variable associated with it. I mean it could be you are getting a true/false, that is does it match or doesn't it.
Line 10 has a placeholder variable written to another placeholder variable which isn't allowed as match variables need to be associated with a field. I think in this specific area would want another line of criteria that is creating the $ldap_user placeholder variable but using the re.capture function to grab the value you want (which can then be used for the match variable).
Finally, the match variable accepts values over a 2 day window. The match is taking all events that meet the criteria in the events section and aggregates them based on the match variables(s) across a time range of 1 minute to 2 days.

Looking back over 30 days is more of a search function at the moment, though with some of the work we have underway, we may have some other ways to solve for things like this.

If you are looking for additional help on rule writing in Chronicle, here are some additional resources to assist.
Video shorts on tips when building rules: https://www.googlecloudcommunity.com/gc/Chronicle-Best-Practices/tkb-p/chronicle-best-practices
New to Chronicle Blog Series (new posts coming soon to SecOpsCommunity): https://chronicle.security/blog/?filters=new-to-chronicle-series

 

Thanks for the reply @jstoner 

I'm trying to create an anomaly-based threat detection.  The $event.principal.hostname full event looks like this "Temp Vault Client auth=ldap-exampleuser expires on: Jan 27 2024 20:17:49". 

This variable $ldap_user_extract = re.regex($event.principal.hostname, "auth=([^ ]+) expires") is supposed to pull ldap-exampleuser from the event and pass it to the variable, in which it is supposed to check to see if this user has created an event in $event.principal.hostname within a certain amount of days. If a user has triggered the alert after a certain amount of days I would like to be notified.

Is this possible in chronicle ?

 

The maximum time window within a match statement is 48 hours, therefore creating a rule to detect this (if you are trying to capture an even extended period of time) is not currently feasible unfortunately.

However, if you are happy with matching over a 48 hour window, then this modification may work?

rule auth0_anomaly_ldap_vault_creds {
 meta:
   author = "Ayman C"

 events:
    // Retrieve all Auth0 events regarding the issuance of vault temp creds for ldap users
    $event.metadata.log_type = "AUTH_ZERO"
    $event.principal.hostname = /^Temp Vault Client auth=ldap/

    // Extract LDAP user
     $ldap_user_extract = re.capture($event.principal.hostname, "auth=([^ ]+) expires")
     
  match:
   $ldap_user_extract over 48h  
    
  outcome:
    // Alert Meta
    $alert_severity = array_distinct("HIGH")

    // Alert Details
    $principal_ip = array_distinct($event.principal.ip)
    $auth0_event_type = array_distinct($event.metadata.product_event_type)
    $auth0_signup_email = array_distinct($event.additional.fields["email"])
    $auth0_user_id = array_distinct($event.target.user.userid)
    $auth0_user_full_name = array_distinct($event.principal.user.userid)
    $network_org_name = array_distinct($event.principal.ip_geo_artifact.network.organization_name)
    $source_state = array_distinct($event.principal.location.state)
    $source_country = array_distinct($event.principal.location.country_or_region)
    $user_agent = array_distinct($event.network.http.user_agent)
    $referrer = array_distinct($event.network.http.referral_url)
    $principal_ip_asn = array_distinct($event.principal.ip_geo_artifact.network.asn)

    // Alert Risk Score
    $risk_score = max(
        // Base score for High Severity
        75 + 
        // Increase Risk if SRE, CloudOps, or IT Support
        if ( $event.principal.user.department = "IT Technical Operations", 20) +
        if ( $event.principal.user.department = "IT Support", 10) +
        // Increase Risk in cases of elevated Risk_Level (Okta Logs)
        if ( $event.security_result.outcomes["Risk_Level"] = "MEDIUM" nocase, 10) +
        if ( $event.security_result.outcomes["Risk_Level"] = "HIGH" nocase, 20) +
        // Increase Risk if an Identity Threat is detected (Okta Logs)
        if ( $event.security_result.outcomes["threatSuspected"] = "true" nocase, 10) +
        // Increase Risk if user is an Admin or Delegated Admin
        if ( $event.target.user.attribute.labels["is_admin"] = "true", 10) +
        if ( $event.target.user.attribute.labels["is_delegated_admin"] = "true", 10)
    )

  condition:
    $event
}

 

Thanks, I assumed that this wouldnt be possible. I looked into the context awareness feature and didnt seem to be helpful either