Hi @spanuganti . Have you considered refactoring the way that you calculate the risk score? In your current setup you are using a series of if statements, which you can refactor into an outcome block. You can use this same strategy for other similar logical expressions.
I removed the code snippet which was malformed from my post.
@jstoner Could you please help/suggest ?
@vaskenh rule itself is showing an error.
description = "Detects CrowdStrike EDR events potentially related to T1078 (Valid Accounts) during Reconnaissance/Initial Access."
yara_version = "YL2.0"
rule_version = "1.10"
rule_type = "ENDPOINT_DETECTION"
priority = "Medium"
severity = "Medium"
kill_chain = "Reconnaissance"
mitre_tactic = "TA0001"
mitre_technique = "T1078"
tactic_name = "Initial Access"
events:
// Event A: Crowdstrike EDR Detect event
$a.metadata.log_type = "CS_EDR"
// Use an aggregation ID for the match section
$a.metadata.product_log_id = $log_id
// Exclusion: Filter out known benign process paths efficiently
not $a.target.file.full_path = "/opt/dynatrace/oneagent/agent/lib64/oneagentinstallaction"
match:
// Match events sharing the same CrowdStrike log ID within a 5-minute window.
$log_id over 5m
outcome:
// **Risk Score Calculation (Corrected Syntax):**
// We use math_max (or max, depending on the platform's exact function name) on each conditional check.
// This ensures we get the highest risk score across all grouped events ($a) by summing the max possible score from each severity bucket.
// Only one bucket will typically be non-zero.
$risk_score =
max(if($a.security_result[0].severity = "CRITICAL", 100, 0)) +
max(if($a.security_result[0].severity = "HIGH", 70, 0)) +
max(if($a.security_result[0].severity = "MEDIUM", 50, 0)) +
max(if($a.security_result[0].severity = "INFORMATIONAL", 10, 0))
// **Aggregation Variables:**
// Use collect_set, which is the standard aggregation function for unique values.
$commandline = collect_set($a.principal.process.command_line)
$log_type = collect_set($a.metadata.log_type)
$hostname = collect_set($a.principal.asset.hostname)
$signature = collect_set($a.metadata.description)
$url_back_to_product = collect_set($a.metadata.url_back_to_product)
$src_user = collect_set($a.principal.user.userid)
$target_user_sid = collect_set($a.target.user.windows_sid)
$asset_id = collect_set($a.principal.asset.asset_id)
$process_file_full_path = collect_set($a.principal.process.file.full_path)
$principal_file_md5 = collect_set($a.principal.process.file.md5)
$principal_file_sha1 = collect_set($a.principal.process.file.sha1)
$principal_file_sha256 = collect_set($a.principal.process.file.sha256)
$target_file_full_path = collect_set($a.target.file.full_path)
condition:
// The most concise way to ensure at least one event matches.
$a
}
where Im I missign gettig this logic error--
description = "Detects CrowdStrike EDR events potentially related to T1078 (Valid Accounts) during Reconnaissance/Initial Access."
yara_version = "YL2.0"
rule_version = "1.10"
rule_type = "ENDPOINT_DETECTION"
priority = "Medium"
severity = "Medium"
kill_chain = "Reconnaissance"
mitre_tactic = "TA0001"
mitre_technique = "T1078"
tactic_name = "Initial Access"
events:
// Event A: Crowdstrike EDR Detect event
$a.metadata.log_type = "CS_EDR"
// Use an aggregation ID for the match section
$a.metadata.product_log_id = $log_id
// Exclusion: Filter out known benign process paths efficiently
not $a.target.file.full_path =/cmd\.exe/ nocase
// Exclude common Edge and WebView processes launching themselves
not $a.principal.process.file.full_path = /msedgewebview2\.exe/ nocase
// Exclude Docker processes (if they are known to be benign in our own environment)
not $a.principal.process.file.full_path = /docker\.exe/ nocase
// Exclude Microsoft URLs/IPs related to common telemetry or updates (st01.dsx.microsoft.com)
// detection is on a network connection (target.url)
not $a.target.url = /st0(1|2)\.dsx\.microsoft\.com/ nocase
match:
// Match events sharing the same CrowdStrike log ID within a 5-minute window.
$log_id over 5m
outcome:
// **Risk Score Calculation (Corrected Syntax):**
// We use math_max (or max, depending on the platform's exact function name) on each conditional check.
// This ensures we get the highest risk score across all grouped events ($a) by summing the max possible score from each severity bucket.
// Only one bucket will typically be non-zero.
$risk_score =
max(if($a.security_result[0].severity = "CRITICAL", 100, 0)) +
max(if($a.security_result[0].severity = "HIGH", 70, 0)) +
max(if($a.security_result[0].severity = "MEDIUM", 50, 0)) +
max(if($a.security_result[0].severity = "INFORMATIONAL", 10, 0))
// **Aggregation Variables:**
// Use collect_set, which is the standard aggregation function for unique values.
$commandline = array_distinct($a.principal.process.command_line)
$log_type = array_distinct($a.metadata.log_type)
$hostname = array_distinct($a.principal.asset.hostname)
$signature = array_distinct($a.metadata.description)
$url_back_to_product = array_distinct($a.metadata.url_back_to_product)
$src_user = array_distinct($a.principal.user.userid)
$target_user_sid = array_distinct($a.target.user.windows_sid)
$asset_id = array_distinct($a.principal.asset.asset_id)
$process_file_full_path = array_distinct($a.principal.process.file.full_path)
$principal_file_md5 = array_distinct($a.principal.process.file.md5)
$principal_file_sha1 = array_distinct($a.principal.process.file.sha1)
$principal_file_sha256 = array_distinct($a.principal.process.file.sha256)
$target_file_full_path = array_distinct($a.target.file.full_path)
condition:
// To ensure at least one event matches.
$a
}
this is working, but getting 10,000 detections is this to be expected or need to be more optimized to avoid false positives or noise?