Detection rules › YARA-L

YARA-L rules: 1u

AWS IAM Activity From EC2 Instance

#
Severity
high
Type
Alert
Time window
1h
Match by
ip
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Detect AWS IAM activities made by AWS EC2 instances to retain access or escalate privileges.

MITRE ATT&CK Coverage

TacticTechniques
Persistence

Telemetry Coverage

Rule Body

// Copyright 2023 Google LLC. Licensed under Apache-2.0.

rule aws_iam_activity_from_ec2_instance {

  meta:
    author = "Google Cloud Security"
    description = "Detect AWS IAM activities made by AWS EC2 instances to retain access or escalate privileges."
    rule_id = "mr_60c7bb2f-2f02-4ac5-bbe0-ba8be871f3fb"
    rule_name = "AWS IAM Activity From EC2 Instance"
    mitre_attack_tactic = "Persistence"
    mitre_attack_technique = "Account Manipulation"
    mitre_attack_url = "https://attack.mitre.org/techniques/T1098/"
    mitre_attack_version = "v13.1"
    type = "Alert"
    data_source = "AWS CloudTrail"
    platform = "AWS"
    severity = "High"
    priority = "High"

  events:
    $cloudtrail.metadata.vendor_name = "AMAZON"
    $cloudtrail.metadata.product_name = "AWS CloudTrail"
    $cloudtrail.target.application = "iam.amazonaws.com"
    (
    $cloudtrail.metadata.product_event_type = "CreateUser" or
    $cloudtrail.metadata.product_event_type = "AttachUserPolicy" or
    $cloudtrail.metadata.product_event_type = "CreateLoginProfile" or
    $cloudtrail.metadata.product_event_type = "UpdateLoginProfile" or
    $cloudtrail.metadata.product_event_type = "CreateAccessKey" or
    $cloudtrail.metadata.product_event_type = "CreateGroup" or
    $cloudtrail.metadata.product_event_type = "AttachGroupPolicy" or
    $cloudtrail.metadata.product_event_type = "CreateRole" or
    $cloudtrail.metadata.product_event_type = "AttachRolePolicy"
    )
    $cloudtrail.security_result.action = "ALLOW"
    $cloudtrail.principal.ip = $ip
    $cloudtrail.principal.resource.type = "AssumedRole"
    $cloudtrail.principal.user.userid = /\/i-.*$/ //regex to be improved
    re.capture($cloudtrail.principal.user.userid, ":assumed-role/.*/(.*)$") = $instanceId

  match:
    $ip over 1h

  outcome:
    $risk_score = max(35)
    $mitre_attack_tactic = "Persistence"
    $mitre_attack_technique = "Account Manipulation"
    $mitre_attack_technique_id = "T1098"
    $event_count = count_distinct($cloudtrail.metadata.id)
    $network_http_user_agent = array_distinct($cloudtrail.network.http.user_agent)
    $principal_ip = array_distinct($cloudtrail.principal.ip)
    $principal_ip_country = array_distinct($cloudtrail.principal.ip_geo_artifact.location.country_or_region)
    $principal_ip_state = array_distinct($cloudtrail.principal.ip_geo_artifact.location.state)
    $principal_user_display_name = array_distinct($cloudtrail.principal.user.user_display_name)
    $recipient_aws_account_id = array_distinct($cloudtrail.additional.fields["recipientAccountId"])
    $aws_region = array_distinct($cloudtrail.principal.location.name)
    $target_resource_name = array_distinct($cloudtrail.target.resource.name)
    $target_resource_product_object_id = array_distinct($cloudtrail.target.resource.product_object_id)
    $ec2_instance_id = array_distinct($instanceId)

  condition:
    $cloudtrail
}

YARA-L Rule Structure

Condition

Fires when at least one $cloudtrail event in the 1h window.

Events

$cloudtrail

  • target.application = "iam.amazonaws.com"
  • metadata.product_event_type is one of:
    • CreateUser
    • AttachUserPolicy
    • CreateLoginProfile
    • UpdateLoginProfile
    • CreateAccessKey
    • CreateGroup
    • AttachGroupPolicy
    • CreateRole
    • AttachRolePolicy
  • security_result.action = "ALLOW"
  • principal.resource.type = "AssumedRole"
  • principal.user.userid matches "\/i-.*$"

