Detection rules › YARA-L

YARA-L rules: 1e

GitHub User Blocked From Accessing Organization Repositories

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

Detects when a user is blocked from accessing repositories within a GitHub organization.

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_user_blocked_from_accessing_organization_repositories {

  meta:
    author = "Google Cloud Security"
    description = "Detects when a user is blocked from accessing repositories within a GitHub organization."
    rule_id = "mr_f422422c-7a15-47da-accd-b499b8d0b33f"
    rule_name = "GitHub User Blocked From Accessing Organization Repositories"
    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"
    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 = "org.block_user"
    $github.principal.user.userid = $actor_user_id
    $github.extracted.fields["blocked_user"] = $target_user_id

  match:
    $actor_user_id, $target_user_id over 30m

  outcome:
    $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)

  condition:
    $github
}

YARA-L Rule Structure

Condition

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

Events

$github

  • metadata.product_event_type = "org.block_user"

Match and Correlation

Match key
$actor_user_id (principal.user.userid), $target_user_id (extracted.fields["blocked_user"])
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(35)
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)

Okta User Password and MFA Factor Reset or Deactivated

#
Severity
medium
Type
Alert
Time window
30m
Match by
user_id
Author
Drew Pilarski - Tempus AI
Source
github.com/chronicle/detection-rules

Detects when an Okta user's password is reset and MFA factor(s) are deactivated or reset within a 30 minute time window. This activity may indicate that the user account has been compromised.

MITRE ATT&CK Coverage

References

Telemetry Coverage

Rules Detecting the Same Action

These rules filter on the same operation.

Rule Body

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

rule okta_user_password_and_mfa_factor_reset_or_deactivated {

  meta:
    author = "Drew Pilarski - Tempus AI"
    description = "Detects when an Okta user's password is reset and MFA factor(s) are deactivated or reset within a 30 minute time window. This activity may indicate that the user account has been compromised."
    rule_id = "mr_a4344fef-2310-4fed-8f3a-8e76237cfc1f"
    rule_name = "Okta User Password and MFA Factor Reset or Deactivated"
    reference = "https://developer.okta.com/docs/reference/api/event-types/"
    mitre_attack_tactic = "Credential Access, Defense Evasion, Persistence"
    mitre_attack_technique = "Modify Authentication Process: Multi-Factor Authentication"
    mitre_attack_url = "https://attack.mitre.org/techniques/T1556/006/"
    type = "Alert"
    platform = "Okta"
    data_source = "Okta"
    severity = "Medium"
    priority = "Medium"

  events:
    $pw.metadata.product_name = "Okta"
    $pw.metadata.vendor_name = "Okta"
    (
        $pw.metadata.product_event_type = "user.mfa.factor.reset_all" OR
        $pw.metadata.product_event_type = "user.mfa.factor.deactivate"
    )

    $user_id = $pw.target.user.product_object_id

    $mfa.metadata.product_name = "Okta"
    $mfa.metadata.vendor_name = "Okta"
    $mfa.metadata.product_event_type = "user.account.reset_password"

    $user_id = $mfa.target.user.product_object_id

    match:
      $user_id over 30m

  outcome:
    $principal_user_email = array_distinct($pw.principal.user.email_addresses)
    $principal_ip = array_distinct($pw.principal.ip)
    $risk_score = 65
    $mitre_attack_tactic = array_distinct("Credential Access, Defense Evasion, Persistence")
    $mitre_attack_technique = array_distinct("Modify Authentication Process: Multi-Factor Authentication")
    $mitre_attack_technique_id = array_distinct("T1556.006")

  condition:
    $pw and $mfa
}

YARA-L Rule Structure

Condition

Fires when at least one $pw event in the 30m window and at least one $mfa event in the 30m window.

Events

$mfa

  • metadata.product_event_type = "user.account.reset_password"

$pw

  • metadata.product_event_type is one of:
    • user.mfa.factor.reset_all
    • user.mfa.factor.deactivate

Match and Correlation

Match key
$user_id
Within
30m

Outcome

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

FieldExpression
principal_user_emailarray_distinct($pw.principal.user.email_addresses)
principal_iparray_distinct($pw.principal.ip)
risk_score65

Process Memory Dump Via Comsvcs.DLL

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

Detects a process memory dump via comsvcs.dll using rundll32, covering multiple different techniques

Known False Positives

  • Unlikely

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

References

Telemetry Coverage

Rule Body

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

