Detection rules › YARA-L

YARA-L rules: 16

GitHub Secret Scanning Alert

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

Detects when a secret is found in a GitHub repository. Adversaries may attempt to harvest leaked/exposed secrets to further infiltrate their target's environment, maintain access, or steal data.

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

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

  meta:
    author = "Google Cloud Security"
    description = "Detects when a secret is found in a GitHub repository. Adversaries may attempt to harvest leaked/exposed secrets to further infiltrate their target's environment, maintain access, or steal data."
    rule_id = "mr_7cd99259-68ef-4b09-96a5-3130f44664b5"
    rule_name = "GitHub Secret Scanning Alert"
    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 = "Credential Access"
    mitre_attack_technique = "Unsecured Credentials"
    mitre_attack_url = "https://attack.mitre.org/versions/v14/techniques/T1552/"
    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 = "secret_scanning_alert.create"

  outcome:
    $risk_score = max(85)
    $mitre_attack_tactic = "Credential Access"
    $mitre_attack_technique = "Unsecured Credentials"
    $mitre_attack_technique_id = "T1552"
    $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.

Events

$github

  • metadata.product_event_type = "secret_scanning_alert.create"

Outcome

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

FieldExpression
risk_scoremax(85)
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)

Hunt for successful group creation in the Microsoft Graph API

#
Severity
low
Type
Hunt
Time window
5m
Match by
ip, session
Author
Google Cloud Security
Source
github.com/chronicle/detection-rules

Identify a successful group creation. Triggered through the use of GraphRunner's Invoke-SecurityGroupCloner function.

References

Rule Body

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

rule ms_graph_group_creation_success {

  meta:
    author = "Google Cloud Security"
    description = "Identify a successful group creation. Triggered through the use of GraphRunner's Invoke-SecurityGroupCloner function."
    rule_id = "mr_04b3df2c-470f-4b4d-9382-cdbe0539e5ec"
    rule_name = "Hunt for successful group creation in the Microsoft Graph API"
    assumption = "This detects all web activity associated with the groups endpoint with a response code 201, normal admin actions could trigger as well. Tune using IP address ranges for admins and user agents."
    reference = "https://github.com/dafthack/GraphRunner/blob/main/GraphRunner.ps1"
    type = "Hunt"
    data_source = "MS Graph Activity Logs"
    platform = "Azure"
    severity = "Low"
    priority = "Low"

  events:
    $api.metadata.event_type = "NETWORK_HTTP"
    $api.metadata.product_event_type = "Microsoft Graph Activity"
    $api.target.url = "https://graph.microsoft.com/v1.0/groups" nocase
    $api.network.http.method = "POST"
    $api.network.http.response_code = 201
    //Can be tuned for specific User Agent strings being used - by default GraphRunner does not forge the UA for this action
    //$api.network.http.user_agent = /PowerShell/ nocase
    $api.principal.ip = $ip
    $api.network.session_id = $session

  match:
    $ip, $session over 5m

  outcome:
    $risk_score = 35
    $event_count = count_distinct($api.metadata.id)
    $requesting_user_guid = array_distinct($api.principal.user.userid)
    $requesting_ip = array_distinct($api.principal.ip)
    $user_agent = array_distinct($api.network.http.user_agent)
    $location = array_distinct($api.principal.location.name)
    $target_application_id_guid = array_distinct($api.target.resource.product_object_id)
    $session_id = array_distinct($api.network.session_id)
    $target_url = array_distinct($api.target.url)

  condition:
    $api
}

YARA-L Rule Structure

Condition

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

Events

$api NETWORK_HTTP

  • metadata.product_event_type = "Microsoft Graph Activity"
  • target.url = "https://graph.microsoft.com/v1.0/groups"
  • network.http.method = "POST"
  • network.http.response_code = "201"

Match and Correlation

Match key
$ip (principal.ip), $session (network.session_id)
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($api.metadata.id)
requesting_user_guidarray_distinct($api.principal.user.userid)
requesting_iparray_distinct($api.principal.ip)
user_agentarray_distinct($api.network.http.user_agent)
locationarray_distinct($api.principal.location.name)
target_application_id_guidarray_distinct($api.target.resource.product_object_id)
session_idarray_distinct($api.network.session_id)
target_urlarray_distinct($api.target.url)

IOC IP Target

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

Detect network events that indicate communication to a watchlisted IP address

Telemetry Coverage

Rule Body

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