Match and Correlation

Match key
$ip (principal.ip)
Within
1h

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_scoremax(35)
event_countcount_distinct($cloudtrail.metadata.id)
network_http_user_agentarray_distinct($cloudtrail.network.http.user_agent)
principal_iparray_distinct($cloudtrail.principal.ip)
principal_ip_countryarray_distinct($cloudtrail.principal.ip_geo_artifact.location.country_or_region)
principal_ip_statearray_distinct($cloudtrail.principal.ip_geo_artifact.location.state)
principal_user_display_namearray_distinct($cloudtrail.principal.user.user_display_name)
recipient_aws_account_idarray_distinct($cloudtrail.additional.fields["recipientAccountId"])
aws_regionarray_distinct($cloudtrail.principal.location.name)
target_resource_namearray_distinct($cloudtrail.target.resource.name)
target_resource_product_object_idarray_distinct($cloudtrail.target.resource.product_object_id)
ec2_instance_idarray_distinct($instanceId)

GCP Firewall Rule Opened To The World

#
Severity
high
Type
Alert
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Detect when a GCP Firewall rule is opened to the world (0.0.0.0/0) on all protocols.

MITRE ATT&CK Coverage

TacticTechniques
Defense Impairment

Telemetry Coverage

Rule Body

// Copyright 2024 Google LLC. Licensed under Apache-2.0.

 rule gcp_firewall_rule_opened_to_world {

  meta:
    author = "Google Cloud Security"
    description = "Detect when a GCP Firewall rule is opened to the world (0.0.0.0/0) on all protocols."
    rule_id = "mr_340c7a66-56ea-498a-bf00-270e9e61fed0"
    rule_name = "GCP Firewall Rule Opened To The World"
    mitre_attack_tactic = "Defense Evasion"
    mitre_attack_technique = "Impair Defenses"
    mitre_attack_url = "https://attack.mitre.org/techniques/T1562/"
    mitre_attack_version = "v14.1"
    type = "Alert"
    data_source = "GCP Cloud Audit"
    platform = "GCP"
    severity = "High"
    priority = "High"

  events:
    $gcp.metadata.event_type = "RESOURCE_CREATION"
    $gcp.metadata.log_type = "GCP_CLOUDAUDIT"
    $gcp.metadata.product_event_type = /compute.firewalls.insert$/ nocase
    $gcp.metadata.product_name = "Google Compute Engine"
    $gcp.security_result.action = "ALLOW"
    $gcp.target.resource.attribute.labels["source_ranges"] = "0.0.0.0/0"
    $gcp.security_result.detection_fields["allowed_ipprotocol"] = "all"
    $gcp.target.resource.attribute.labels["response_status"] = "RUNNING"

  outcome:
    $risk_score = max(75)
    $mitre_attack_tactic = "Defense Evasion"
    $mitre_attack_technique = "Impair Defenses"
    $mitre_attack_technique_id = "T1562"
    $event_count = count_distinct($gcp.metadata.id)
    $network_http_user_agent = array_distinct($gcp.network.http.user_agent)
    $principal_ip = array_distinct($gcp.principal.ip)
    $principal_ip_country = array_distinct($gcp.principal.ip_geo_artifact.location.country_or_region)
    $principal_ip_state = array_distinct($gcp.principal.ip_geo_artifact.location.state)
    $principal_user_id = $gcp.principal.user.userid
    $principal_user_display_name = $gcp.principal.user.user_display_name
    $target_resource_name = $gcp.target.resource.name
    $event_name = $gcp.metadata.product_event_type

  condition:
    $gcp
}

YARA-L Rule Structure

Condition

Fires when at least one $gcp event.

Events

$gcp RESOURCE_CREATION

  • metadata.log_type = "GCP_CLOUDAUDIT"
  • metadata.product_event_type matches "compute.firewalls.insert$"
  • security_result.action = "ALLOW"
  • target.resource.attribute.labels["source_ranges"] = "0.0.0.0/0"
  • security_result.detection_fields["allowed_ipprotocol"] = "all"
  • target.resource.attribute.labels["response_status"] = "RUNNING"

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_scoremax(75)
event_countcount_distinct($gcp.metadata.id)
network_http_user_agentarray_distinct($gcp.network.http.user_agent)
principal_iparray_distinct($gcp.principal.ip)
principal_ip_countryarray_distinct($gcp.principal.ip_geo_artifact.location.country_or_region)
principal_ip_statearray_distinct($gcp.principal.ip_geo_artifact.location.state)
principal_user_id$gcp.principal.user.userid
principal_user_display_name$gcp.principal.user.user_display_name
target_resource_name$gcp.target.resource.name
event_name$gcp.metadata.product_event_type

