Detection rules › YARA-L

YARA-L rules: 32

AWS Password Policy Change

#
Severity
medium
Type
Alert
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Detects when an existing password policy is updated or deleted in an AWS account.

MITRE ATT&CK Coverage

TacticTechniques
Discovery

Telemetry Coverage

Rule Body

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

rule aws_password_policy_change {

  meta:
    author = "Google Cloud Security"
    description = "Detects when an existing password policy is updated or deleted in an AWS account."
    rule_id = "mr_2e66b918-acfc-46ea-b625-58732558005d"
    rule_name = "AWS Password Policy Change"
    mitre_attack_tactic = "Discovery"
    mitre_attack_technique = "Password Policy Discovery"
    mitre_attack_url = "https://attack.mitre.org/techniques/T1201/"
    mitre_attack_version = "v13.1"
    type = "Alert"
    data_source = "AWS CloudTrail"
    platform = "AWS"
    severity = "Medium"
    priority = "Medium"

  events:
    $cloudtrail.metadata.vendor_name = "AMAZON"
    $cloudtrail.metadata.product_name = "AWS CloudTrail"
    (
     $cloudtrail.metadata.product_event_type = "UpdateAccountPasswordPolicy" or
     $cloudtrail.metadata.product_event_type = "DeleteAccountPasswordPolicy"
    )
    $cloudtrail.security_result.action = "ALLOW"

  outcome:
    $risk_score = max(50)
    $mitre_attack_tactic = "Discovery"
    $mitre_attack_technique = "Password Policy Discovery"
    $mitre_attack_technique_id = "T1201"
    $event_count = count_distinct($cloudtrail.metadata.id)
    $network_http_user_agent = $cloudtrail.network.http.user_agent
    $principal_ip = array_distinct($cloudtrail.principal.ip)
    $principal_ip_country = array_distinct($cloudtrail.principal.ip_geo_artifact.location.country_or_region)
    $principal_ip_state = array_distinct($cloudtrail.principal.ip_geo_artifact.location.state)
    $principal_user_display_name = $cloudtrail.principal.user.user_display_name
    $recipient_aws_account_id = $cloudtrail.additional.fields["recipientAccountId"]
    $aws_region = $cloudtrail.principal.location.name

  condition:
    $cloudtrail
}

YARA-L Rule Structure

Condition

Fires when at least one $cloudtrail event.

Events

$cloudtrail

  • metadata.product_event_type is one of:
    • UpdateAccountPasswordPolicy
    • DeleteAccountPasswordPolicy
  • security_result.action = "ALLOW"

Outcome

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

FieldExpression
risk_scoremax(50)
event_countcount_distinct($cloudtrail.metadata.id)
network_http_user_agent$cloudtrail.network.http.user_agent
principal_iparray_distinct($cloudtrail.principal.ip)
principal_ip_countryarray_distinct($cloudtrail.principal.ip_geo_artifact.location.country_or_region)
principal_ip_statearray_distinct($cloudtrail.principal.ip_geo_artifact.location.state)
principal_user_display_name$cloudtrail.principal.user.user_display_name
recipient_aws_account_id$cloudtrail.additional.fields["recipientAccountId"]
aws_region$cloudtrail.principal.location.name

DNS Query To Recently Created Domain

#
Severity
low
Type
alert
Time window
1h
Match by
user
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

DNS query to a recently created domain

Telemetry Coverage

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

Rule Body

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