rule ioc_ip_target {

  meta:
    author = "Google Cloud Security"
    description = "Detect network events that indicate communication to a watchlisted IP address"
    rule_id = "mr_cb71b798-5931-47a9-8572-8166db41fc5c"
    rule_name = "IOC IP Target"
    type = "alert"
    tags = "threat indicators"
    assumption = "Assumes MISP data has been ingested into entity graph; this rule can be modified to utilize other TI indicators"
    data_source = "microsoft windows events"
    severity = "Medium"
    priority = "Medium"

  events:
    $network.metadata.event_type = "NETWORK_CONNECTION"
    $network.target.ip = $ip
    //Target IP is not part of RFC1918 space, can modify as needed
    not net.ip_in_range_cidr($network.target.ip, "10.0.0.0/24")
    not net.ip_in_range_cidr($network.target.ip, "172.16.0.0/12")
    not net.ip_in_range_cidr($network.target.ip, "192.168.0.0/16")

    // Correlates with MISP data; can be modified based on your MISP parser or other TI
    $ioc.graph.metadata.product_name = "MISP"
    $ioc.graph.metadata.entity_type = "IP_ADDRESS"
    $ioc.graph.metadata.source_type = "ENTITY_CONTEXT"
    $ioc.graph.entity.ip = $ip

  match:
    $ip over 5m

  outcome:
    $risk_score = 65
    $event_count = count_distinct($network.metadata.id)
    // added to populate alert graph with additional context
    $principal_ip = array_distinct($network.principal.ip)
    // Commented out target.ip because it is already represented in graph as match variable. If match changes, can uncomment to add to results
    //$target_ip = array_distinct($network.target.ip)
    $principal_process_pid = array_distinct($network.principal.process.pid)
    $principal_process_command_line = array_distinct($network.principal.process.command_line)
    $principal_process_file_sha256 = array_distinct($network.principal.process.file.sha256)
    $principal_process_file_full_path = array_distinct($network.principal.process.file.full_path)
    $principal_process_product_specific_process_id = array_distinct($network.principal.process.product_specific_process_id)
    $principal_process_parent_process_product_specific_process_id = array_distinct($network.principal.process.parent_process.product_specific_process_id)
    $target_process_pid = array_distinct($network.target.process.pid)
    $target_process_command_line = array_distinct($network.target.process.command_line)
    $target_process_file_sha256 = array_distinct($network.target.process.file.sha256)
    $target_process_file_full_path = array_distinct($network.target.process.file.full_path)
    $target_process_product_specific_process_id = array_distinct($network.target.process.product_specific_process_id)
    $target_process_parent_process_product_specific_process_id = array_distinct($network.target.process.parent_process.product_specific_process_id)
    $principal_user_userid = array_distinct($network.principal.user.userid)
    $target_user_userid = array_distinct($network.target.user.userid)

  condition:
    $network and $ioc
}

YARA-L Rule Structure

Condition

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

Events

$ioc entity context (IP_ADDRESS)

  • graph.metadata.product_name = "MISP"
  • graph.metadata.entity_type = "IP_ADDRESS"
  • graph.metadata.source_type = "ENTITY_CONTEXT"

$network NETWORK_CONNECTION (3, 5156)

  • target.ip cidr_match "10.0.0.0/24"
  • target.ip cidr_match "172.16.0.0/12"
  • target.ip cidr_match "192.168.0.0/16"

Match and Correlation

Match key
$ip (target.ip)
Within
5m

Outcome

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

FieldExpression
risk_score65
event_countcount_distinct($network.metadata.id)
principal_iparray_distinct($network.principal.ip)
principal_process_pidarray_distinct($network.principal.process.pid)
principal_process_command_linearray_distinct($network.principal.process.command_line)
principal_process_file_sha256array_distinct($network.principal.process.file.sha256)
principal_process_file_full_patharray_distinct($network.principal.process.file.full_path)
principal_process_product_specific_process_idarray_distinct($network.principal.process.product_specific_process_id)
principal_process_parent_process_product_specific_process_idarray_distinct($network.principal.process.parent_process.product_specific_process_id)
target_process_pidarray_distinct($network.target.process.pid)
target_process_command_linearray_distinct($network.target.process.command_line)
target_process_file_sha256array_distinct($network.target.process.file.sha256)
target_process_file_full_patharray_distinct($network.target.process.file.full_path)
target_process_product_specific_process_idarray_distinct($network.target.process.product_specific_process_id)
target_process_parent_process_product_specific_process_idarray_distinct($network.target.process.parent_process.product_specific_process_id)
principal_user_useridarray_distinct($network.principal.user.userid)
target_user_useridarray_distinct($network.target.user.userid)