GCP Storage Bucket Opened To Public

#
Severity
high
Type
Alert
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Detect when Google Cloud Storage buckets are opened to public by adding allUsers or allAuthenticatedUsers to the access policy.

MITRE ATT&CK Coverage

TacticTechniques
Defense Impairment

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

// Copyright 2024 Google LLC. Licensed under Apache-2.0.

 rule gcp_storage_bucket_opened_to_public {

  meta:
    author = "Google Cloud Security"
    description = "Detect when Google Cloud Storage buckets are opened to public by adding allUsers or allAuthenticatedUsers to the access policy."
    rule_id = "mr_b776abb0-9e7b-444d-ae0f-8a88b5654ded"
    rule_name = "GCP Storage Bucket Opened To Public"
    mitre_attack_tactic = "Defense Evasion"
    mitre_attack_technique = "Impair Defenses"
    mitre_attack_url = "https://attack.mitre.org/techniques/T1562/"
    mitre_attack_version = "v14.1"
    type = "Alert"
    data_source = "GCP Cloud Audit"
    platform = "GCP"
    severity = "High"
    priority = "High"

  events:
    $gcp.metadata.event_type = "USER_RESOURCE_UPDATE_PERMISSIONS"
    $gcp.metadata.log_type = "GCP_CLOUDAUDIT"
    $gcp.metadata.vendor_name = "Google Cloud Platform"
    $gcp.metadata.product_name = "Google Cloud Storage"
    $gcp.metadata.product_event_type = "storage.setIamPermissions"
    $gcp.target.application = "storage.googleapis.com"
    $gcp.security_result.action = "ALLOW"
    $gcp.target.resource.attribute.labels["ser_binding_deltas_action"] = "ADD"
    $gcp.target.resource.attribute.labels["ser_binding_deltas_role"] = /roles\/storage.*/
    $gcp.target.resource.attribute.labels["ser_binding_deltas_member"] = /allUsers|allAuthenticatedUsers/
    $gcp.target.resource.resource_type = "STORAGE_BUCKET"

  outcome:
    $risk_score = max(75)
    $mitre_attack_tactic = "Defense Evasion"
    $mitre_attack_technique = "Impair Defenses"
    $mitre_attack_technique_id = "T1562"
    $event_count = count_distinct($gcp.metadata.id)
    $network_http_user_agent = array_distinct($gcp.network.http.user_agent)
    $principal_ip = array_distinct($gcp.principal.ip)
    $principal_ip_country = array_distinct($gcp.principal.ip_geo_artifact.location.country_or_region)
    $principal_ip_state = array_distinct($gcp.principal.ip_geo_artifact.location.state)
    $principal_user_id = $gcp.principal.user.userid
    $principal_user_display_name = $gcp.principal.user.user_display_name
    $target_resource_name = $gcp.target.resource.name
    $event_name = $gcp.metadata.product_event_type

  condition:
    $gcp
}

YARA-L Rule Structure

Condition

Fires when at least one $gcp event.

Events

$gcp USER_RESOURCE_UPDATE_PERMISSIONS

  • metadata.log_type = "GCP_CLOUDAUDIT"
  • metadata.product_event_type = "storage.setIamPermissions"
  • target.application = "storage.googleapis.com"
  • security_result.action = "ALLOW"
  • target.resource.attribute.labels["ser_binding_deltas_action"] = "ADD"
  • target.resource.attribute.labels["ser_binding_deltas_role"] matches "roles\/storage.*"
  • target.resource.attribute.labels["ser_binding_deltas_member"] matches "allUsers|allAuthenticatedUsers"
  • target.resource.resource_type = "STORAGE_BUCKET"

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_scoremax(75)
event_countcount_distinct($gcp.metadata.id)
network_http_user_agentarray_distinct($gcp.network.http.user_agent)
principal_iparray_distinct($gcp.principal.ip)
principal_ip_countryarray_distinct($gcp.principal.ip_geo_artifact.location.country_or_region)
principal_ip_statearray_distinct($gcp.principal.ip_geo_artifact.location.state)
principal_user_id$gcp.principal.user.userid
principal_user_display_name$gcp.principal.user.user_display_name
target_resource_name$gcp.target.resource.name
event_name$gcp.metadata.product_event_type

