Detection rules › YARA-L

YARA-L rules: 0r

Microsoft Entra ID Device code phishing attack

#
Severity
high
Type
alert
Time window
16m
Match by
user
Author
Bastradamus
Source
github.com/chronicle/detection-rules

Detects strong indicators of a successful device code phishing attack.

MITRE ATT&CK Coverage

TacticTechniques
Initial Access

References

Telemetry Coverage

Rule Body

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

rule entra_id_devicecode_phishing_attack {

  meta:
    author = "Bastradamus"
    description = "Detects strong indicators of a successful device code phishing attack."
    severity = "High"
    priority = "High"
    rule_id = "mr_8b29e3d1-5c42-4f91-9aef-b673ad89f0e4"
    rule_name = "Microsoft Entra ID Device code phishing attack"
    type = "alert"
    data_source = "Workspace Activity, azure ad"
    reference = "https://systemweakness.com/detecting-device-code-phishing-in-google-security-operations-9bf1c282cff0"
    mitre_attack_tactic = "Initial Access"
    mitre_attack_technique = "Phishing"
    mitre_attack_url = "https://attack.mitre.org/techniques/T1566/"

  events:
    $email.network.email.to = $user
    $email.metadata.vendor_name = "Google Workspace"
    $email.metadata.product_name = "gmail" nocase
    $email.about.url = /microsoft.com\/devicelogin/ or
    $email.about.url = /oauth2\/deviceauth/
    //user clicks the device code phish URL.
    $email.about.labels.value = /71|9/

    $entra.metadata.vendor_name = "Microsoft"
    $entra.metadata.product_name = "Azure AD"
    //Entra error code 50199: The user was asked to confirm that this app is the application they intended to sign into.
    $entra.security_result.rule_id = /^(0|50199)$/

    //join
    $email.network.email.to = $entra.target.user.userid

  match:
    //Time window based on the fact that the device code expires within 15 minutes. Added an extra 60 seconds.
    $user over 16m

  outcome:
    $mitre_attack_tactic = array_distinct("Initial Access")
    $mitre_attack_technique = array_distinct("Phishing")
    $mitre_attack_technique_id = array_distinct("T1566")
    $target_user_distinct_count = count_distinct($user)
    $target_user_count = count($user)
    $principal_ip = array_distinct($email.principal.ip)
    $sender_from = array_distinct($email.principal.network.email.from)
    $recipient = array_distinct($email.network.email.to)

  condition:
    $email and $entra
}

YARA-L Rule Structure

Condition

Fires when at least one $email event in the 16m window and at least one $entra event in the 16m window.

Events

$email

  • about.url matches "microsoft.com\/devicelogin"
  • about.url matches "oauth2\/deviceauth"
  • about.labels.value matches "71|9"
  • network.email.to cross_field_compare "entra.target.user.userid"

$entra

  • security_result.rule_id matches "^(0|50199)$"

Match and Correlation

Match key
$user (network.email.to)
Within
16m

Outcome

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

FieldExpression
target_user_distinct_countcount_distinct($user)
target_user_countcount($user)
principal_iparray_distinct($email.principal.ip)
sender_fromarray_distinct($email.principal.network.email.from)
recipientarray_distinct($email.network.email.to)

OneLogin Multiple Users Assumed

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

Detects when a user assumes multiple user accounts.

MITRE ATT&CK Coverage

TacticTechniques
Lateral Movement

References

Rule Body

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

rule onelogin_multiple_users_assumed {

  meta:
    author = "Google Cloud Security"
    description = "Detects when a user assumes multiple user accounts."
    rule_id = "mr_20b98df8-72a3-4163-8654-b66e4192d744"
    rule_name = "OneLogin Multiple Users Assumed"
    reference = "https://onelogin.service-now.com/kb_view_customer.do?sysparm_article=KB0010594"
    mitre_attack_tactic = "Lateral Movement"
    mitre_attack_technique = "Use Alternate Authentication Material"
    mitre_attack_url = "https://attack.mitre.org/techniques/T1550/"
    mitre_attack_version = "v15.1"
    type = "Alert"
    data_source = "OneLogin"
    severity = "Low"
    priority = "Low"

  events:
     $assume.metadata.event_type = "USER_RESOURCE_ACCESS"
     $assume.metadata.product_name = "ONELOGIN_SSO"
     $assume.metadata.vendor_name = "ONELOGIN"
     $assume.metadata.product_event_type = "3" //a user assumed another user
     $assume.principal.user.userid = $actor_user

  match:
    $actor_user over 1h

  outcome:
    $risk_score = max(35)
    $mitre_attack_tactic = "Lateral Movement"
    $mitre_attack_technique = "Use Alternate Authentication Material"
    $assume_reason = array_distinct($assume.metadata.description)
    $principal_user_userid = array_distinct($assume.principal.user.userid)
    $principal_user_user_display_name = array_distinct($assume.principal.user.user_display_name)
    $principal_ip = array_distinct($assume.principal.ip)
    $principal_ip_country = array_distinct($assume.principal.ip_geo_artifact.location.country_or_region)
    $principal_ip_state = array_distinct($assume.principal.ip_geo_artifact.location.state)
    $target_user_userid = array_distinct($assume.target.user.userid)
    $dc_target_user_userid = count_distinct($assume.target.user.userid)

  condition:
    $assume and $dc_target_user_userid > 3
}

YARA-L Rule Structure

Condition

Fires when at least one $assume event in the 1h window and $dc_target_user_userid > 3.

Events

$assume USER_RESOURCE_ACCESS

  • metadata.product_event_type = "3"

Match and Correlation

Match key
$actor_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)
assume_reasonarray_distinct($assume.metadata.description)
principal_user_useridarray_distinct($assume.principal.user.userid)
principal_user_user_display_namearray_distinct($assume.principal.user.user_display_name)
principal_iparray_distinct($assume.principal.ip)
principal_ip_countryarray_distinct($assume.principal.ip_geo_artifact.location.country_or_region)
principal_ip_statearray_distinct($assume.principal.ip_geo_artifact.location.state)
target_user_useridarray_distinct($assume.target.user.userid)
dc_target_user_useridcount_distinct($assume.target.user.userid)

Back to all YARA-L rules