Recon Credential Theft CISA Report

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

Detects suspicious credential access commands as identified in CISA Living off the Land pdf. Alone they may be normal but in concert, they may be worth looking into

MITRE ATT&CK Coverage

TacticTechniques
Credential Access

References

Telemetry Coverage

Rule Body

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

rule recon_credential_theft_cisa_report {

  meta:
    author = "Google Cloud Security"
    description = "Detects suspicious credential access commands as identified in CISA Living off the Land pdf. Alone they may be normal but in concert, they may be worth looking into"
    rule_id = "mr_90b80326-d559-4e82-b5da-613e5406127a"
    rule_name = "Recon Credential Theft CISA Report"
    type = "hunt"
    platform = "Windows"
    data_source = "microsoft sysmon"
    tactic = "TA0006"
    technique = "T1555"
    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"
    $process.principal.hostname = $hostname
    $process.target.process.command_line = $command_line

    // 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).*dir.*C:\\Users\\.*\\.ssh\\known_hosts`) nocase or
        re.regex($process.target.process.command_line, `(|cmd.*/c).*dir.*C:\\users\\.*\\appdata\\roaming\\Mozilla\\firefox\\profiles`) nocase or
        re.regex($process.target.process.command_line, `(|cmd.*/c).*mimikatz`) nocase or
        re.regex($process.target.process.command_line, `(|cmd.*/c).*reg.*query.*hklm\\software\\OpenSSH`) nocase or
        re.regex($process.target.process.command_line, `(|cmd.*/c).*reg.*query.*hklm\\software\\OpenSSH\\Agent`) nocase or
        re.regex($process.target.process.command_line, `(|cmd.*/c).*reg.*query.*hklm\\software\\realvnc`) nocase or
        re.regex($process.target.process.command_line, `(|cmd.*/c).*reg.*query.*hklm\\software\\realvnc\\vncserver`) nocase or
        re.regex($process.target.process.command_line, `(|cmd.*/c).*reg.*query.*hklm\\software\\realvnc\\Allusers`) nocase or
        re.regex($process.target.process.command_line, `(|cmd.*/c).*reg.*query.*hklm\\software\\realvnc\\Allusers\\vncserver`) nocase or
        re.regex($process.target.process.command_line, `(|cmd.*/c).*reg.*query.*hkcu\\software\\.*\\putty\\session`) nocase or
        re.regex($process.target.process.command_line, `(|cmd.*/c).*reg.*save.*hklm\\sam ss.dat`) nocase or
        re.regex($process.target.process.command_line, `(|cmd.*/c).*reg.*save.*hklm\\system sy.dat`) nocase
    )

  match:
    $hostname over 15m

  outcome:
    $risk_score = 35
    $event_count = count_distinct($process.metadata.id)
    $unique_command_line_threshold = max(5)
    // 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:
    // modify the condition value for command line to throttle how many of these commands can be issued until the rule is triggered
    $process and #command_line > 5
}

YARA-L Rule Structure

Condition

Fires when at least one $process event in the 15m window and $command_line occurs more than 5 times in the 15m window.

Events

$process PROCESS_LAUNCH (1, 4688)

  • target.process.command_line matches "(|cmd.*/c).*dir.*C:\\Users\\.*\\.ssh\\known_hosts"
  • target.process.command_line matches "(|cmd.*/c).*dir.*C:\\users\\.*\\appdata\\roaming\\Mozilla\\firefox\\profiles"
  • target.process.command_line matches "(|cmd.*/c).*mimikatz"
  • target.process.command_line matches "(|cmd.*/c).*reg.*query.*hklm\\software\\OpenSSH"
  • target.process.command_line matches "(|cmd.*/c).*reg.*query.*hklm\\software\\OpenSSH\\Agent"
  • target.process.command_line matches "(|cmd.*/c).*reg.*query.*hklm\\software\\realvnc"
  • target.process.command_line matches "(|cmd.*/c).*reg.*query.*hklm\\software\\realvnc\\vncserver"
  • target.process.command_line matches "(|cmd.*/c).*reg.*query.*hklm\\software\\realvnc\\Allusers"
  • target.process.command_line matches "(|cmd.*/c).*reg.*query.*hklm\\software\\realvnc\\Allusers\\vncserver"
  • target.process.command_line matches "(|cmd.*/c).*reg.*query.*hkcu\\software\\.*\\putty\\session"
  • target.process.command_line matches "(|cmd.*/c).*reg.*save.*hklm\\sam ss.dat"
  • target.process.command_line matches "(|cmd.*/c).*reg.*save.*hklm\\system sy.dat"

