Detection rules › YARA-L

YARA-L rules: 0p

Domain Prevalence

#
Severity
low
Type
alert
Time window
5m
Match by
domain
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Detects DNS events querying domains that have a low rolling max prevalence.

Telemetry Coverage

ProviderRecord / event type
SysmonEvent ID 22: DNSEvent (DNS query)

Rule Body

// Copyright 2023 Google LLC. Licensed under Apache-2.0.

rule domain_prevalence {

  meta:
    author = "Google Cloud Security"
    description = "Detects DNS events querying domains that have a low rolling max prevalence."
    rule_id = "mr_cf5dd851-d7e9-42b8-baf9-f4527ab61bf3"
    rule_name = "Domain Prevalence"
    type = "alert"
    tags = "prevalence"
    data_source = "extrahop, tanium, microsoft sysmon, gcp dns, crowdstrike"
    severity = "Low"
    priority = "Low"

  events:
    $dns.metadata.event_type = "NETWORK_DNS"
    $dns.network.dns.questions.name = $domain

    // derived from events ingested by Chronicle
    $prevalence.graph.metadata.entity_type = "DOMAIN_NAME"
    $prevalence.graph.metadata.source_type = "DERIVED_CONTEXT"
    $prevalence.graph.entity.hostname = $domain
    $prevalence.graph.entity.domain.prevalence.day_count = 10
    $prevalence.graph.entity.domain.prevalence.rolling_max <= 3
    $prevalence.graph.entity.domain.prevalence.rolling_max > 0

  match:
    $domain over 5m

  outcome:
    $risk_score = max(35)
    $event_count = count_distinct($dns.metadata.id)
    $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_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)
    $principal_user_userid = array_distinct($dns.principal.user.userid)


  condition:
    $dns and $prevalence
}

YARA-L Rule Structure

Condition

Fires when at least one $dns event in the 5m window and $prevalence matches entity context.

Events

$dns NETWORK_DNS (22)

No field filters (binds the event for correlation only).

$prevalence entity context (DOMAIN_NAME)

  • graph.metadata.entity_type = "DOMAIN_NAME"
  • graph.metadata.source_type = "DERIVED_CONTEXT"
  • graph.entity.domain.prevalence.day_count = "10"
  • graph.entity.domain.prevalence.rolling_max <= "3"
  • graph.entity.domain.prevalence.rolling_max > "0"

Match and Correlation

Match key
$domain (network.dns.questions.name)
Within
5m

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_scoremax(35)
event_countcount_distinct($dns.metadata.id)
network_dns_questions_namearray_distinct($dns.network.dns.questions.name)
network_dns_answers_dataarray_distinct($dns.network.dns.answers.data)
principal_iparray_distinct($dns.principal.ip)
target_iparray_distinct($dns.target.ip)
principal_process_pidarray_distinct($dns.principal.process.pid)
principal_process_file_full_patharray_distinct($dns.principal.process.file.full_path)
principal_process_product_specific_process_idarray_distinct($dns.principal.process.product_specific_process_id)
principal_process_command_linearray_distinct($dns.principal.process.command_line)
principal_process_file_sha256array_distinct($dns.principal.process.file.sha256)
principal_process_parent_process_product_specific_process_idarray_distinct($dns.principal.process.parent_process.product_specific_process_id)
principal_user_useridarray_distinct($dns.principal.user.userid)

Entra ID Recently Created User Assigned an Entra ID Role

#
Severity
high
Type
alert
Time window
30m
Match by
principal_userid, target_userid
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Detect users who are newly created and then immediately assigned administrator level roles

MITRE ATT&CK Coverage

References

Telemetry Coverage

PlatformRecord / event type
AzureAdd member to role
AzureAdd user

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

// Copyright 2025 Google LLC. Licensed under Apache-2.0.

