Adversaries may enable external user access to bypass authentication controls and gain unauthorized entry into internal systems. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential lateral movement or persistence tactics early.
KQL Query
ZoomLogs
| where Event =~ "account.settings_updated"
| extend EnforceLogin = columnifexists("payload_object_settings_schedule_meeting_enfore_login_b", "")
| extend EnforceLoginDomain = columnifexists("payload_object_settings_schedule_meeting_enfore_login_b", "")
| extend GuestAlerts = columnifexists("payload_object_settings_in_meeting_alert_guest_join_b", "")
| where EnforceLogin == 'false' or EnforceLoginDomain == 'false' or GuestAlerts == 'false'
| extend SettingChanged = case(EnforceLogin == 'false' and EnforceLoginDomain == 'false' and GuestAlerts == 'false', "All settings changed",
EnforceLogin == 'false' and EnforceLoginDomain == 'false', "Enforced Logons and Restricted Domains Changed",
EnforceLoginDomain == 'false' and GuestAlerts == 'false', "Enforced Domains Changed",
EnforceLoginDomain == 'false', "Enfored Domains Changed",
GuestAlerts == 'false', "Guest Join Alerts Changed",
EnforceLogin == 'false', "Enforced Logins Changed",
"No Changes")
| extend AccountName = tostring(split(User, "@")[0]), AccountUPNSuffix = tostring(split(User, "@")[1])
id: 8e267e91-6bda-4b3c-bf68-9f5cbdd103a3
name: External User Access Enabled
description: |
'This alerts when the account setting is changed to allow either external domain access or anonymous access to meetings.'
severity: Low
requiredDataConnectors: []
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
- Persistence
relevantTechniques:
- T1098
- T1556
query: |
ZoomLogs
| where Event =~ "account.settings_updated"
| extend EnforceLogin = columnifexists("payload_object_settings_schedule_meeting_enfore_login_b", "")
| extend EnforceLoginDomain = columnifexists("payload_object_settings_schedule_meeting_enfore_login_b", "")
| extend GuestAlerts = columnifexists("payload_object_settings_in_meeting_alert_guest_join_b", "")
| where EnforceLogin == 'false' or EnforceLoginDomain == 'false' or GuestAlerts == 'false'
| extend SettingChanged = case(EnforceLogin == 'false' and EnforceLoginDomain == 'false' and GuestAlerts == 'false', "All settings changed",
EnforceLogin == 'false' and EnforceLoginDomain == 'false', "Enforced Logons and Restricted Domains Changed",
EnforceLoginDomain == 'false' and GuestAlerts == 'false', "Enforced Domains Changed",
EnforceLoginDomain == 'false', "Enfored Domains Changed",
GuestAlerts == 'false', "Guest Join Alerts Changed",
EnforceLogin == 'false', "Enforced Logins Changed",
"No Changes")
| extend AccountName = tostring(split(User, "@")[0]), AccountUPNSuffix = tostring(split(User, "@")[1])
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: User
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
version: 1.0.4
kind: Scheduled
metadata:
source:
kind: Community
author:
name: Microsoft Security Research
support:
tier: Community
categories:
domains: [ "Security - Others", "Identity" ]
Scenario: A system administrator enables external domain access for a service account to allow integration with a third-party SaaS application (e.g., Microsoft Teams or Zoom).
Filter/Exclusion: Check for accounts associated with known SaaS integrations or use a filter like account_type = "service_account" and external_domain = "trusted_saaS_domain.com".
Scenario: A scheduled job (e.g., using Windows Task Scheduler or cron) is configured to run a script that requires temporary anonymous access to a meeting room for automated testing.
Filter/Exclusion: Filter by event_type = "scheduled_job" and job_name = "automated_testing_script" or include a tag like exclude_automation.
Scenario: An IT admin configures anonymous access to a meeting room for a public-facing website (e.g., using Zoom Webinar or Microsoft Teams Live Events) to allow guest participation.
Filter/Exclusion: Use a filter like meeting_type = "public_webinar" or access_type = "anonymous_allowed_for_guests".
Scenario: A user is granted external access to a company’s internal collaboration tool (e.g., Microsoft Teams) via a partner portal for a joint project.
Filter/Exclusion: Filter by user_role = "partner" or external_domain = "partner_portal_domain.com".
Scenario: A system update or patching process temporarily enables anonymous access to a meeting room for a system diagnostics tool (e.g., using a script in PowerShell or Bash).
Filter/Exclusion: Filter by event_type = "system_update" or include a tag like exclude_patch_process.