Google Workspace Suspicious Login and Google Drive File Share

#
Severity
high
Type
Alert
Time window
1h
Match by
principal_ip, target_userid
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Identifies when a Google Workspace user shares a file on Google Drive after a suspicious login event occurred.

MITRE ATT&CK Coverage

TacticTechniques
Exfiltration

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

// Copyright 2023 Google LLC. Licensed under Apache-2.0.

rule google_workspace_suspicious_login_and_google_drive_file_share {

  meta:
    author = "Google Cloud Security"
    description = "Identifies when a Google Workspace user shares a file on Google Drive after a suspicious login event occurred."
    rule_id = "mr_0ddcbd08-e918-4f7c-918b-3190c8b54ea4"
    rule_name = "Google Workspace Suspicious Login and Google Drive File Share"
    mitre_attack_tactic = "Exfiltration"
    mitre_attack_technique = "Exfiltration Over Web Service"
    mitre_attack_url = "https://attack.mitre.org/techniques/T1567/"
    mitre_attack_version = "v13.1"
    type = "Alert"
    data_source = "Workspace Activity"
    severity = "High"
    priority = "High"

  events:
    // Suspicious Login Event
    $login.metadata.vendor_name = "Google Workspace"
    $login.metadata.product_name = "login"
    $login.metadata.product_event_type = "login_success"
    $login.about.labels["is_suspicious"] = "true"

    // Document Download Event
    $share.metadata.vendor_name = "Google Workspace"
    $share.metadata.product_name = "drive"
    (
        $share.metadata.product_event_type = "change_user_access" or
        $share.metadata.product_event_type = "change_document_visibility" or
        $share.metadata.product_event_type = "change_document_access_scope" or
        $share.metadata.product_event_type = "change_acl_editors"
    )

    // Joining login and download events using userid
    $login.target.user.userid = $share.principal.user.userid

    // Placeholders for match section
    $login.principal.ip = $principal_ip
    $login.target.user.userid = $target_userid

    // First login event occurs later a download event
    $login.metadata.event_timestamp.seconds < $share.metadata.event_timestamp.seconds

  match:
    $target_userid, $principal_ip over 1h

  outcome:

    $risk_score = max(75)
    $mitre_attack_tactic = "Exfiltration"
    $mitre_attack_technique = "Exfiltration Over Web Service"
    $mitre_attack_technique_id = "T1567"
    $event_count = count_distinct($share.metadata.id)
    $product_event_type = array_distinct($share.metadata.product_event_type)
    $userid = array_distinct($share.principal.user.userid)
    $doc_type = array_distinct($share.src.resource.attribute.labels["doc_type"])
    $owner = array_distinct($share.target.resource.attribute.labels["owner"])
    $doc_name = array_distinct($share.target.resource.name)
    $doc_id = array_distinct($share.target.resource.product_object_id)

  condition:
    $login and $share
}

YARA-L Rule Structure

Condition

Fires when at least one $login event in the 1h window and at least one $share event in the 1h window.

Events

$login

  • metadata.product_event_type = "login_success"
  • about.labels["is_suspicious"] = "true"
  • target.user.userid cross_field_compare "share.principal.user.userid"

$share

  • metadata.product_event_type is one of:
    • change_user_access
    • change_document_visibility
    • change_document_access_scope
    • change_acl_editors

Match and Correlation

Order
$login before $share
Match key
$principal_ip (principal.ip), $target_userid (target.user.userid)
Within
1h

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_scoremax(75)
event_countcount_distinct($share.metadata.id)
product_event_typearray_distinct($share.metadata.product_event_type)
useridarray_distinct($share.principal.user.userid)
doc_typearray_distinct($share.src.resource.attribute.labels["doc_type"])
ownerarray_distinct($share.target.resource.attribute.labels["owner"])
doc_namearray_distinct($share.target.resource.name)
doc_idarray_distinct($share.target.resource.product_object_id)