Match and Correlation

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

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)
unique_command_line_thresholdmax(5)
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)

Wdigest Enable UseLogonCredential

#
Severity
high
Type
Detection
Time window
5m
Match by
hostname
Author
Roberto Rodriguez (Cyb3rWard0g), OTR (Open Threat Research)
Source
github.com/chronicle/detection-rules

Detects potential malicious modification of the property value of UseLogonCredential from HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest to enable clear-text credentials

Known False Positives

  • Unknown

MITRE ATT&CK Coverage

TacticTechniques
Persistence
Defense Impairment

References

Telemetry Coverage

Rule Body

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

rule wdigest_enable_uselogoncredential {

  meta:
    author = "Roberto Rodriguez (Cyb3rWard0g), OTR (Open Threat Research)"
    description = "Detects potential malicious modification of the property value of UseLogonCredential from HKLM:\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\WDigest to enable clear-text credentials"
    reference = "https://github.com/SigmaHQ/sigma/blob/master/rules/windows/registry/registry_set/registry_set_wdigest_enable_uselogoncredential.yml"
    license = "https://github.com/SigmaHQ/Detection-Rule-License/blob/main/LICENSE.Detection.Rules.md"
    rule_name = "Wdigest Enable UseLogonCredential"
    rule_id = "mr_b91eeb90-12e0-40f2-878c-a4716fe722bc"
    sigma_uuid = "d6a9b252-c666-4de6-8806-5561bbbd3bdc"
    sigma_status = "test"
    tactic = "TA0005"
    technique = "T1112"
    type = "Detection"
    data_source = "Sysmon Windows Registry"
    platform = "Windows"
    severity = "High"
    priority = "High"
    false_positives = "Unknown"

  events:
    $reg.metadata.event_type = "REGISTRY_MODIFICATION"
    re.regex($reg.target.registry.registry_key, `WDigest\\UseLogonCredential$`) nocase
    $reg.target.registry.registry_value_data = "DWORD (0x00000001)" nocase

    $reg.principal.hostname = $hostname

  match:
    $hostname over 5m

  outcome:
    //example usage of specifying test user and hostname to adjust risk score
    $risk_score = max(if($reg.principal.user.userid = "user" and $reg.principal.hostname = "hostname", 0, 15))
    $principal_hostname = array_distinct($reg.principal.hostname)
    $principal_process_pid = array_distinct($reg.principal.process.pid)
    $principal_process_file_full_path = array_distinct($reg.principal.process.file.full_path)
    $principal_process_product_specific_process_id = array_distinct($reg.principal.process.product_specific_process_id)
    $principal_user_userid = array_distinct($reg.principal.user.userid)
    $target_registry_key = array_distinct($reg.target.registry.registry_key)
    $target_registry_value_data = array_distinct($reg.target.registry.registry_value_data)
    $log_type = array_distinct(strings.concat($reg.metadata.log_type,"/",$reg.metadata.product_event_type))

  condition:
    $reg
}

YARA-L Rule Structure

Condition

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

Events

$reg REGISTRY_MODIFICATION (13, 4657)

  • target.registry.registry_key matches "WDigest\\UseLogonCredential$"
  • target.registry.registry_value_data = "DWORD (0x00000001)"

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($reg.principal.user.userid = "user" and $reg.principal.hostname = "hostname", 0, 15))
principal_hostnamearray_distinct($reg.principal.hostname)
principal_process_pidarray_distinct($reg.principal.process.pid)
principal_process_file_full_patharray_distinct($reg.principal.process.file.full_path)
principal_process_product_specific_process_idarray_distinct($reg.principal.process.product_specific_process_id)
principal_user_useridarray_distinct($reg.principal.user.userid)
target_registry_keyarray_distinct($reg.target.registry.registry_key)
target_registry_value_dataarray_distinct($reg.target.registry.registry_value_data)
log_typearray_distinct(strings.concat($reg.metadata.log_type,"/",$reg.metadata.product_event_type))

Back to all YARA-L rules