rule dns_query_to_recently_created_domain {

  meta:
    author = "Google Cloud Security"
    description = "DNS query to a recently created domain"
    rule_id = "mr_a5cff3f1-8092-48a0-b4a3-f3f856299474"
    rule_name = "DNS Query To Recently Created Domain"
    type = "alert"
    tags = "whois"
    data_source = "microsoft sysmon"
    severity = "Low"
    priority = "Low"

  events:
    $dns.metadata.event_type = "NETWORK_DNS"
    $dns.network.dns.questions.name = $dns_query
    $dns.principal.user.userid = $user

    // whois data provided by GCTI
    $whois.graph.entity.hostname = $dns_query
    $whois.graph.metadata.entity_type = "DOMAIN_NAME"
    $whois.graph.metadata.vendor_name = "WHOIS"
    $whois.graph.entity.domain.creation_time.seconds > 0
    // domain was created in the last 30 days
    2592000 > timestamp.current_seconds() - $whois.graph.entity.domain.creation_time.seconds

  match:
    $user over 1h

  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)
   // Commented out principal.user.userid because it is already represented in graph as match variable. If match changes, can uncomment to add to results
   //$principal_user_userid = array_distinct($dns.principal.user.userid)

  condition:
    $dns and $whois
}

YARA-L Rule Structure

Condition

Fires when at least one $dns event in the 1h window and $whois matches entity context.

Events

$dns NETWORK_DNS (22)

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

$whois entity context (DOMAIN_NAME)

  • graph.metadata.entity_type = "DOMAIN_NAME"
  • graph.metadata.vendor_name = "WHOIS"
  • graph.entity.domain.creation_time.seconds > "0"
  • timestamp.current_seconds() time_arithmetic "graph.entity.domain.creation_time.seconds" or "2592000"

Match and Correlation

Match key
$user (principal.user.userid)
Within
1h

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)

GitHub Enterprise Deleted

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

Detects when a GitHub enterprise is deleted.

MITRE ATT&CK Coverage

TacticTechniques
Impact

References

Telemetry Coverage

Rule Body

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

