Detection rules › YARA-L
YARA-L rules: 2n
AWS Lambda Update Function Code
#Detects an IAM user attempting to update/modify AWS lambda code.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| AWS | CloudTrail event UpdateFunctionCode: Updates a Lambda function's code. |
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
Outcome
Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.
| Field | Expression |
|---|---|
risk_score | max(35) |
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) |
Google Workspace Suspicious Login and Google Drive File Download
#Identifies when a Google Workspace user downloads a file from Google Drive after a suspicious login event occurred.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Exfiltration |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Google Workspace | download: Download |
| Google Workspace | login_success: Login Success |
Rules Detecting the Same Action
These rules filter on the same operation.
- GCP Successful Single-Factor Authentication (Splunk)
- Google Workspace Encryption Key File Accessed By An Anonymous User (YARA-L)
- Google Workspace Malicious File Downloaded (YARA-L)
- Google Workspace Many Docs Downloaded (Panther)
- Google Workspace Multiple Files Downloaded From Google Drive (YARA-L)
- Google Workspace Rapid Multi-IP Authentication (Panther)
- Google Workspace Rapid Multi-IP Authentication (Panther)
- Google Workspace Suspicious Login and Google Drive File Share (YARA-L)
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
Outcome
Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.
| Field | Expression |
|---|---|
risk_score | max(75) |
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) |
Hunt for Office 365 group creation failures
#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
| Platform | Record / event type |
|---|---|
| Microsoft 365 | Add 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
metadata.product_event_type = "Add group."security_result.action = "BLOCK"
Match and Correlation
Outcome
Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.
| Field | Expression |
|---|---|
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) |
proposed_group_name | array_distinct($group.target.group.group_display_name) |
reason | array_distinct($group.target.labels["MethodExecutionResult."]) |
Recon Environment Enumeration Network CISA Report
#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
| Tactic | Techniques |
|---|---|
| Discovery |
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
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
Outcome
Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.
| Field | Expression |
|---|---|
risk_score | 35 |
event_count | count_distinct($process.metadata.id) |
unique_command_line_threshold | 5 |
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) |
sap execution of sensitive abap program
#Detects the execution of high-risk ABAP programs (AUW). These programs often bypass standard transaction-level security.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Execution |
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
Outcome
Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.
| Field | Expression |
|---|---|
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"]) |