rule entra_id_recently_created_user_assigned_entra_id_roles {

  meta:
    author = "Google Cloud Security"
    description = "Detect users who are newly created and then immediately assigned administrator level roles"
    rule_id = "mr_ab6067cd-b8a0-49f7-9efb-8a9b3b096a49"
    rule_name = "Entra ID Recently Created User Assigned an Entra ID Role"
    tactic = "TA0003"
    technique = "T1098.003"
    assumption = "The list msgraph_watchlist_roles_guid is popualted with admin role guids, ie 62e90394-69f5-4237-9190-012177145e10"
    reference = "https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/permissions-reference"
    type = "alert"
    platform = "azure"
    data_source = "azure ad"
    severity = "High"
    priority = "High"

  events:
    (
        $create.metadata.event_type = "USER_CREATION" and
        $create.metadata.product_event_type = "Add user" and
        $create.metadata.product_name = "Azure AD Directory Audit" and
        $create.metadata.vendor_name = "Microsoft" and
        $create.security_result.action = "ALLOW" and
        $create.principal.user.userid = $principal_userid and
        $create.target.user.userid = $target_userid
    )
    $create.metadata.event_timestamp.seconds < $role.metadata.event_timestamp.seconds
    (
        $role.metadata.event_type = "USER_CHANGE_PERMISSIONS" and
        $role.metadata.product_event_type = "Add member to role" and
        $role.metadata.product_name = "Azure AD Directory Audit" and
        $role.metadata.vendor_name = "Microsoft" and
        $role.security_result.action = "ALLOW" and
        //To detect on specific roles, they can be added to a reference list and the following line uncommented
        //$role.target.resource.attribute.labels["Role.Role.TemplateId"] in %msgraph_watchlist_roles_guid and
        $role.principal.user.userid = $principal_userid and
        re.replace($role.target.user.userid, `@.*$`, "") = $target_userid
    )

  match:
    $principal_userid, $target_userid over 30m

  outcome:
    $risk_score = 85
    $principal_county_region = array_distinct(strings.concat($create.principal.location.city," ",$create.principal.location.state," ",$create.principal.location.country_or_region))
    $assigned_role = array_distinct($role.target.user.title)
    $assigned_role_guid = array_distinct($role.target.resource.attribute.labels["Role.TemplateId"])

  condition:
    $create and $role
}

YARA-L Rule Structure

Condition

Fires when at least one $create event in the 30m window and at least one $role event in the 30m window.

Events

$create USER_CREATION

  • metadata.product_event_type = "Add user"
  • security_result.action = "ALLOW"

$role USER_CHANGE_PERMISSIONS

  • metadata.product_event_type = "Add member to role"
  • security_result.action = "ALLOW"

Match and Correlation

Order
$create before $role
Match key
$principal_userid, $target_userid (target.user.userid)
Within
30m

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_score85
principal_county_regionarray_distinct(strings.concat($create.principal.location.city," ",$create.principal.location.state," ",$create.principal.location.country_or_region))
assigned_rolearray_distinct($role.target.user.title)
assigned_role_guidarray_distinct($role.target.resource.attribute.labels["Role.TemplateId"])

File Download Via Windows Defender MpCmpRun.EXE

#
Severity
high
Type
Detection
Time window
1m
Match by
hostname
Author
Matthew Matchen
Source
github.com/chronicle/detection-rules

Detects the use of Windows Defender MpCmdRun.EXE to download files

Known False Positives

  • Unknown

MITRE ATT&CK Coverage

TacticTechniques
Command & Control

References

Telemetry Coverage

Rule Body

// Copyright 2025 Google LLC. Licensed under Apache-2.0.