rule github_enterprise_deleted {

  meta:
    author = "Google Cloud Security"
    description = "Detects when a GitHub enterprise is deleted."
    rule_id = "mr_6443a51b-c381-4504-9b45-9d8b5e9531d7"
    rule_name = "GitHub Enterprise 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 = "High"
    priority = "High"
    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 = "business.delete"
    $github.principal.user.userid = $user_id
    $github.target.user.company_name = $github_enterprise_name

  match:
    $user_id, $github_enterprise_name over 30m

outcome:
    $risk_score = max(85)
    $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 = "business.delete"

Match and Correlation

Match key
$github_enterprise_name (target.user.company_name), $user_id (principal.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_scoremax(85)
event_countcount_distinct($github.metadata.id)
principal_iparray_distinct($github.principal.ip)
principal_user_useridarray_distinct($github.principal.user.userid)
principal_ip_countryarray_distinct($github.principal.ip_geo_artifact.location.country_or_region)
principal_ip_statearray_distinct($github.principal.ip_geo_artifact.location.state)
principal_ip_cityarray_distinct($github.principal.location.city)
security_result_summaryarray_distinct($github.security_result.summary)

GitHub Outgoing Repository Transfer Initiated

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

Detects when a GitHub repository is transferred.

References

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

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

rule github_outgoing_repository_transfer_initiated {

  meta:
    author = "Google Cloud Security"
    description = "Detects when a GitHub repository is transferred."
    rule_id = "mr_28486f60-1be2-467c-a3e6-6105491c3226"
    rule_name = "GitHub Outgoing Repository Transfer Initiated"
    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 = "High"
    priority = "High"
    platform = "GitHub"
    data_source = "github"
    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.transfer_outgoing"
    $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(85)
    $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.transfer_outgoing"

Match and Correlation

Match key
$github_repo_name (target.resource.name), $user_id (principal.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_scoremax(85)
event_countcount_distinct($github.metadata.id)
principal_iparray_distinct($github.principal.ip)
principal_user_useridarray_distinct($github.principal.user.userid)
principal_ip_countryarray_distinct($github.principal.ip_geo_artifact.location.country_or_region)
principal_ip_statearray_distinct($github.principal.ip_geo_artifact.location.state)
principal_ip_cityarray_distinct($github.principal.location.city)
security_result_summaryarray_distinct($github.security_result.summary)

MITRE ATT&CK T1090 Port Proxy Forwarding CISA Report

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

Detects port forwarding being enabled using netsh command and registry settings created or modified in support of portproxy v4tov4

MITRE ATT&CK Coverage

TacticTechniques
Command & Control

References

Telemetry Coverage

Rule Body

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

rule port_proxy_forwarding_T1090_cisa_report {

  meta:
    author = "Google Cloud Security"
    description = "Detects port forwarding being enabled using netsh command and registry settings created or modified in support of portproxy v4tov4"
    rule_id = "mr_4c6f2d66-ed6f-4dda-bd2f-7c545898468b"
    rule_name = "MITRE ATT&CK T1090 Port Proxy Forwarding CISA Report"
    type = "hunt"
    platform = "Windows"
    data_source = "microsoft sysmon, windows event log"
    tactic = "TA0011"
    technique = "T1090"
    reference = "https://media.defense.gov/2023/May/24/2003229517/-1/-1/0/CSA_Living_off_the_Land.PDF"
    severity = "Low"
    priority = "Low"

  events:
    (
        $process.metadata.event_type = "PROCESS_LAUNCH" and

        // cisa report referenced cmd /c in their report throughout, can filter this in/out for tuning as needed
        re.regex($process.target.process.command_line, `(|cmd.*/c).*netsh.*interface.*portproxy.*add.*v4tov4`) nocase
        // For greater precision to align with the report, comment out the above line and uncomment the below line to incorporate exact ports referenced
        //re.regex($process.target.process.command_line, `(|cmd.*/c).*netsh.*interface.*portproxy.*add.*v4tov4.*port\=(9999|50100).*port\=(8443|1433)`) nocase
    )
    or
    (
        // Looks for the actual registry creation or modification that would accompany portproxy command executing
        (
        $process.metadata.event_type = "REGISTRY_CREATION" or
        $process.metadata.event_type = "REGISTRY_MODIFICATION"
        ) and
        $process.target.registry.registry_key = "HKLM\\System\\CurrentControlSet\\Services\\PortProxy\\v4tov4"
    )

    $process.principal.hostname = $hostname

  match:
    $hostname over 5m

  outcome:
    $risk_score = 35
    $event_count = count_distinct($process.metadata.id)
    // 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, 12, 13, 4656, 4657, 4688)

  • target.process.command_line matches "(|cmd.*/c).*netsh.*interface.*portproxy.*add.*v4tov4"
  • target.registry.registry_key = "HKLM\System\CurrentControlSet\Services\PortProxy\v4tov4"

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_score35
event_countcount_distinct($process.metadata.id)
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)

MITRE ATT&CK T1570 Suspicious Command PSExec

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

Command-line execution of the PsExec tool on Windows

MITRE ATT&CK Coverage

TacticTechniques
Lateral Movement

Telemetry Coverage

Rule Body

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

rule mitre_attack_T1570_suspicious_command_psexec {

  meta:
    author = "Google Cloud Security"
    description = "Command-line execution of the PsExec tool on Windows"
    rule_id = "mr_b1c34e7b-79c2-4d44-a105-d8166f6fd2c5"
    rule_name = "MITRE ATT&CK T1570 Suspicious Command PSExec"
    tactic = "TA0008"
    technique = "T1570"
    type = "alert"
    platform = "Windows"
    data_source = "sentinelone"
    severity = "Info"
    priority = "Info"

  events:
    $process.metadata.event_type = "PROCESS_LAUNCH"
    $process.principal.hostname = $hostname
    re.regex($process.principal.process.command_line, `psexec`) nocase

  match:
    $hostname over 5m

  outcome:
    $risk_score = 15
    $event_count = count_distinct($process.metadata.id)
    // 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)

  • principal.process.command_line matches "psexec"

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_score15
event_countcount_distinct($process.metadata.id)
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)

Back to all YARA-L rules