Detection rules › YARA-L
YARA-L rules: 3g
| Rule | Severity |
|---|---|
| ADFS DB Suspicious Named Pipe Connection | medium |
| GitHub Repository Archived Or Deleted | low |
| IOC Domain Internal Policy | low |
| Okta Phishing Detection With Fastpass Origin Check | medium |
ADFS DB Suspicious Named Pipe Connection
#Connection to ADFS via named pipes that are not using specific Windows ADFS processes may be indicative of user attempting to access ADFS for suspicious purposes
References
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 17: PipeEvent (Pipe Created) |
| Sysmon | Event ID 18: PipeEvent (Pipe Connected) |
Rule Body
// Copyright 2023 Google LLC. Licensed under Apache-2.0.
rule adfs_db_suspicious_named_pipe_connection {
meta:
author = "Google Cloud Security"
description = "Connection to ADFS via named pipes that are not using specific Windows ADFS processes may be indicative of user attempting to access ADFS for suspicious purposes"
rule_id = "mr_a25913a1-65be-4cb5-b0de-6858dd04ac99"
rule_name = "ADFS DB Suspicious Named Pipe Connection"
reference = "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Windows%20Security%20Events/Analytic%20Rules/ADFSDBNamedPipeConnection.yaml"
type = "alert"
platform = "Windows"
data_source = "sysmon"
severity = "Medium"
priority = "Medium"
events:
$process.metadata.event_type = "PROCESS_UNCATEGORIZED"
$process.metadata.product_event_type = "18"
$process.metadata.product_name = "Microsoft-Windows-Sysmon"
not re.regex($process.target.process.file.full_path, `Microsoft.Identity.Health.Adfs.PshSurrogate.exe|Microsoft.IdentityServer.ServiceHost.exe|AzureADConnect.exe|Microsoft.Tri.Sensor.exe|wsmprovhost.exe|mmc.exe|sqlservr.exe|sqlwriter.exe`) nocase
$process.target.resource.name = "\\MICROSOFT##WID\\tsql\\query" nocase
/*
If you have a listing of ADFS servers, you can use a reference list or enumerate them in the field below.
Alternatively, if ADFS servers are grouped in an asset attribute, that attribute could be used instead.
*/
$process.principal.hostname = /adfs/ nocase
$process.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
$risk_score = 65
$event_count = count_distinct($process.metadata.id)
$security_summary = array_distinct($process.security_result.summary)
$target_process_parent_process_command_line = array_distinct($process.target.process.parent_process.command_line)
//added to populate alert graph with additional context
//Commented out because it is the same as the match variable, if match variable changes, uncomment to use
//$principal_hostname = array_distinct($process.principal.hostname)
$principal_user_userid = array_distinct($process.principal.user.userid)
$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)
$target_process_parent_product_specific_process_id = array_distinct($process.target.process.parent_process.product_specific_process_id)
$target_resource_name = array_distinct($process.target.resource.name)
condition:
$process
}
YARA-L Rule Structure
Condition
Fires when at least one $process event in the 5m window.
Events
$process
metadata.product_event_type = "18"target.process.file.full_path matches "Microsoft.Identity.Health.Adfs.PshSurrogate.exe|Microsoft.IdentityServer.ServiceHost.exe|AzureADConnect.exe|Microsoft.Tri.Sensor.exe|wsmprovhost.exe|mmc.exe|sqlservr.exe|sqlwriter.exe"target.resource.name = "\MICROSOFT##WID\tsql\query"principal.hostname matches "adfs"
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($process.metadata.id) |
security_summary | array_distinct($process.security_result.summary) |
target_process_parent_process_command_line | array_distinct($process.target.process.parent_process.command_line) |
principal_user_userid | array_distinct($process.principal.user.userid) |
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) |
target_process_parent_product_specific_process_id | array_distinct($process.target.process.parent_process.product_specific_process_id) |
target_resource_name | array_distinct($process.target.resource.name) |
GitHub Repository Archived Or Deleted
#Detects when a GitHub repository is archived or deleted.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Impact |
References
Telemetry Coverage
Rules Detecting the Same Action
These rules filter on the same operation.
- GitHub - Repository was destroyed (Kusto)
- Github Delete Action Invoked (Sigma)
- GitHub Enterprise Repository Archived (Splunk)
- GitHub Enterprise Repository Deleted (Splunk)
- GitHub Organizations Repository Archived (Splunk)
- GitHub Organizations Repository Deleted (Splunk)
- GitHub Repository Archive Status Changed (Sigma)
- GitHub Repository Archived (Panther)
Rule Body
// Copyright 2024 Google LLC. Licensed under Apache-2.0.
rule github_repository_archived_or_deleted {
meta:
author = "Google Cloud Security"
description = "Detects when a GitHub repository is archived or deleted."
rule_id = "mr_8c515a63-1e2e-4f9e-9150-93302b813315"
rule_name = "GitHub Repository Archived Or Deleted"
assumption = "Your GitHub enterprise audit log settings are configured to log the source IP address for events. Reference: https://docs.github.com/en/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/displaying-ip-addresses-in-the-audit-log-for-your-organization"
type = "alert"
severity = "Low"
priority = "Low"
platform = "GitHub"
data_source = "github"
mitre_attack_tactic = "Impact"
mitre_attack_technique = "Data Destruction"
mitre_attack_url = "https://attack.mitre.org/versions/v14/techniques/T1485/"
mitre_attack_version = "v14"
reference = "https://docs.github.com/en/enterprise-cloud@latest/admin/monitoring-activity-in-your-enterprise/reviewing-audit-logs-for-your-enterprise/audit-log-events-for-your-enterprise"
events:
$github.metadata.vendor_name = "GITHUB" nocase
$github.metadata.product_name = "GITHUB"
(
$github.metadata.product_event_type = "repo.archived" or
$github.metadata.product_event_type = "repo.destroy"
)
$github.principal.user.userid = $user_id
$github.target.resource.name = $github_repo_name
match:
$user_id, $github_repo_name over 30m
outcome:
$risk_score = max(35)
$mitre_attack_tactic = "Impact"
$mitre_attack_technique = "Data Destruction"
$mitre_attack_technique_id = "T1485"
$event_count = count_distinct($github.metadata.id)
$principal_ip = array_distinct($github.principal.ip)
$principal_user_userid = array_distinct($github.principal.user.userid)
$principal_ip_country = array_distinct($github.principal.ip_geo_artifact.location.country_or_region)
$principal_ip_state = array_distinct($github.principal.ip_geo_artifact.location.state)
$principal_ip_city = array_distinct($github.principal.location.city)
$security_result_summary = array_distinct($github.security_result.summary)
condition:
$github
}
YARA-L Rule Structure
Condition
Fires when at least one $github event in the 30m window.
Events
$github
metadata.product_event_type = "repo.archived" or "repo.destroy"
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($github.metadata.id) |
principal_ip | array_distinct($github.principal.ip) |
principal_user_userid | array_distinct($github.principal.user.userid) |
principal_ip_country | array_distinct($github.principal.ip_geo_artifact.location.country_or_region) |
principal_ip_state | array_distinct($github.principal.ip_geo_artifact.location.state) |
principal_ip_city | array_distinct($github.principal.location.city) |
security_result_summary | array_distinct($github.security_result.summary) |
IOC Domain Internal Policy
#Detect DNS events that communicate with gaming sites in MISP. These violate policy.
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 22: DNSEvent (DNS query) |
Rule Body
// Copyright 2023 Google LLC. Licensed under Apache-2.0.
rule ioc_domain_internal_policy {
meta:
author = "Google Cloud Security"
description = "Detect DNS events that communicate with gaming sites in MISP. These violate policy."
rule_id = "mr_853bfafe-3049-43b5-a077-6a5f4a24ea3c"
rule_name = "IOC Domain Internal Policy"
type = "alert"
tags = "threat indicators"
assumption = "Assumes MISP data has been ingested into entity graph; this rule can be modified to utilize other TI indicators"
data_source = "microsoft sysmon"
severity = "Low"
priority = "Low"
events:
$dns.metadata.event_type = "NETWORK_DNS"
$dns.network.dns.questions.name = $dns_query
// Correlates with MISP data; can be modified based on your MISP parser or other TI
$ioc.graph.metadata.product_name = "MISP"
$ioc.graph.metadata.entity_type = "DOMAIN_NAME"
$ioc.graph.metadata.source_type = "ENTITY_CONTEXT"
// Summary is used to focus on a specific subset of MISP indicators, can modify as needed
$ioc.graph.metadata.threat.summary = "Gaming Sites"
// Threat Feed Name is used to focus on a specific subset of MISP indicators, can modify as needed
$ioc.graph.metadata.threat.threat_feed_name = "Internal"
$ioc.graph.entity.hostname = $dns_query
// Regex used to extract subset of data from field description, optional
re.capture($ioc.graph.metadata.threat.description, "additional info: (.*)") = $info
match:
$dns_query over 5m
outcome:
$risk_score = 35
$event_count = count_distinct($dns.metadata.id)
// If not doing any additional extractions to $info placeholder variable, the following outcome variable can be removed
$threat_info = array_distinct($info)
$network_dns_questions_name = array_distinct($dns.network.dns.questions.name)
$network_dns_answers_data = array_distinct($dns.network.dns.answers.data)
// added to populate alert graph with additional context
$principal_ip = array_distinct($dns.principal.ip)
$target_ip = array_distinct($dns.target.ip)
$principal_process_pid = array_distinct($dns.principal.process.pid)
$principal_process_file_full_path = array_distinct($dns.principal.process.file.full_path)
$principal_process_product_specific_process_id = array_distinct($dns.principal.process.product_specific_process_id)
$principal_user_userid = array_distinct($dns.principal.user.userid)
$principal_process_command_line = array_distinct($dns.principal.process.command_line)
$principal_process_file_sha256 = array_distinct($dns.principal.process.file.sha256)
$principal_process_parent_process_product_specific_process_id = array_distinct($dns.principal.process.parent_process.product_specific_process_id)
condition:
$dns and $ioc
}
YARA-L Rule Structure
Condition
Fires when at least one $dns event in the 5m window and $ioc matches entity context.
Events
$dns
$ioc
graph.metadata.product_name = "MISP"graph.metadata.entity_type = "DOMAIN_NAME"graph.metadata.source_type = "ENTITY_CONTEXT"graph.metadata.threat.summary = "Gaming Sites"graph.metadata.threat.threat_feed_name = "Internal"
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($dns.metadata.id) |
threat_info | array_distinct($info) |
network_dns_questions_name | array_distinct($dns.network.dns.questions.name) |
network_dns_answers_data | array_distinct($dns.network.dns.answers.data) |
principal_ip | array_distinct($dns.principal.ip) |
target_ip | array_distinct($dns.target.ip) |
principal_process_pid | array_distinct($dns.principal.process.pid) |
principal_process_file_full_path | array_distinct($dns.principal.process.file.full_path) |
principal_process_product_specific_process_id | array_distinct($dns.principal.process.product_specific_process_id) |
principal_user_userid | array_distinct($dns.principal.user.userid) |
principal_process_command_line | array_distinct($dns.principal.process.command_line) |
principal_process_file_sha256 | array_distinct($dns.principal.process.file.sha256) |
principal_process_parent_process_product_specific_process_id | array_distinct($dns.principal.process.parent_process.product_specific_process_id) |
Okta Phishing Detection With Fastpass Origin Check
#Okta provides a platform detection for when a user enrolled in FastPass fails to authenticate via a real-time AiTM phishing proxy.
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
References
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Okta | System Log event type user.authentication.auth_via_mfa: User authenticated via MFA |
Rules Detecting the Same Action
These rules filter on the same operation.
- First Occurrence of Okta User Session Started via Proxy (Elastic)
- MFA Fatigue (OKTA) (Kusto)
- Okta AiTM Phishing Attempt Blocked by FastPass (Panther)
- Okta Authentication Failed During MFA Challenge (Splunk)
- Okta Fast Pass phishing Detection (Kusto)
- Okta FastPass Phishing Detection (Sigma)
- Okta FastPass Phishing Detection (Elastic)
- Okta MFA Bruteforce Attack (YARA-L)
Rule Body
// Copyright 2023 Google LLC. Licensed under Apache-2.0.
rule okta_phishing_detection_with_fastpass_origin_check {
meta:
author = "Google Cloud Security"
description = "Okta provides a platform detection for when a user enrolled in FastPass fails to authenticate via a real-time AiTM phishing proxy."
rule_id = "mr_07d1a26d-1132-4228-bd49-c8dd899c7792"
rule_name = "Okta Phishing Detection With Fastpass Origin Check"
reference = "https://sec.okta.com/fastpassphishingdetection"
mitre_attack_tactic = "Initial Access"
mitre_attack_technique = "Phishing"
mitre_attack_url = "https://attack.mitre.org/techniques/T1566/"
mitre_attack_version = "v13.1"
type = "Alert"
data_source = "Okta"
severity = "Medium"
priority = "Medium"
events:
$login.metadata.product_name = "Okta"
$login.metadata.vendor_name = "Okta"
$login.metadata.event_type = "USER_LOGIN"
$login.metadata.product_event_type = "user.authentication.auth_via_mfa"
$login.security_result.action = "BLOCK"
$login.security_result.category_details = "FastPass declined phishing attempt"
$login.target.user.userid = $userid
match:
$userid over 1h
outcome:
$risk_score = max(35)
$mitre_attack_tactic = "Initial Access"
$mitre_attack_technique = "Phishing"
$target_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)
$principal_ip_city = array_distinct($login.principal.location.city)
$principal_user_email_addresses = array_distinct ($login.principal.user.email_addresses)
$security_result_summary = array_distinct($login.security_result.summary)
$target_user_email_addresses = array_distinct($login.target.user.email_addresses)
$target_user_userid = array_distinct($login.target.user.userid)
$security_result_risk_reason = array_distinct($login.security_result.detection_fields["Risk Reasons"])
condition:
$login
}
YARA-L Rule Structure
Condition
Fires when at least one $login event in the 1h window.
Events
$login
metadata.product_event_type = "user.authentication.auth_via_mfa"security_result.action = "BLOCK"security_result.category_details = "FastPass declined phishing attempt"
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) |
target_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) |
principal_ip_city | array_distinct($login.principal.location.city) |
principal_user_email_addresses | array_distinct ($login.principal.user.email_addresses) |
security_result_summary | array_distinct($login.security_result.summary) |
target_user_email_addresses | array_distinct($login.target.user.email_addresses) |
target_user_userid | array_distinct($login.target.user.userid) |
security_result_risk_reason | array_distinct($login.security_result.detection_fields["Risk Reasons"]) |