Detection rules › YARA-L
YARA-L rules: 02
| Rule | Severity |
|---|---|
| Finger.EXE Execution | high |
| Logins From Terminated Employees | medium |
| Suspicious Invoke-WebRequest Execution | high |
Finger.EXE Execution
#Detects execution of the finger.exe utility. Finger.EXE or "TCPIP Finger Command" is an old utility that is still present on modern Windows installation. It Displays information about users on a specified remote computer (typically a UNIX computer) that is running the finger service or daemon. Due to the old nature of this utility and the rareness of machines having the finger service. Any execution of finger.exe can be considered suspicious and worth investigating.
Known False Positives
- Admin activity (unclear what they do nowadays with finger.exe)
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
References
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
// Copyright 2025 Google LLC. Licensed under Apache-2.0.
rule finger_exe_execution {
meta:
author = "Florian Roth (Nextron Systems), omkar72, oscd.community"
description = "Detects execution of the finger.exe utility. Finger.EXE or \"TCPIP Finger Command\" is an old utility that is still present on modern Windows installation. It Displays information about users on a specified remote computer (typically a UNIX computer) that is running the finger service or daemon. Due to the old nature of this utility and the rareness of machines having the finger service. Any execution of finger.exe can be considered suspicious and worth investigating."
reference = "https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_finger_execution.yml"
license = "https://github.com/SigmaHQ/Detection-Rule-License/blob/main/LICENSE.Detection.Rules.md"
rule_name = "Finger.EXE Execution"
sigma_uuid = "af491bca-e752-4b44-9c86-df5680533dbc"
sigma_status = "test"
rule_id = "mr_9174795b-96f3-4fce-b5a3-f8e5901990b1"
tactic = "TA0011"
technique = "T1105"
type = "Detection"
data_source = "Sysmon"
platform = "Windows"
severity = "High"
priority = "High"
false_positives = "Admin activity (unclear what they do nowadays with finger.exe)"
events:
$process.metadata.event_type = "PROCESS_LAUNCH"
(
$process.src.process.file.full_path = "finger.exe" nocase or
re.regex($process.target.process.file.full_path, `\\finger\.exe$`) nocase
)
$process.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
//example usage of specifying test user and hostname to adjust risk score
$risk_score = max(if($process.principal.user.userid = "user" and $process.principal.hostname = "hostname", 0, 15))
$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_specfic_process_id = array_distinct($process.principal.process.product_specific_process_id)
$principal_process_parent_process_product_specfic_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_specfic_process_id = array_distinct($process.target.process.product_specific_process_id)
$principal_user_userid = array_distinct($process.principal.user.userid)
$log_type = array_distinct(strings.concat($process.metadata.log_type,"/",$process.metadata.product_event_type))
condition:
$process
}
YARA-L Rule Structure
Condition
Fires when at least one $process event in the 5m window.
Events
$process
src.process.file.full_path = "finger.exe"target.process.file.full_path matches "\\finger\.exe$"
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($process.principal.user.userid = "user" and $process.principal.hostname = "hostname", 0, 15)) |
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_specfic_process_id | array_distinct($process.principal.process.product_specific_process_id) |
principal_process_parent_process_product_specfic_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_specfic_process_id | array_distinct($process.target.process.product_specific_process_id) |
principal_user_userid | array_distinct($process.principal.user.userid) |
log_type | array_distinct(strings.concat($process.metadata.log_type,"/",$process.metadata.product_event_type)) |
Logins From Terminated Employees
#Allowed Logins from Terminated Employees
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Initial Access |
Telemetry Coverage
Rule Body
// Copyright 2023 Google LLC. Licensed under Apache-2.0.
rule logins_from_terminated_employees {
meta:
author = "Google Cloud Security"
description = "Allowed Logins from Terminated Employees"
rule_id = "mr_69178541-285b-45cb-b723-e2b5d88f22d3"
rule_name = "Logins From Terminated Employees"
assumptions = "This rule requires a context data source such as AzureAD AD Context or Workday to demonstrate the correlation of context logs with event logs"
type = "alert"
tags = "user enrichment"
data_source = "microsoft windows events"
tactic = "TA0001"
technique = "T1078"
severity = "Medium"
priority = "Medium"
events:
$login.metadata.event_type = "USER_LOGIN"
$login.security_result.action = "ALLOW"
$login.target.user.userid = $user
$login.target.user.termination_date.seconds > 0
$login.target.user.termination_date.seconds < $login.metadata.event_timestamp.seconds
match:
$user over 1d
outcome:
$risk_score = 65
$event_count = count_distinct($login.metadata.id)
$employee_last_login = max($login.target.user.termination_date.seconds)
$total_distinct_ips = count_distinct($login.principal.ip)
// added to populate alert graph with additional context
$principal_hostname = array_distinct($login.principal.hostname)
$target_hostname = array_distinct($login.target.hostname)
$principal_user_userid = array_distinct($login.principal.user.userid)
// Commented out target.user.userid because it is already represented in graph as match variable. If match changes, can uncomment to add to results
//$target_user_userid = array_distinct($login.target.user.userid)
$principal_resource_name = array_distinct($login.principal.resource.name)
$target_resource_name = array_distinct($login.target.resource.name)
$target_url = array_distinct($login.target.url)
condition:
$login
}
YARA-L Rule Structure
Condition
Fires when at least one $login event in the 24h window.
Events
$login
security_result.action = "ALLOW"target.user.termination_date.seconds > "0"target.user.termination_date.seconds cross_field_compare "login.metadata.event_timestamp.seconds"
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($login.metadata.id) |
employee_last_login | max($login.target.user.termination_date.seconds) |
total_distinct_ips | count_distinct($login.principal.ip) |
principal_hostname | array_distinct($login.principal.hostname) |
target_hostname | array_distinct($login.target.hostname) |
principal_user_userid | array_distinct($login.principal.user.userid) |
principal_resource_name | array_distinct($login.principal.resource.name) |
target_resource_name | array_distinct($login.target.resource.name) |
target_url | array_distinct($login.target.url) |
Suspicious Invoke-WebRequest Execution
#Detects a suspicious call to Invoke-WebRequest cmdlet where the and output is located in a suspicious location
Known False Positives
- Unknown
MITRE ATT&CK Coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
References
Telemetry Coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule Body
// Copyright 2025 Google LLC. Licensed under Apache-2.0.
rule suspicious_invoke_webrequest_execution {
meta:
author = "Nasreddine Bencherchali (Nextron Systems)"
description = "Detects a suspicious call to Invoke-WebRequest cmdlet where the and output is located in a suspicious location"
reference = "https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_powershell_invoke_webrequest_download.yml"
license = "https://github.com/SigmaHQ/Detection-Rule-License/blob/main/LICENSE.Detection.Rules.md"
rule_name = "Suspicious Invoke-WebRequest Execution"
sigma_uuid = "5e3cc4d8-3e68-43db-8656-eaaeefdec9cc"
sigma_status = "test"
rule_id = "mr_62fb3b3f-e99f-4ab3-9d5b-21994ba25ebe"
tactic = "TA0011"
technique = "T1105"
type = "Detection"
data_source = "Sysmon"
platform = "Windows"
severity = "High"
priority = "High"
false_positives = "Unknown"
events:
$process.metadata.event_type = "PROCESS_LAUNCH"
(
re.regex($process.target.process.file.full_path, `\\powershell\.exe$`) nocase or
re.regex($process.target.process.file.full_path, `\\pwsh\.exe$`) nocase or
$process.src.process.file.full_path = "powershell.exe" nocase or
$process.src.process.file.full_path = "pwsh.dll" nocase
)
(
strings.contains(strings.to_lower($process.target.process.command_line), "curl ") or
strings.contains(strings.to_lower($process.target.process.command_line), "invoke-webrequest") or
strings.contains(strings.to_lower($process.target.process.command_line), "iwr ") or
strings.contains(strings.to_lower($process.target.process.command_line), "wget ")
)
(
strings.contains(strings.to_lower($process.target.process.command_line), " -ur") or
strings.contains(strings.to_lower($process.target.process.command_line), " -o")
)
(
strings.contains(strings.to_lower($process.target.process.command_line), "\\appdata\\") or
strings.contains(strings.to_lower($process.target.process.command_line), "\\desktop\\") or
strings.contains(strings.to_lower($process.target.process.command_line), "\\temp\\") or
strings.contains(strings.to_lower($process.target.process.command_line), "\\users\\public\\") or
strings.contains(strings.to_lower($process.target.process.command_line), "%appdata%") or
strings.contains(strings.to_lower($process.target.process.command_line), "%public%") or
strings.contains(strings.to_lower($process.target.process.command_line), "%temp%") or
strings.contains(strings.to_lower($process.target.process.command_line), "%tmp%") or
strings.contains(strings.to_lower($process.target.process.command_line), ":\\windows\\")
)
$process.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
//example usage of specifying test user and hostname to adjust risk score
$risk_score = max(if($process.principal.user.userid = "user" and $process.principal.hostname = "hostname", 0, 15))
$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_specfic_process_id = array_distinct($process.principal.process.product_specific_process_id)
$principal_process_parent_process_product_specfic_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_specfic_process_id = array_distinct($process.target.process.product_specific_process_id)
$principal_user_userid = array_distinct($process.principal.user.userid)
$log_type = array_distinct(strings.concat($process.metadata.log_type,"/",$process.metadata.product_event_type))
condition:
$process
}
YARA-L Rule Structure
Condition
Fires when at least one $process event in the 5m window.
Events
$process
target.process.file.full_path matches "\\powershell\.exe$"target.process.file.full_path matches "\\pwsh\.exe$"src.process.file.full_path = "powershell.exe"src.process.file.full_path = "pwsh.dll"target.process.command_line contains "curl "target.process.command_line contains "invoke-webrequest"target.process.command_line contains "iwr "target.process.command_line contains "wget "target.process.command_line contains " -ur"target.process.command_line contains " -o"target.process.command_line contains "\appdata\"target.process.command_line contains "\desktop\"target.process.command_line contains "\temp\"target.process.command_line contains "\users\public\"target.process.command_line contains "%appdata%"target.process.command_line contains "%public%"target.process.command_line contains "%temp%"target.process.command_line contains "%tmp%"target.process.command_line contains ":\windows\"
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($process.principal.user.userid = "user" and $process.principal.hostname = "hostname", 0, 15)) |
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_specfic_process_id | array_distinct($process.principal.process.product_specific_process_id) |
principal_process_parent_process_product_specfic_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_specfic_process_id | array_distinct($process.target.process.product_specific_process_id) |
principal_user_userid | array_distinct($process.principal.user.userid) |
log_type | array_distinct(strings.concat($process.metadata.log_type,"/",$process.metadata.product_event_type)) |