Detection rules › YARA-L
YARA-L rules: 1n
Entra ID Application Hard Deletion
#Deletion of Entra ID application with no recovery of the application.
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Azure | Hard Delete application |
Rules Detecting the Same Action
These rules filter on the same operation.
- [Entra ID] Application Assigned Administrator Permissions Immediately After Obtaining Role Management Permissions (Kusto)
- [Entra ID] Application Granted Administrative Permission to Assign Microsoft Entra ID Roles (Kusto)
- Added Credentials to Existing Application (Sigma)
- Added Owner To Application (Sigma)
- Admin promotion after Role Management Application Permission Grant (Kusto)
- App Granted Microsoft Permissions (Sigma)
- App Granted Privileged Delegated Or App Permissions (Sigma)
- Application AppID Uri Configuration Changes (Sigma)
Rule Body
// Copyright 2025 Google LLC. Licensed under Apache-2.0.
rule entra_id_application_hard_deletion {
meta:
author = "Google Cloud Security"
description = "Deletion of Entra ID application with no recovery of the application."
rule_id = "mr_b4b8a401-4803-498a-b601-d984cf5042fa"
rule_name = "Entra ID Application Hard Deletion"
type = "alert"
platform = "azure"
data_source = "azure ad audit"
severity = "Medium"
priority = "Medium"
events:
$app.metadata.event_type = "SETTING_DELETION"
$app.metadata.product_event_type = "Hard Delete application"
$app.metadata.product_name = "Azure AD Directory Audit"
$app.metadata.vendor_name = "Microsoft"
$app.security_result.action = "ALLOW"
$app.principal.user.userid = $user
match:
$user over 5m
outcome:
$risk_score = 65
$event_count = count_distinct($app.metadata.id)
$principal_ip = array_distinct($app.principal.ip)
$principal_email = array_distinct($app.principal.user.email_addresses)
$principal_county_region = array_distinct($app.principal.ip_geo_artifact.location.country_or_region)
$user_agent = array_distinct($app.network.http.user_agent)
$network_session = array_distinct($app.network.session_id)
$target_application = array_distinct($app.target.resource.name)
$target_application_id = array_distinct($app.target.resource.product_object_id)
condition:
$app
}
YARA-L Rule Structure
Condition
Fires when at least one $app event in the 5m window.
Events
$app
metadata.product_event_type = "Hard Delete application"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 | 65 |
event_count | count_distinct($app.metadata.id) |
principal_ip | array_distinct($app.principal.ip) |
principal_email | array_distinct($app.principal.user.email_addresses) |
principal_county_region | array_distinct($app.principal.ip_geo_artifact.location.country_or_region) |
user_agent | array_distinct($app.network.http.user_agent) |
network_session | array_distinct($app.network.session_id) |
target_application | array_distinct($app.target.resource.name) |
target_application_id | array_distinct($app.target.resource.product_object_id) |
LSASS Process Memory Dump Files
#Detects creation of files with names used by different memory dumping tools to create a memory dump of the LSASS process memory, which contains user credentials
Known False Positives
- Unknown
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
References
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 11: FileCreate |
Rule Body
// Copyright 2025 Google LLC. Licensed under Apache-2.0.
rule lsass_process_memory_dump_file_creation {
meta:
author = "Florian Roth (Nextron Systems)"
description = "Detects creation of files with names used by different memory dumping tools to create a memory dump of the LSASS process memory, which contains user credentials"
reference = "https://github.com/SigmaHQ/sigma/blob/master/rules/windows/file/file_event/file_event_win_lsass_default_dump_file_names.yml"
license = "https://github.com/SigmaHQ/Detection-Rule-License/blob/main/LICENSE.Detection.Rules.md"
rule_name = "LSASS Process Memory Dump Files"
sigma_uuid = "a5a2d357-1ab8-4675-a967-ef9990a59391"
sigma_status = "test"
rule_id = "mr_8fd8cb2b-18dc-468d-acdf-899da9f6de43"
tactic = "TA0006"
technique = "T1003.001"
type = "Detection"
data_source = "Sysmon"
platform = "Windows"
severity = "High"
priority = "High"
false_positives = "Unknown"
events:
$file.metadata.event_type = "FILE_CREATION"
(
re.regex($file.target.file.full_path, `\\(Andrew\.dmp|Coredump\.dmp|lsass\.dmp|lsass\.rar|lsass\.zip|NotLSASS\.zip|PPLBlade\.dmp|rustive\.dmp)\$`) nocase or
strings.contains($file.target.file.full_path, "\\lsass_2") or
strings.contains($file.target.file.full_path, "\\lsassdmp") or
strings.contains($file.target.file.full_path, "\\lsassdump") or
(
strings.contains(strings.to_lower($file.target.file.full_path), "\\lsass") and
re.regex($file.target.file.full_path, `\.dmp$`) nocase
)
or
(
strings.contains(strings.to_lower($file.target.file.full_path), "sqldmpr") and
re.regex($file.target.file.full_path, `\.mdmp$`) nocase
)
or
(
(
strings.contains(strings.to_lower($file.target.file.full_path), "\\nanodump") or
strings.contains(strings.to_lower($file.target.file.full_path), "\\proc_")
)
and
re.regex($file.target.file.full_path, `\.dmp$`) nocase
)
)
$file.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
//example usage of specifying test user and hostname to adjust risk score
$risk_score = max(if($file.principal.user.userid = "user" and $file.principal.hostname = "hostname", 0, 15))
$principal_hostname = array_distinct($file.principal.hostname)
$principal_process_pid = array_distinct($file.principal.process.pid)
$principal_process_command_line = array_distinct($file.principal.process.command_line)
$principal_process_file_sha256 = array_distinct($file.principal.process.file.sha256)
$principal_process_file_full_path = array_distinct($file.principal.process.file.full_path)
$principal_process_product_specific_process_id = array_distinct($file.principal.process.product_specific_process_id)
$principal_process_parent_process_product_specific_process_id = array_distinct($file.principal.process.parent_process.product_specific_process_id)
$principal_user_userid = array_distinct($file.principal.user.userid)
$target_file_sha256 = array_distinct($file.target.file.sha256)
$target_file_full_path = array_distinct($file.target.file.full_path)
condition:
$file
}
YARA-L Rule Structure
Condition
Fires when at least one $file event in the 5m window.
Events
$file
target.file.full_path matches "\\(Andrew\.dmp|Coredump\.dmp|lsass\.dmp|lsass\.rar|lsass\.zip|NotLSASS\.zip|PPLBlade\.dmp|rustive\.dmp)\$"target.file.full_path contains "\lsass_2"target.file.full_path contains "\lsassdmp"target.file.full_path contains "\lsassdump"target.file.full_path contains "\lsass"target.file.full_path matches "\.dmp$"target.file.full_path contains "sqldmpr"target.file.full_path matches "\.mdmp$"target.file.full_path contains "\nanodump"target.file.full_path contains "\proc_"target.file.full_path matches "\.dmp$"
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(if($file.principal.user.userid = "user" and $file.principal.hostname = "hostname", 0, 15)) |
principal_hostname | array_distinct($file.principal.hostname) |
principal_process_pid | array_distinct($file.principal.process.pid) |
principal_process_command_line | array_distinct($file.principal.process.command_line) |
principal_process_file_sha256 | array_distinct($file.principal.process.file.sha256) |
principal_process_file_full_path | array_distinct($file.principal.process.file.full_path) |
principal_process_product_specific_process_id | array_distinct($file.principal.process.product_specific_process_id) |
principal_process_parent_process_product_specific_process_id | array_distinct($file.principal.process.parent_process.product_specific_process_id) |
principal_user_userid | array_distinct($file.principal.user.userid) |
target_file_sha256 | array_distinct($file.target.file.sha256) |
target_file_full_path | array_distinct($file.target.file.full_path) |
O365 Entra ID App Modify Permission Change On Watchlist
#Alerts when a permission on the watchlist is applied to an Entra ID application.
References
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Microsoft 365 | Update application. |
Rules Detecting the Same Action
These rules filter on the same operation.
Rule Body
// Copyright 2023 Google LLC. Licensed under Apache-2.0.
rule o365_entra_id_app_modify_permission_change_on_watchlist {
meta:
author = "Google Cloud Security"
description = "Alerts when a permission on the watchlist is applied to an Entra ID application."
rule_id = "mr_678cafb8-ea1f-42ac-a396-238bc35e4d21"
rule_name = "O365 Entra ID App Modify Permission Change On Watchlist"
reference = "https://learn.microsoft.com/en-us/graph/permissions-reference"
assumption = "The list msgraph_watchlist_permissions is populated as needed with guid permissions Example: 024d486e-b451-40bb-833d-3e66d98c5c73 //Mail.Read.Write"
type = "alert"
platform = "azure"
data_source = "o365"
severity = "Medium"
priority = "Medium"
events:
$app.metadata.event_type = "USER_RESOURCE_UPDATE_CONTENT"
$app.metadata.product_name = "Office 365"
$app.metadata.product_event_type = "Update application."
$app.metadata.vendor_name = "Microsoft"
$app.security_result.action = "ALLOW"
(
$app.target.resource.attribute.labels.key = /NewValue_EntitlementId-/ or
$app.target.resource.attribute.labels.key = /OldValue_EntitlementId-/
)
$app.security_result.detection_fields["target_1"] = $app_name
match:
$app_name over 5m
outcome:
$risk_score = 65
$event_count = count_distinct($app.metadata.id)
$security_summary = array_distinct($app.security_result.summary)
$user_agent = array_distinct($app.network.http.user_agent)
//The reference list msgraph_watchlist_permissions matches on the GUID. List contents example row: 6aedf524-7e1c-45a7-bd76-ded8cab8d0fc //SecurityEvents.ReadWrite.All
$watchlist_permissions_after_modification = array_distinct(if($app.target.resource.attribute.labels.key = /NewValue_EntitlementId/ and $app.target.resource.attribute.labels.value IN %msgraph_watchlist_permissions, $app.target.resource.attribute.labels.value,""))
$watchlist_permissions_before_modification = array_distinct(if($app.target.resource.attribute.labels.key = /OldValue_EntitlementId/ and $app.target.resource.attribute.labels.value IN %msgraph_watchlist_permissions, $app.target.resource.attribute.labels.value,""))
$permissions_after_modification = array_distinct(if($app.target.resource.attribute.labels.key = /NewValue_EntitlementId/ and $app.target.resource.attribute.labels.value !="", $app.target.resource.attribute.labels.value,""))
$permissions_before_modification = array_distinct(if($app.target.resource.attribute.labels.key = /OldValue_EntitlementId/ and $app.target.resource.attribute.labels.value !="", $app.target.resource.attribute.labels.value,""))
$total_permissions_after_modification = count_distinct(if($app.target.resource.attribute.labels.key = /NewValue_EntitlementId/ and $app.target.resource.attribute.labels.value !="", $app.target.resource.attribute.labels.value, "")) - 1
$total_permissions_before_modification = count_distinct(if($app.target.resource.attribute.labels.key = /OldValue_EntitlementId/ and $app.target.resource.attribute.labels.value !="", $app.target.resource.attribute.labels.value, "")) - 1
//added to populate alert graph with additional context
$principal_user_userid = array_distinct($app.principal.user.userid)
condition:
$app
}
YARA-L Rule Structure
Condition
Fires when at least one $app event in the 5m window.
Events
$app
metadata.product_event_type = "Update application."security_result.action = "ALLOW"target.resource.attribute.labels.key matches "NewValue_EntitlementId-"target.resource.attribute.labels.key matches "OldValue_EntitlementId-"
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 | 65 |
event_count | count_distinct($app.metadata.id) |
security_summary | array_distinct($app.security_result.summary) |
user_agent | array_distinct($app.network.http.user_agent) |
watchlist_permissions_after_modification | array_distinct(if($app.target.resource.attribute.labels.key = /NewValue_EntitlementId/ and $app.target.resource.attribute.labels.value IN %msgraph_watchlist_permissions, $app.target.resource.attribute.labels.value,"")) |
watchlist_permissions_before_modification | array_distinct(if($app.target.resource.attribute.labels.key = /OldValue_EntitlementId/ and $app.target.resource.attribute.labels.value IN %msgraph_watchlist_permissions, $app.target.resource.attribute.labels.value,"")) |
permissions_after_modification | array_distinct(if($app.target.resource.attribute.labels.key = /NewValue_EntitlementId/ and $app.target.resource.attribute.labels.value !="", $app.target.resource.attribute.labels.value,"")) |
permissions_before_modification | array_distinct(if($app.target.resource.attribute.labels.key = /OldValue_EntitlementId/ and $app.target.resource.attribute.labels.value !="", $app.target.resource.attribute.labels.value,"")) |
total_permissions_after_modification | count_distinct(if($app.target.resource.attribute.labels.key = /NewValue_EntitlementId/ and $app.target.resource.attribute.labels.value !="", $app.target.resource.attribute.labels.value, "")) - 1 |
total_permissions_before_modification | count_distinct(if($app.target.resource.attribute.labels.key = /OldValue_EntitlementId/ and $app.target.resource.attribute.labels.value !="", $app.target.resource.attribute.labels.value, "")) - 1 |
principal_user_userid | array_distinct($app.principal.user.userid) |
sap sensitive tables direct access by rfc logon data table
#Detects direct access to sensitive SAP tables (e.g., USR02, T000) specifically via RFC logon. This identifies potential data exfiltration or unauthorized inspection of security-critical data tables.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Collection |
Rule Body
// Copyright 2026 Google LLC. Licensed under Apache-2.0.
rule sap_sensitive_tables_direct_access_by_rfc_logon_data_table {
meta:
author = "Google Cloud Security"
description = "Detects direct access to sensitive SAP tables (e.g., USR02, T000) specifically via RFC logon. This identifies potential data exfiltration or unauthorized inspection of security-critical data tables."
severity = "High"
tactic = "TA0009"
technique = "T1005"
events:
$e.metadata.log_type = "SAP_SECURITY_AUDIT"
$e.additional.fields["msg_1"] = "CUZ"
$SID = $e.target.application
$table = $e.additional.fields["param1_1"]
$table in %sap_sensitive_tables.name
match:
$table over 1h
outcome:
$user_list = array_distinct($e.principal.user.userid)
$source_ips = array_distinct($e.principal.ip)
$system_ids = array_distinct($SID)
$event_count = count($e.metadata.id)
$terminal_names = array_distinct($e.principal.hostname)
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"additional.fields["msg_1"] = "CUZ"additional.fields["param1_1"] in "%sap_sensitive_tables.name"
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 |
|---|---|
user_list | array_distinct($e.principal.user.userid) |
source_ips | array_distinct($e.principal.ip) |
system_ids | array_distinct($SID) |
event_count | count($e.metadata.id) |
terminal_names | array_distinct($e.principal.hostname) |
Unauthorized KMS Decryption
#Detects when a Key Management Service (KMS) decryption operation is carried out by a service account that's not in the allowlist. This behavior may indicate unauthorized access to information.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Persistence | No specific technique |
Telemetry Coverage
Rule Body
// Copyright 2025 Google LLC. Licensed under Apache-2.0.
rule gcp_kms_decryption_by_unexpected_service_account {
meta:
author = "Drew Pilarski - Tempus AI"
description = "Detects when a Key Management Service (KMS) decryption operation is carried out by a service account that's not in the allowlist. This behavior may indicate unauthorized access to information."
rule_id = "mr_90cd5b0d-60a7-4028-bc41-dce0947fbafd"
rule_name = "Unauthorized KMS Decryption"
reference = "Internal Security Policy" // Include link to your organization's internal documentation if available
mitre_attack_tactic = "Persistence"
mitre_attack_technique = "Valid Accounts: Cloud Accounts"
type = "Alert"
platform = "GCP"
data_source = "Cloud Audit Logs"
severity = "Medium" // Adjust based on your risk assessment
priority = "Medium" // Adjust based on your incident response process
events:
$decrypt.metadata.product_name = "Google Cloud Platform"
$decrypt.metadata.vendor_name = "Google Cloud Platform"
// Generic KMS Key Pattern - Pick the relevant one to your environment
re.regex($decrypt.target.resource.name, `^projects/[^/]+/locations/[^/]+/keyRings/[^/]+/cryptoKeys/[^/]+$`)
$decrypt.metadata.product_event_type = "Decrypt"
not $decrypt.principal.user.email_addresses in %kms_decryption_service_account_allowlist
outcome:
$action = $decrypt.metadata.product_event_type
$account_name = array_distinct($decrypt.principal.user.email_addresses)
$mitre_attack_tactic = array_distinct("Persistence")
$mitre_attack_technique = array_distinct("Valid Accounts: Cloud Accounts")
$mitre_attack_technique_id = array_distinct("T1078.004")
condition:
$decrypt
}
YARA-L Rule Structure
Condition
Fires when at least one $decrypt event.
Events
$decrypt
target.resource.name matches "^projects/[^/]+/locations/[^/]+/keyRings/[^/]+/cryptoKeys/[^/]+$"metadata.product_event_type = "Decrypt"principal.user.email_addresses in "%kms_decryption_service_account_allowlist"
Outcome
Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.
| Field | Expression |
|---|---|
action | $decrypt.metadata.product_event_type |
account_name | array_distinct($decrypt.principal.user.email_addresses) |