Detection rules › YARA-L

YARA-L rules: 2n

AWS Lambda Update Function Code

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

Detects an IAM user attempting to update/modify AWS lambda code.

MITRE ATT&CK Coverage

TacticTechniques
Execution

Telemetry Coverage

Rule Body

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

rule aws_lambda_update_function_code {

  meta:
    author = "Google Cloud Security"
    description = "Detects an IAM user attempting to update/modify AWS lambda code."
    rule_id = "mr_046e8bc7-2d48-4118-ae38-eb095a4333e3"
    rule_name = "AWS Lambda Update Function Code"
    mitre_attack_tactic = "Execution"
    mitre_attack_technique = "Serverless Execution"
    mitre_attack_url = "https://attack.mitre.org/techniques/T1648/"
    mitre_attack_version = "v13.1"
    type = "Alert"
    data_source = "AWS CloudTrail"
    platform = "AWS"
    severity = "Low"
    priority = "Low"

  events:
    $cloudtrail.metadata.vendor_name = "AMAZON"
    $cloudtrail.metadata.product_name = "AWS CloudTrail"
    $cloudtrail.metadata.product_event_type = /UpdateFunctionCode/
    $cloudtrail.security_result.action = "ALLOW"
    $cloudtrail.principal.user.userid = $user_id

  match:
    $user_id over 1h

  outcome:
    $risk_score = max(35)
    $mitre_attack_tactic = "Execution"
    $mitre_attack_technique = "Serverless Execution"
    $mitre_attack_technique_id = "T1648"
    $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)

  condition:
    $cloudtrail
}

YARA-L Rule Structure

Condition

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

Events

$cloudtrail

  • metadata.product_event_type matches "UpdateFunctionCode"
  • security_result.action = "ALLOW"

Match and Correlation