rule file_download_via_windows_defender_mpcmdrun_exe {

  meta:
    author = "Matthew Matchen"
    description = "Detects the use of Windows Defender MpCmdRun.EXE to download files"
    reference = "https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_mpcmdrun_download_arbitrary_file.yml"
    license = "https://github.com/SigmaHQ/Detection-Rule-License/blob/main/LICENSE.Detection.Rules.md"
    rule_name = "File Download Via Windows Defender MpCmpRun.EXE"
    sigma_uuid = "46123129-1024-423e-9fae-43af4a0fa9a5"
    sigma_status = "test"
    rule_id = "mr_22c73791-b666-436e-b584-f14afb3cf6d5"
    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"
    (
      $process.src.process.file.full_path = "mpcmdrun.exe" nocase or
      re.regex($process.target.process.file.full_path, `\\mpcmdrun\.exe$`) nocase or
      strings.contains(strings.to_lower($process.target.process.command_line), "mpcmdrun.exe") or
      $process.target.asset.software.description = "Microsoft Malware Protection Command Line Utility" nocase
    )
    (
      strings.contains(strings.to_lower($process.target.process.command_line), "downloadfile") and
      strings.contains(strings.to_lower($process.target.process.command_line), "url")
    )
    $process.principal.hostname = $hostname

  match:
    $hostname over 1m

  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 1m window.

Events

$process PROCESS_LAUNCH (1, 4688)

  • src.process.file.full_path = "mpcmdrun.exe"
  • target.process.file.full_path matches "\\mpcmdrun\.exe$"
  • target.process.command_line contains "mpcmdrun.exe"
  • target.asset.software.description = "Microsoft Malware Protection Command Line Utility"
  • target.process.command_line contains "downloadfile"
  • target.process.command_line contains "url"

Match and Correlation

Match key
$hostname (principal.hostname)
Within
1m

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_scoremax(if($process.principal.user.userid = "user" and $process.principal.hostname = "hostname", 0, 15))
principal_process_pidarray_distinct($process.principal.process.pid)
principal_process_command_linearray_distinct($process.principal.process.command_line)
principal_process_file_sha256array_distinct($process.principal.process.file.sha256)
principal_process_file_full_patharray_distinct($process.principal.process.file.full_path)
principal_process_product_specfic_process_idarray_distinct($process.principal.process.product_specific_process_id)
principal_process_parent_process_product_specfic_process_idarray_distinct($process.principal.process.parent_process.product_specific_process_id)
target_process_pidarray_distinct($process.target.process.pid)
target_process_command_linearray_distinct($process.target.process.command_line)
target_process_file_sha256array_distinct($process.target.process.file.sha256)
target_process_file_full_patharray_distinct($process.target.process.file.full_path)
target_process_product_specfic_process_idarray_distinct($process.target.process.product_specific_process_id)
principal_user_useridarray_distinct($process.principal.user.userid)
log_typearray_distinct(strings.concat($process.metadata.log_type,"/",$process.metadata.product_event_type))

MITRE ATT&CK T1140 Encoded Powershell Command

#
Severity
info
Type
hunt
Time window
5m
Match by
hostname
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Detects encoded powershell commands

MITRE ATT&CK Coverage

Telemetry Coverage

Rule Body

// Copyright 2023 Google LLC. Licensed under Apache-2.0.

rule mitre_attack_T1140_encoded_powershell_command {

  meta:
    author = "Google Cloud Security"
    description = "Detects encoded powershell commands"
    rule_id = "mr_c01d7d92-db49-4044-a2c5-5a16c74a141d"
    rule_name = "MITRE ATT&CK T1140 Encoded Powershell Command"
    tactic = "TA0005"
    technique = "T1140"
    type = "hunt"
    platform = "Windows"
    data_source = "microsoft sysmon, microsoft windows events"
    severity = "Info"
    priority = "Info"

  events:
    $process.metadata.event_type = "PROCESS_LAUNCH"
    $process.principal.hostname = $hostname
    re.regex($process.target.process.file.full_path, `(system32|syswow64)\\WindowsPowerShell\\v1\.0\\powershell(|\_ise)\.exe`) nocase
    re.regex($process.target.process.command_line, `(?i)(?:-enc|-ec|-en)\s*\S*`)
    $encoded_value = re.capture($process.target.process.command_line, `(?i)(?:-enc|-ec|-en)\s*(\S*)`)
    $decoded_value = re.replace(strings.base64_decode(re.capture($process.target.process.command_line, `(?i)(?:-enc|-ec|-en)\s*(\S*)`)),`\0`, "")

  match:
    $hostname over 5m

  outcome:
    $risk_score = 10
    $event_count = count_distinct($process.metadata.id)
    $encoded_powershell = array_distinct($encoded_value)
    $decoded_powershell = array_distinct($decoded_value)
    // 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:
    $process
}

YARA-L Rule Structure

Condition

Fires when at least one $process event in the 5m window.

Events

$process PROCESS_LAUNCH (1, 4688)

  • target.process.file.full_path matches "(system32|syswow64)\\WindowsPowerShell\\v1\.0\\powershell(|\_ise)\.exe"
  • target.process.command_line matches "(?i)(?:-enc|-ec|-en)\s*\S*"

Match and Correlation

Match key
$hostname (principal.hostname)
Within
5m

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_score10
event_countcount_distinct($process.metadata.id)
encoded_powershellarray_distinct($encoded_value)
decoded_powershellarray_distinct($decoded_value)
principal_hostnamearray_distinct($process.principal.hostname)
principal_process_pidarray_distinct($process.principal.process.pid)
principal_process_command_linearray_distinct($process.principal.process.command_line)
principal_process_file_sha256array_distinct($process.principal.process.file.sha256)
principal_process_file_full_patharray_distinct($process.principal.process.file.full_path)
principal_process_product_specific_process_idarray_distinct($process.principal.process.product_specific_process_id)
principal_process_parent_process_product_specific_process_idarray_distinct($process.principal.process.parent_process.product_specific_process_id)
target_process_pidarray_distinct($process.target.process.pid)
target_process_command_linearray_distinct($process.target.process.command_line)
target_process_file_sha256array_distinct($process.target.process.file.sha256)
target_process_file_full_patharray_distinct($process.target.process.file.full_path)
target_process_product_specific_process_idarray_distinct($process.target.process.product_specific_process_id)
principal_user_useridarray_distinct($process.principal.user.userid)

potential lsass process dump via procdump

#
Severity
high
Type
Detection
Time window
5m
Match by
hostname
Author
Florian Roth (Nextron Systems)
Source
github.com/chronicle/detection-rules

Detects suspicious uses of the SysInternals Procdump utility by using a special command line parameter in combination with the lsass.exe process. This way we are also able to catch cases in which the attacker has renamed the procdump executable. Procdump dump of lsass using minidump or memory dump options. Covers atomic tests 1 and 8

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

References

Telemetry Coverage

Rule Body

// Copyright 2025 Google LLC. Licensed under Apache-2.0.

rule potential_lsass_process_dump_via_procdump {

  meta:
    author = "Florian Roth (Nextron Systems)"
    description = "Detects suspicious uses of the SysInternals Procdump utility by using a special command line parameter in combination with the lsass.exe process. This way we are also able to catch cases in which the attacker has renamed the procdump executable. Procdump dump of lsass using minidump or memory dump options. Covers atomic tests 1 and 8"
    reference = "https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_sysinternals_procdump_lsass.yml"
    license = "https://github.com/SigmaHQ/Detection-Rule-License/blob/main/LICENSE.Detection.Rules.md"
    sigma_uuid = "5afee48e-67dd-4e03-a783-f74259dcf998"
    sigma_status = "stable"
    rule_id = "mr_f7efb1a2-866c-4505-947e-3b06d4240262"
    tactic = "TA0006"
    technique = "T1003.001"
    type = "Detection"
    data_source = "Sysmon"
    platform = "Windows"
    severity = "High"
    priority = "High"
    falsepositives = "Unlikely, because no one should dump an lsass process memory, another tool that uses command line flags similar to ProcDump"

  events:
    $process.metadata.event_type = "PROCESS_LAUNCH"
    (
        strings.contains($process.target.process.command_line, " -ma ") or
        strings.contains($process.target.process.command_line, " -mm ")
    )
    strings.contains(strings.to_lower($process.target.process.command_line), " ls")
    $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 PROCESS_LAUNCH (1, 4688)

  • target.process.command_line contains " -ma "
  • target.process.command_line contains " -mm "
  • target.process.command_line contains " ls"

Match and Correlation

Match key
$hostname (principal.hostname)
Within
5m

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_scoremax(if($process.principal.user.userid = "user" and $process.principal.hostname = "hostname", 0, 15))
principal_process_pidarray_distinct($process.principal.process.pid)
principal_process_command_linearray_distinct($process.principal.process.command_line)
principal_process_file_sha256array_distinct($process.principal.process.file.sha256)
principal_process_file_full_patharray_distinct($process.principal.process.file.full_path)
principal_process_product_specfic_process_idarray_distinct($process.principal.process.product_specific_process_id)
principal_process_parent_process_product_specfic_process_idarray_distinct($process.principal.process.parent_process.product_specific_process_id)
target_process_pidarray_distinct($process.target.process.pid)
target_process_command_linearray_distinct($process.target.process.command_line)
target_process_file_sha256array_distinct($process.target.process.file.sha256)
target_process_file_full_patharray_distinct($process.target.process.file.full_path)
target_process_product_specfic_process_idarray_distinct($process.target.process.product_specific_process_id)
principal_user_useridarray_distinct($process.principal.user.userid)
log_typearray_distinct(strings.concat($process.metadata.log_type,"/",$process.metadata.product_event_type))

Potential Remote PowerShell Session Initiated

#
Severity
high
Type
Hunt
Time window
5m
Match by
hostname
Author
Roberto Rodriguez @Cyb3rWard0g
Source
github.com/chronicle/detection-rules

Detects a process that initiated a network connection over ports 5985 or 5986 from a non-network service account. This could potentially indicates a remote PowerShell connection.

Known False Positives

  • Legitimate usage of remote PowerShell, e.g. remote administration and monitoring. Network Service user name of a not-covered localization

MITRE ATT&CK Coverage

References

Telemetry Coverage

Rule Body

// Copyright 2025 Google LLC. Licensed under Apache-2.0.

rule potential_remote_powershell_session_initiated {

  meta:
    author = "Roberto Rodriguez @Cyb3rWard0g"
    description = "Detects a process that initiated a network connection over ports 5985 or 5986 from a non-network service account. This could potentially indicates a remote PowerShell connection."
    reference = "https://github.com/SigmaHQ/sigma/blob/master/rules/windows/network_connection/net_connection_win_susp_remote_powershell_session.yml"
    license = "https://github.com/SigmaHQ/Detection-Rule-License/blob/main/LICENSE.Detection.Rules.md"
    rule_name = "Potential Remote PowerShell Session Initiated"
    sigma_uuid = "c539afac-c12a-46ed-b1bd-5a5567c9f045"
    sigma_status = "test"
    rule_id = "mr_7186feaf-ab01-4c41-b17f-994b08b5bc33"
    tactic = "TA0008"
    technique = "T1021.006"
    type = "Hunt"
    data_source = "Sysmon"
    platform = "Windows"
    severity = "High"
    priority = "High"
    false_positives = "Legitimate usage of remote PowerShell, e.g. remote administration and monitoring. Network Service user name of a not-covered localization"

  events:
    $net.metadata.event_type = "NETWORK_CONNECTION"
    $net.metadata.product_event_type = "3"
    $net.metadata.product_name = "Microsoft-Windows-Sysmon"
    $net.metadata.vendor_name = "Microsoft"
    (
        $net.target.port = 5985 or
        $net.target.port = 5986
    )
    //Parser extension added for Initiated/true field/value, not currently in Sysmon parser
    //Initiated: 'true'
    $net.additional.fields["Initiated"] = "true"
    net.ip_in_range_cidr($net.principal.ip, "0.0.0.0/0")
    NOT (
        strings.contains(strings.to_upper($net.principal.user.userid), "NETWORK SERVICE") or
        strings.contains(strings.to_upper($net.principal.user.userid), "NETZWERKDIENST") or
        strings.contains(strings.to_upper($net.principal.user.userid), "SERVICIO DE RED") or
        strings.contains(strings.to_upper($net.principal.user.userid), "SERVIZIO DI RETE")
        or
        (
            strings.contains(strings.to_upper($net.principal.user.userid), "SERVICE R") and
            strings.contains(strings.to_upper($net.principal.user.userid), "SEAU")
        )
    )
    NOT (
        $net.principal.ip = "::1" or
        $net.principal.ip = "127.0.0.1" or
        $net.target.ip = "::1" or
        $net.target.ip = "127.0.0.1"
    )
    NOT (
        $net.principal.process.file.full_path = "C:\\Program Files\\Avast Software\\Avast\\AvastSvc.exe" nocase or
        $net.principal.process.file.full_path = "C:\\Program Files (x86)\\Avast Software\\Avast\\AvastSvc.exe" nocase
    )

    $net.principal.hostname = $hostname

  match:
    $hostname over 5m

  outcome:
    //example usage of specifying test user and hostname to adjust risk score
    $risk_score = max(if($net.principal.user.userid = "user" and $net.principal.hostname = "hostname", 0, 15))
    $principal_ip = array_distinct($net.principal.ip)
    $principal_port = array_distinct($net.principal.port)
    $principal_process_pid = array_distinct($net.principal.process.pid)
    $principal_process_command_line = array_distinct($net.principal.process.command_line)
    $principal_process_file_sha256 = array_distinct($net.principal.process.file.sha256)
    $principal_process_file_full_path = array_distinct($net.principal.process.file.full_path)
    $principal_process_product_specific_process_id = array_distinct($net.principal.process.product_specific_process_id)
    $principal_process_parent_process_product_specific_process_id = array_distinct($net.principal.process.parent_process.product_specific_process_id)
    $principal_user_userid = array_distinct($net.principal.user.userid)
    $target_ip = array_distinct($net.target.ip)
    $target_port = array_distinct($net.target.port)

  condition:
    $net
}

YARA-L Rule Structure

Condition

Fires when at least one $net event in the 5m window.

Events

$net NETWORK_CONNECTION (3)

  • metadata.product_event_type = "3"
  • target.port = "5985" or "5986"
  • additional.fields["Initiated"] = "true"
  • principal.ip cidr_match "0.0.0.0/0"
  • principal.user.userid contains "NETWORK SERVICE"
  • principal.user.userid contains "NETZWERKDIENST"
  • principal.user.userid contains "SERVICIO DE RED"
  • principal.user.userid contains "SERVIZIO DI RETE"
  • principal.user.userid contains "SERVICE R"
  • principal.user.userid contains "SEAU"
  • principal.ip = "::1"
  • principal.ip = "127.0.0.1"
  • target.ip = "::1"
  • target.ip = "127.0.0.1"
  • principal.process.file.full_path is one of:
    • C:\Program Files\Avast Software\Avast\AvastSvc.exe
    • C:\Program Files (x86)\Avast Software\Avast\AvastSvc.exe

Match and Correlation

Match key
$hostname (principal.hostname)
Within
5m

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_scoremax(if($net.principal.user.userid = "user" and $net.principal.hostname = "hostname", 0, 15))
principal_iparray_distinct($net.principal.ip)
principal_portarray_distinct($net.principal.port)
principal_process_pidarray_distinct($net.principal.process.pid)
principal_process_command_linearray_distinct($net.principal.process.command_line)
principal_process_file_sha256array_distinct($net.principal.process.file.sha256)
principal_process_file_full_patharray_distinct($net.principal.process.file.full_path)
principal_process_product_specific_process_idarray_distinct($net.principal.process.product_specific_process_id)
principal_process_parent_process_product_specific_process_idarray_distinct($net.principal.process.parent_process.product_specific_process_id)
principal_user_useridarray_distinct($net.principal.user.userid)
target_iparray_distinct($net.target.ip)
target_portarray_distinct($net.target.port)

Purple Knight Tool Execution Detected

#
Type
alert
Time window
10m
Match by
hostname
Author
Georg Lauenstein - suresecure GmbH
Source
github.com/chronicle/detection-rules

This detection rule identifies the execution of the Purple Knight tool, a free Active Directory security assessment utility developed by Semperis. Purple Knight is designed to scan for AD vulnerabilities, misconfigurations, and common attack paths. While it is a legitimate tool used by defenders, its execution in production environments may also indicate red team activity or unauthorized reconnaissance by adversaries attempting to map domain weaknesses.

MITRE ATT&CK Coverage

TacticTechniques
Discovery

References

Telemetry Coverage

Rule Body

// Copyright 2025 Google LLC. Licensed under Apache-2.0.

rule hacktool_purpleknight_execution {

    meta:
      author = "Georg Lauenstein - suresecure GmbH"
      description = "This detection rule identifies the execution of the Purple Knight tool, a free Active Directory security assessment utility developed by Semperis. Purple Knight is designed to scan for AD vulnerabilities, misconfigurations, and common attack paths. While it is a legitimate tool used by defenders, its execution in production environments may also indicate red team activity or unauthorized reconnaissance by adversaries attempting to map domain weaknesses."
      rule_id = "mr_69e428bb-c946-4e3f-abb8-0e28316f2389"
      rule_name = "Purple Knight Tool Execution Detected"
      tactic = "TA0007"
      technique = "T1087"
      references = "https://www.purple-knight.com/"
      type = "alert"
      platform = "Windows, EDR"
      data_source = "Microsoft Sysmon, Windows Event Logs"
      severity = "Medium"  // Adjust based on your risk assessment
      priority = "Medium"  // Adjust based on your incident response process

    events:
      $purple_knight.metadata.event_type = "PROCESS_LAUNCH"
      (
        $purple_knight.target.process.file.full_path = /\\PurpleKnight\.exe$/ nocase or
        $purple_knight.principal.process.file.full_path = /\\PurpleKnight\.exe$/ nocase or
        $purple_knight.principal.process.command_line = /PurpleKnight/ nocase
      )

    // Capture the hostname where the event occurred
    $purple_knight.principal.hostname = $hostname

    match:
      $hostname over 10m

    outcome:
      $risk_score = max(65)
      $event_count = count_distinct($purple_knight.metadata.id)
      $principal_process_pid = array_distinct($purple_knight.principal.process.pid)
      $principal_process_command_line = array_distinct($purple_knight.principal.process.command_line)
      $principal_process_file_sha256 = array_distinct($purple_knight.principal.process.file.sha256)
      $principal_process_file_full_path = array_distinct($purple_knight.principal.process.file.full_path)
      $principal_process_product_specific_process_id = array_distinct($purple_knight.principal.process.product_specific_process_id)
      $principal_process_parent_process_product_specific_process_id = array_distinct($purple_knight.principal.process.parent_process.product_specific_process_id)
      $target_process_pid = array_distinct($purple_knight.target.process.pid)
      $target_process_command_line = array_distinct($purple_knight.target.process.command_line)
      $target_process_file_sha256 = array_distinct($purple_knight.target.process.file.sha256)
      $target_process_file_full_path = array_distinct($purple_knight.target.process.file.full_path)
      $target_process_product_specific_process_id = array_distinct($purple_knight.target.process.product_specific_process_id)
      $principal_user_userid = array_distinct($purple_knight.principal.user.userid)

    condition:
      $purple_knight
}

YARA-L Rule Structure

Condition

Fires when at least one $purple_knight event in the 10m window.

Events

$purple_knight PROCESS_LAUNCH (1, 4688)

  • target.process.file.full_path matches "\\PurpleKnight\.exe$"
  • principal.process.file.full_path matches "\\PurpleKnight\.exe$"
  • principal.process.command_line matches "PurpleKnight"

Match and Correlation

Match key
$hostname (principal.hostname)
Within
10m

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
risk_scoremax(65)
event_countcount_distinct($purple_knight.metadata.id)
principal_process_pidarray_distinct($purple_knight.principal.process.pid)
principal_process_command_linearray_distinct($purple_knight.principal.process.command_line)
principal_process_file_sha256array_distinct($purple_knight.principal.process.file.sha256)
principal_process_file_full_patharray_distinct($purple_knight.principal.process.file.full_path)
principal_process_product_specific_process_idarray_distinct($purple_knight.principal.process.product_specific_process_id)
principal_process_parent_process_product_specific_process_idarray_distinct($purple_knight.principal.process.parent_process.product_specific_process_id)
target_process_pidarray_distinct($purple_knight.target.process.pid)
target_process_command_linearray_distinct($purple_knight.target.process.command_line)
target_process_file_sha256array_distinct($purple_knight.target.process.file.sha256)
target_process_file_full_patharray_distinct($purple_knight.target.process.file.full_path)
target_process_product_specific_process_idarray_distinct($purple_knight.target.process.product_specific_process_id)
principal_user_useridarray_distinct($purple_knight.principal.user.userid)

sap change documents sensitive role assignment

#
Severity
critical
Time window
30m
Match by
principal_user
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Detects the assignment of highly privileged SAP roles via Change Documents.

MITRE ATT&CK Coverage

TacticTechniques
Privilege Escalation

Rule Body

// Copyright 2026 Google LLC. Licensed under Apache-2.0.

rule sap_change_documents_sensitive_role_assignment {

    meta:
        author = "Google Cloud Security"
        description = "Detects the assignment of highly privileged SAP roles via Change Documents."
        severity = "Critical"
        tactic = "TA0004"
        technique = "T1098"

    events:
        $e.metadata.log_type = "SAP_CHANGE_DOCUMENT"
        $e.target.resource.product_object_id in %sap_sensitive_roles.role

        $principal_user = $e.principal.user.userid


    match:
        $principal_user over 30m

    outcome:
        $target_user = array_distinct($e.target.resource.product_object_id)
        $tcode = array_distinct($e.target.application)
        $tabname = array_distinct($e.target.resource.attribute.labels["TABNAME"])
        $sensitive_role_assigned = array_distinct($e.target.resource.attribute.labels["TABKEY"])

    condition:
        $e

}

YARA-L Rule Structure

Condition

Fires when at least one $e event in the 30m window.

Events

$e

  • metadata.log_type = "SAP_CHANGE_DOCUMENT"
  • target.resource.product_object_id in "%sap_sensitive_roles.role"

Match and Correlation

Match key
$principal_user
Within
30m

Outcome

Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.

FieldExpression
target_userarray_distinct($e.target.resource.product_object_id)
tcodearray_distinct($e.target.application)
tabnamearray_distinct($e.target.resource.attribute.labels["TABNAME"])
sensitive_role_assignedarray_distinct($e.target.resource.attribute.labels["TABKEY"])

Back to all YARA-L rules