Adversaries may attempt to register for multiple events to identify successful registration patterns, leveraging denied attempts to refine their targeting. SOC teams should proactively hunt for this behavior in Azure Sentinel to detect potential reconnaissance or credential compromise efforts.
KQL Query
let threshold = 2;
let failed_users = (
ZoomLogs
| where Event =~ "webinar.registration_denied" or Event =~ "recording.registration_denied"
| extend RegisteringUser = columnifexists('payload_object_registrant_email_s', payload_object_registrant_email_s)
| extend ItemId = columnifexists('tostring(parse_json(WebinarEvents).WebinarId)',payload_object_uuid_s)
| summarize dcount(ItemId) by RegisteringUser
| where dcount_ItemId > threshold
| project RegisteringUser);
ZoomLogs
| where Event =~ "webinar.registration_approved" or Event =~ "recording.registration_approved"
| extend RegisteringUser = columnifexists('payload_object_registrant_email_s', columnifexists('payload_object_registrant_email_s', ""))
| extend ItemId = columnifexists('tostring(parse_json(WebinarEvents).WebinarId)',columnifexists('payload_object_uuid_s', ""))
| extend EventName = columnifexists('tostring(parse_json(WebinarEvents).WebinarName)',columnifexists('payload_object_topic_s', ""))
| extend EventHost = columnifexists('payload_object_host_id',"")
| extend EventStart = columnifexists('tostring(parse_json(WebinarEvents).Start)',columnifexists('payload_object_start_time_s' ,""))
| where RegisteringUser !in (failed_users)
| project TimeGenerated, RegisteringUser, EventName, ItemId, EventHost, EventStart
| extend timestamp = TimeGenerated, AccountCustomEntity = RegisteringUser
id: e119c365-9213-45a1-bbd7-8faf6d103d30
name: User denied multiple registration events successfully registering
description: |
'Query identifies users denied registration for multiple webinars or recordings but successfully registered for at least one event. Threshold variable adjusts number of events user needs to be rejected from.'
description_detailed: |
'This hunting query identifies users that have attempted to register for multiple webinars or recordings and has been denied by the organizer but have also successfully register for at least one event. The number of events a user needs to be rejected from to be included in this query is adjusted with the threshold variable.'
requiredDataConnectors: []
tactics:
- InitialAccess
relevantTechniques:
- T1078
query: |
let threshold = 2;
let failed_users = (
ZoomLogs
| where Event =~ "webinar.registration_denied" or Event =~ "recording.registration_denied"
| extend RegisteringUser = columnifexists('payload_object_registrant_email_s', payload_object_registrant_email_s)
| extend ItemId = columnifexists('tostring(parse_json(WebinarEvents).WebinarId)',payload_object_uuid_s)
| summarize dcount(ItemId) by RegisteringUser
| where dcount_ItemId > threshold
| project RegisteringUser);
ZoomLogs
| where Event =~ "webinar.registration_approved" or Event =~ "recording.registration_approved"
| extend RegisteringUser = columnifexists('payload_object_registrant_email_s', columnifexists('payload_object_registrant_email_s', ""))
| extend ItemId = columnifexists('tostring(parse_json(WebinarEvents).WebinarId)',columnifexists('payload_object_uuid_s', ""))
| extend EventName = columnifexists('tostring(parse_json(WebinarEvents).WebinarName)',columnifexists('payload_object_topic_s', ""))
| extend EventHost = columnifexists('payload_object_host_id',"")
| extend EventStart = columnifexists('tostring(parse_json(WebinarEvents).Start)',columnifexists('payload_object_start_time_s' ,""))
| where RegisteringUser !in (failed_users)
| project TimeGenerated, RegisteringUser, EventName, ItemId, EventHost, EventStart
| extend timestamp = TimeGenerated, AccountCustomEntity = RegisteringUser
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AccountCustomEntity
version: 1.0.1
metadata:
source:
kind: Community
author:
name: Pete Bryan
support:
tier: Community
categories:
domains: [ "Security - Other" ]
Scenario: System administrator schedules a recurring backup job that registers multiple webinars for system testing.
Filter/Exclusion: Exclude events associated with scheduled system tasks (e.g., task_id or job_name fields matching known backup or maintenance tasks in Microsoft Endpoint Manager or Ansible).
Scenario: A user is part of a training program that automatically registers them for multiple webinars as part of onboarding.
Filter/Exclusion: Exclude users with a specific role or attribute (e.g., user_role = "training_user") in Azure Active Directory or Okta.
Scenario: A customer support team uses a script to register users for multiple webinars during a product launch.
Filter/Exclusion: Exclude events where the user has a specific tag or flag (e.g., is_automated_registration = true) in ServiceNow or Zendesk.
Scenario: A marketing team uses HubSpot or Salesforce to bulk register users for webinars as part of a campaign.
Filter/Exclusion: Exclude events where the user is registered via an integration (e.g., source_system = "HubSpot" or source_system = "Salesforce") in Eventbrite or Zoom.
Scenario: A developer uses Postman or curl to programmatically register users for multiple webinars during API testing.
Filter/Exclusion: Exclude events where the user has a specific IP address or user agent (e.g., ip_address = "192.168.1.100" or user_agent = "Postman") in Splunk or ELK Stack.