rule process_memory_dump_via_comsvcs_dll {

  meta:
    author = "Florian Roth (Nextron Systems), Modexp, Nasreddine Bencherchali (Nextron Systems), Swachchhanda Shrawan Poudel (Nextron Systems)"
    description = "Detects a process memory dump via comsvcs.dll using rundll32, covering multiple different techniques"
    reference = "https://github.com/SigmaHQ/sigma/blob/master/rules/windows/process_creation/proc_creation_win_rundll32_process_dump_via_comsvcs.yml"
    license = "https://github.com/SigmaHQ/Detection-Rule-License/blob/main/LICENSE.Detection.Rules.md"
    rule_name = "Process Memory Dump Via Comsvcs.DLL"
    sigma_uuid = "646ea171-dded-4578-8a4d-65e9822892e3"
    sigma_status = "test"
    rule_id = "mr_ad21bd09-c624-48c8-a949-a82a40fbb88c"
    tactic = "TA0006"
    technique = "T1003.001"
    type = "Detection"
    data_source = "Sysmon"
    platform = "Windows"
    severity = "High"
    priority = "High"
    false_positives = "Unlikely"

  events:
    $process.metadata.event_type = "PROCESS_LAUNCH"
    (
        (
            (
                re.regex($process.target.process.file.full_path, `\\rundll32\.exe$`) nocase or
                $process.src.process.file.full_path = "RUNDLL32.EXE" nocase or
                strings.contains(strings.to_lower($process.target.process.command_line), "rundll32")
            )
            and
            (
                (
                    strings.contains(strings.to_lower($process.target.process.command_line), "comsvcs") and
                    strings.contains(strings.to_lower($process.target.process.command_line), "full")
                )
                or
                (
                    strings.contains($process.target.process.command_line, "#-") or
                    strings.contains($process.target.process.command_line, "#+") or
                    strings.contains($process.target.process.command_line, "#24") or
                    strings.contains(strings.to_lower($process.target.process.command_line), "minidump")
                )
            )
        )
        or
        (
                (
                    strings.contains($process.target.process.command_line, "24") and
                    strings.contains(strings.to_lower($process.target.process.command_line), "comsvcs") and
                    strings.contains(strings.to_lower($process.target.process.command_line), "full")
                )
                and
                (
                    strings.contains($process.target.process.command_line, " #") or
                    strings.contains($process.target.process.command_line, ",#") or
                    strings.contains($process.target.process.command_line, ", #")
                )
        )
    )
    $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.file.full_path matches "\\rundll32\.exe$"
  • src.process.file.full_path = "RUNDLL32.EXE"
  • target.process.command_line contains "rundll32"
  • target.process.command_line contains "comsvcs"
  • target.process.command_line contains "full"
  • target.process.command_line contains "#-"
  • target.process.command_line contains "#+"
  • target.process.command_line contains "#24"
  • target.process.command_line contains "minidump"
  • target.process.command_line contains "24"
  • target.process.command_line contains "comsvcs"
  • target.process.command_line contains "full"
  • target.process.command_line contains " #"
  • target.process.command_line contains ",#"
  • target.process.command_line contains ", #"

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))

sap impossible travel

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

Identifies two successful logons for the same User ID from two different geographic locations in a timeframe that is physically impossible to travel between, indicating credential sharing or theft.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access
Persistence
Privilege Escalation
Stealth

Telemetry Coverage

Rule Body

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

rule sap_impossible_travel {

  meta:
    author = "Google Cloud Security"
    description = "Identifies two successful logons for the same User ID from two different geographic locations in a timeframe that is physically impossible to travel between, indicating credential sharing or theft."
    severity = "medium"
    tactic = "TA0006"
    technique = "T1078"

  events:
    $e.metadata.log_type = "SAP_SECURITY_AUDIT"
    (
        $e.metadata.event_type = "USER_LOGIN" or
        $e.additional.fields["msg_1"] = /^AU1$|^AU5$/
    )
    $e.principal.ip_geo_artifact.location.country_or_region != ""

    $country = $e.principal.ip_geo_artifact.location.country_or_region
    $state = $e.principal.ip_geo_artifact.location.state
    $user = $e.principal.user.userid

  match:
    $user over 1h

  outcome:
    $countries = array_distinct($country)
    $states = array_distinct($state)
    $count_of_countries = count_distinct($country)
    $count_of_states = count_distinct($state)
    $risk_score = if(count_distinct($country) > 1, 30, 0) + if(count_distinct($state) > 2, 30, 0) + 30
    $network_carrier_name = array_distinct($e.principal.ip_geo_artifact.network.carrier_name)
    $networn_dns_domain = array_distinct($e.principal.ip_geo_artifact.network.dns_domain)
    $network_org = array_distinct($e.principal.ip_geo_artifact.network.organization_name)
    $sap_instance = array_distinct($e.target.resource.name)

  condition:
    #country >= 2 or #state >= 2
}

YARA-L Rule Structure

Condition

Fires when $country occurs at least 2 times in the 1h window or $state occurs at least 2 times in the 1h window.

Events

$e USER_LOGIN (4624, 4625, 4648)

  • metadata.log_type = "SAP_SECURITY_AUDIT"
  • additional.fields["msg_1"] matches "^AU1$|^AU5$"
  • principal.ip_geo_artifact.location.country_or_region is not null

Match and Correlation

Match key
$user
Within
1h

Outcome

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

FieldExpression
countriesarray_distinct($country)
statesarray_distinct($state)
count_of_countriescount_distinct($country)
count_of_statescount_distinct($state)
risk_scoreif(count_distinct($country) > 1, 30, 0) + if(count_distinct($state) > 2, 30, 0) + 30
network_carrier_namearray_distinct($e.principal.ip_geo_artifact.network.carrier_name)
networn_dns_domainarray_distinct($e.principal.ip_geo_artifact.network.dns_domain)
network_orgarray_distinct($e.principal.ip_geo_artifact.network.organization_name)
sap_instancearray_distinct($e.target.resource.name)

Back to all YARA-L rules