Match key
$user_id (principal.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(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)

Google Workspace Suspicious Login and Google Drive File Download

#
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 downloads a file from 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_download {

  meta:
    author = "Google Cloud Security"
    description = "Identifies when a Google Workspace user downloads a file from Google Drive after a suspicious login event occurred."
    rule_id = "mr_3c55c930-d9be-4d34-a90e-baf92c22ae40"
    rule_name = "Google Workspace Suspicious Login and Google Drive File Download"
    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
    $download.metadata.vendor_name = "Google Workspace"
    $download.metadata.product_name = "drive"
    $download.metadata.product_event_type = "download"

    // Joining login and download events using userid
    $login.target.user.userid = $download.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 < $download.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($download.metadata.id)
    $product_event_type = array_distinct($download.metadata.product_event_type)
    $userid = array_distinct($download.principal.user.userid)
    $doc_type = array_distinct($download.src.resource.attribute.labels["doc_type"])
    $owner = array_distinct($download.target.resource.attribute.labels["owner"])
    $doc_name = array_distinct($download.target.resource.name)
    $doc_id = array_distinct($download.target.resource.product_object_id)

  condition:
    $login and $download
}

YARA-L Rule Structure

Condition

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

Events

$login

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

$download

  • metadata.product_event_type = "download"

Match and Correlation

Order
$login before $download
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($download.metadata.id)
product_event_typearray_distinct($download.metadata.product_event_type)
useridarray_distinct($download.principal.user.userid)
doc_typearray_distinct($download.src.resource.attribute.labels["doc_type"])
ownerarray_distinct($download.target.resource.attribute.labels["owner"])
doc_namearray_distinct($download.target.resource.name)
doc_idarray_distinct($download.target.resource.product_object_id)

Hunt for Office 365 group creation failures

#
Severity
low
Type
hunt
Time window
5m
Match by
user
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Detects when a group is attempted to be created but fails in Office 365. This could be due to insufficient permissions or other errors

Telemetry Coverage

PlatformRecord / event type
Microsoft 365Add group.

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

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

rule o365_group_creation_failure {

  meta:
    author = "Google Cloud Security"
    description = "Detects when a group is attempted to be created but fails in Office 365. This could be due to insufficient permissions or other errors"
    rule_id = "mr_964c36cd-cf07-446d-bc85-68a937d4441a"
    rule_name = "Hunt for Office 365 group creation failures"
    type = "hunt"
    platform = "azure"
    data_source = "o365"
    severity = "Low"
    priority = "Low"

  events:
    $group.metadata.event_type = "GROUP_CREATION"
    $group.metadata.product_event_type = "Add group."
    $group.metadata.product_name = "Office 365"
    $group.metadata.vendor_name = "Microsoft"
    $group.security_result.action = "BLOCK"
    $group.principal.user.userid = $user

  match:
    $user over 5m

  outcome:
    $risk_score = 35
    $event_count = count_distinct($group.metadata.id)
    $security_summary = array_distinct($group.security_result.summary)
    $user_agent = array_distinct($group.network.http.user_agent)
    $target_application = array_distinct($group.target.application)
    //$principal_user_userid = array_distinct($group.principal.user.userid)
    $proposed_group_name = array_distinct($group.target.group.group_display_name)
    $reason = array_distinct($group.target.labels["MethodExecutionResult."])

  condition:
    $group
}

YARA-L Rule Structure

Condition

Fires when at least one $group event in the 5m window.

Events

$group GROUP_CREATION

  • metadata.product_event_type = "Add group."
  • security_result.action = "BLOCK"

Match and Correlation

Match key
$user (principal.user.userid)
Within
5m

Outcome

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

FieldExpression
risk_score35
event_countcount_distinct($group.metadata.id)
security_summaryarray_distinct($group.security_result.summary)
user_agentarray_distinct($group.network.http.user_agent)
target_applicationarray_distinct($group.target.application)
proposed_group_namearray_distinct($group.target.group.group_display_name)
reasonarray_distinct($group.target.labels["MethodExecutionResult."])

Recon Environment Enumeration Network CISA Report

#
Severity
low
Type
hunt
Time window
15m
Match by
hostname
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Detects network enumeration commands as identified in CISA Living off the Land pdf. Alone they may be normal but in concert, they may be worth looking into

MITRE ATT&CK Coverage

References

Telemetry Coverage

Rule Body

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

rule recon_environment_enumeration_network_cisa_report {

  meta:
    author = "Google Cloud Security"
    description = "Detects network enumeration commands as identified in CISA Living off the Land pdf. Alone they may be normal but in concert, they may be worth looking into"
    rule_id = "mr_9ca49a46-fb60-4ada-b722-5714d5cb7f53"
    rule_name = "Recon Environment Enumeration Network CISA Report"
    type = "hunt"
    platform = "Windows"
    data_source = "microsoft sysmon, windows event logs"
    tactic = "TA0007"
    technique = "T1016"
    reference = "https://media.defense.gov/2023/May/24/2003229517/-1/-1/0/CSA_Living_off_the_Land.PDF"
    severity = "Low"
    priority = "Low"

  events:
    (
        $process.metadata.event_type = "PROCESS_LAUNCH" and
        (
            // cisa report referenced cmd /c in their report throughout, can filter this in/out for tuning as needed
            re.regex($process.target.process.command_line, `(|cmd.*/c).*arp.*-a`) nocase or
            re.regex($process.target.process.command_line, `(|cmd.*/c).*curl.*www.ip-api.com`) nocase or
            // the following line is a broader look at dnscmd /enumrecords not explicitly called out in the report can comment out if not needed
            //re.regex($process.target.process.command_line, `(|cmd.*/c).*dnscmd.*/enumrecords`) nocase or
            re.regex($process.target.process.command_line, `(|cmd.*/c).*dnscmd.*/enumrecords.*/zone`) nocase or
            re.regex($process.target.process.command_line, `(|cmd.*/c).*dnscmd.*/enumzones`) nocase or
            re.regex($process.target.process.command_line, `(|cmd.*/c).*dnscmd.*/enumrecords.*/additional`) nocase or
            re.regex($process.target.process.command_line, `(|cmd.*/c).*ipconfig.*/all`) nocase or
            re.regex($process.target.process.command_line, `(|cmd.*/c).*netsh.*interface.*firewall.*show`) nocase or
            re.regex($process.target.process.command_line, `(|cmd.*/c).*netsh.*interface.*portproxy.*show`) nocase or
            re.regex($process.target.process.command_line, `(|cmd.*/c).*netsh.*interface.*portproxy.*show.*v4tov4`) nocase or
            re.regex($process.target.process.command_line, `(|cmd.*/c).*netsh.*firewall.*show`) nocase or
            re.regex($process.target.process.command_line, `(|cmd.*/c).*netsh.*portproxy.*show.*v4tov4`) nocase or
            re.regex($process.target.process.command_line, `(|cmd.*/c).*netstat.*-ano`) nocase
        )
    )
    or
        (
            // C2 like Covenant will mask curl command running from PowerShell; added this to detect DNS lookup for this site as another method to identify
            $process.metadata.event_type = "NETWORK_DNS" and
            $process.network.application_protocol = "DNS" and
            $process.network.dns.questions.name = "www.ip-api.com"
        )

    $process.principal.hostname = $hostname
    $process.target.process.command_line = $command_line

  match:
    $hostname over 15m

  outcome:
    $risk_score = 35
    $event_count = count_distinct($process.metadata.id)
    $unique_command_line_threshold = 5
    // added to populate alert graph with additional context
    // Commented out principal.hostname because it is already represented in graph as match variable. If match changes, can uncomment to add to results
    //$principal_hostname = array_distinct($process.principal.hostname)
    $principal_process_pid = array_distinct($process.principal.process.pid)
    $principal_process_command_line = array_distinct($process.principal.process.command_line)
    $principal_process_file_sha256 = array_distinct($process.principal.process.file.sha256)
    $principal_process_file_full_path = array_distinct($process.principal.process.file.full_path)
    $principal_process_product_specific_process_id = array_distinct($process.principal.process.product_specific_process_id)
    $principal_process_parent_process_product_specific_process_id = array_distinct($process.principal.process.parent_process.product_specific_process_id)
    $target_process_pid = array_distinct($process.target.process.pid)
    $target_process_command_line = array_distinct($process.target.process.command_line)
    $target_process_file_sha256 = array_distinct($process.target.process.file.sha256)
    $target_process_file_full_path = array_distinct($process.target.process.file.full_path)
    $target_process_product_specific_process_id = array_distinct($process.target.process.product_specific_process_id)
    $principal_user_userid = array_distinct($process.principal.user.userid)

  condition:
    // modify the condition value for command line to throttle how many of these commands can be issued until the rule is triggered
    $process and #command_line > 5
}

YARA-L Rule Structure

Condition

Fires when at least one $process event in the 15m window and $command_line occurs more than 5 times in the 15m window.

Events

$process PROCESS_LAUNCH (1, 22, 4688)

  • target.process.command_line matches "(|cmd.*/c).*arp.*-a"
  • target.process.command_line matches "(|cmd.*/c).*curl.*www.ip-api.com"
  • target.process.command_line matches "(|cmd.*/c).*dnscmd.*/enumrecords.*/zone"
  • target.process.command_line matches "(|cmd.*/c).*dnscmd.*/enumzones"
  • target.process.command_line matches "(|cmd.*/c).*dnscmd.*/enumrecords.*/additional"
  • target.process.command_line matches "(|cmd.*/c).*ipconfig.*/all"
  • target.process.command_line matches "(|cmd.*/c).*netsh.*interface.*firewall.*show"
  • target.process.command_line matches "(|cmd.*/c).*netsh.*interface.*portproxy.*show"
  • target.process.command_line matches "(|cmd.*/c).*netsh.*interface.*portproxy.*show.*v4tov4"
  • target.process.command_line matches "(|cmd.*/c).*netsh.*firewall.*show"
  • target.process.command_line matches "(|cmd.*/c).*netsh.*portproxy.*show.*v4tov4"
  • target.process.command_line matches "(|cmd.*/c).*netstat.*-ano"
  • network.application_protocol = "DNS"
  • network.dns.questions.name = "www.ip-api.com"

Match and Correlation

Match key
$hostname (principal.hostname)
Within
15m

Outcome

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

FieldExpression
risk_score35
event_countcount_distinct($process.metadata.id)
unique_command_line_threshold5
principal_process_pidarray_distinct($process.principal.process.pid)
principal_process_command_linearray_distinct($process.principal.process.command_line)
principal_process_file_sha256array_distinct($process.principal.process.file.sha256)
principal_process_file_full_patharray_distinct($process.principal.process.file.full_path)
principal_process_product_specific_process_idarray_distinct($process.principal.process.product_specific_process_id)
principal_process_parent_process_product_specific_process_idarray_distinct($process.principal.process.parent_process.product_specific_process_id)
target_process_pidarray_distinct($process.target.process.pid)
target_process_command_linearray_distinct($process.target.process.command_line)
target_process_file_sha256array_distinct($process.target.process.file.sha256)
target_process_file_full_patharray_distinct($process.target.process.file.full_path)
target_process_product_specific_process_idarray_distinct($process.target.process.product_specific_process_id)
principal_user_useridarray_distinct($process.principal.user.userid)

sap execution of sensitive abap program

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

Detects the execution of high-risk ABAP programs (AUW). These programs often bypass standard transaction-level security.

MITRE ATT&CK Coverage

Rule Body

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

rule sap_execution_of_sensitive_abap_program {

  meta:
    author = "Google Cloud Security"
    description = "Detects the execution of high-risk ABAP programs (AUW). These programs often bypass standard transaction-level security."
    severity = "High"
    tactic = "TA0002"
    technique = "T1059"

  events:
    $e.metadata.log_type = "SAP_SECURITY_AUDIT"

    $e.principal.process.file.names = %sap_sensitive_abap_programs.abap_program

    $user = $e.principal.user.userid

    //exclusions
    not $user in %sap_admin_users.user

  match:
    $user over 1h

  outcome:
    $risk_score = 60
    $sensitive_abap_program = array_distinct($e.principal.process.file.names)
    $description = array_distinct($e.metadata.description)
    $sid = array_distinct($e.target.application)
    $t_code = array_distinct($e.security_result.detection_fields["slgtc_1"])

  condition:
    $e
}

YARA-L Rule Structure

Condition

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

Events

$e

  • metadata.log_type = "SAP_SECURITY_AUDIT"
  • principal.process.file.names in "%sap_sensitive_abap_programs.abap_program"
  • principal.user.userid in "%sap_admin_users.user"

Match and Correlation

Match key
$user
Within
1h

Outcome

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

FieldExpression
risk_score60
sensitive_abap_programarray_distinct($e.principal.process.file.names)
descriptionarray_distinct($e.metadata.description)
sidarray_distinct($e.target.application)
t_codearray_distinct($e.security_result.detection_fields["slgtc_1"])

Back to all YARA-L rules