OneLogin User Logins From Multiple Countries

#
Severity
medium
Type
Alert
Time window
1d
Match by
userid
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Detects user logins for the same user from different cities within 24 hours.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

Rule Body

// Copyright 2024 Google LLC. Licensed under Apache-2.0.

rule onelogin_user_logins_from_multiple_countries {

  meta:
    author = "Google Cloud Security"
    description = "Detects user logins for the same user from different cities within 24 hours."
    rule_id = "mr_92eb87fb-0310-460f-9640-8bc0bb87a8a3"
    rule_name = "OneLogin User Logins From Multiple Countries"
    mitre_attack_tactic = "Initial Access"
    mitre_attack_technique = "Valid Accounts: Cloud Accounts"
    mitre_attack_url = "https://attack.mitre.org/techniques/T1078/004/"
    mitre_attack_version = "v15.1"
    type = "Alert"
    data_source = "OneLogin"
    severity = "Medium"
    priority = "Medium"

  events:
    $login.metadata.event_type = "USER_LOGIN"
    $login.metadata.product_name = "ONELOGIN_SSO"
    $login.metadata.vendor_name = "ONELOGIN"
    $login.metadata.product_event_type = "5" //user logged into onelogin
    $login.principal.user.userid = $userid

  match:
    $userid over 24h

  outcome:
      $risk_score = max(
        35 +
        // Unauthorized target geographies
        if($login.principal.ip_geo_artifact.location.country_or_region = "Cuba", 20) +
        if($login.principal.ip_geo_artifact.location.country_or_region = "Iran", 20) +
        if($login.principal.ip_geo_artifact.location.country_or_region = "North Korea", 20) +
        if($login.principal.ip_geo_artifact.location.country_or_region = "Russia", 20) +
        if($login.principal.ip_geo_artifact.location.country_or_region = "Syria", 20)
    )
    $mitre_attack_tactic = "Initial Access"
    $mitre_attack_technique = "Valid Accounts: Cloud Accounts"
    $network_user_agent = array_distinct($login.network.http.user_agent)
    $principal_ip = array_distinct($login.principal.ip)
    $principal_ip_country = array_distinct($login.principal.ip_geo_artifact.location.country_or_region)
    $principal_ip_state = array_distinct($login.principal.ip_geo_artifact.location.state)
    $dc_principal_ip_country = count_distinct($login.principal.ip_geo_artifact.location.country_or_region)
    $principal_user_userid = array_distinct($login.principal.user.userid)
    $principal_user_user_display_name = array_distinct($login.principal.user.user_display_name)
    $target_user_userid = array_distinct($login.target.user.userid)

  condition:
    $login and $dc_principal_ip_country > 1
}

YARA-L Rule Structure

Condition

Fires when at least one $login event in the 24h window and $dc_principal_ip_country > 1.

Events

$login USER_LOGIN

  • metadata.product_event_type = "5"

Match and Correlation

Match key
$userid (principal.user.userid)
Within
1d

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_scoremax( 35 + if($login.principal.ip_geo_artifact.location.country_or_region = "Cuba", 20) + if($login.principal.ip_geo_artifact.location.country_or_region = "Iran", 20) + if($login.principal.ip_geo_artifact.location.country_or_region = "North Korea", 20) + if($login.principal.ip_geo_artifact.location.country_or_region = "Russia", 20) + if($login.principal.ip_geo_artifact.location.country_or_region = "Syria", 20) )
network_user_agentarray_distinct($login.network.http.user_agent)
principal_iparray_distinct($login.principal.ip)
principal_ip_countryarray_distinct($login.principal.ip_geo_artifact.location.country_or_region)
principal_ip_statearray_distinct($login.principal.ip_geo_artifact.location.state)
dc_principal_ip_countrycount_distinct($login.principal.ip_geo_artifact.location.country_or_region)
principal_user_useridarray_distinct($login.principal.user.userid)
principal_user_user_display_namearray_distinct($login.principal.user.user_display_name)
target_user_useridarray_distinct($login.target.user.userid)

Back to all YARA-L rules