This hypothesis targets adversaries leveraging Microsoft Teams to conduct phishing campaigns by spoofing display names to bypass user trust and evade initial detection. Proactively hunting for these patterns in Azure Sentinel allows the SOC to identify coordinated bulk impersonation attempts that rely on rotating sender addresses, enabling faster containment of social engineering threats before they compromise high-value accounts.
//This query groups Microsoft Teams impersonation detections over the last 30 days by fake display name, sender
//domain and impersonation type, with the count of distinct sending addresses behind each identity.
//Attackers rotate sending addresses under one display name, so per-address ranking scatters a single campaign
//into many low-count rows. Distinct Sender Addresses is what reveals the bulk activity.
CloudAppEvents
| where Timestamp > ago(30d)
| where ActionType == "TeamsImpersonationDetected"
| extend RD = parse_json(RawEventData)
| extend ImpersonationType = tostring(RD.ImpersonationType),
FakeDisplayName = tostring(RD.Sender.DisplayName),
FakeSenderAddress = tostring(RD.Sender.UPN),
TargetUser = tostring(RD.UserId)
| extend FakeSenderDomain = tolower(tostring(split(FakeSenderAddress, "@")[1]))
| where isnotempty(FakeSenderDomain)
| summarize Detections = count(), SenderAddresses = dcount(FakeSenderAddress),
Targets = dcount(TargetUser), FirstSeen = min(Timestamp), LastSeen = max(Timestamp)
by FakeDisplayName, FakeSenderDomain, ImpersonationType
| top 20 by Detections desc
| project ['Fake Display Name']=FakeDisplayName, ['Sender Domain']=FakeSenderDomain,
['Impersonation Type']=ImpersonationType, ['Distinct Sender Addresses']=SenderAddresses,
['Detections']=Detections, ['Targeted Users']=Targets,
['First Seen']=FirstSeen, ['Last Seen']=LastSeen
id: 588c9935-c17b-4681-9bb1-ede0da2667bd
name: Microsoft Teams Impersonation Identities by Fake Display Name
description: |
This query groups Microsoft Teams impersonation detections by the fake display name and sender domain to expose bulk campaigns behind rotating addresses.
description-detailed: |
This query groups Microsoft Teams impersonation detections over the last 30 days by the fake display name, the sender domain and the impersonation type, using Advanced hunting in Microsoft Defender XDR, and returns the number of distinct sending addresses used behind each identity along with the number of users targeted and first and last seen. Grouping this way is the point. Attackers rotate through many sending addresses while keeping one convincing display name, so ranking by individual address scatters a single campaign across many low-count rows and hides it. Counting distinct sender addresses per display name makes bulk activity obvious, and a high address count against a small number of detections usually indicates an actor cycling identities to stay under per-sender thresholds.
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- CloudAppEvents
tactics:
- InitialAccess
relevantTechniques:
- T1566
query: |
//This query groups Microsoft Teams impersonation detections over the last 30 days by fake display name, sender
//domain and impersonation type, with the count of distinct sending addresses behind each identity.
//Attackers rotate sending addresses under one display name, so per-address ranking scatters a single campaign
//into many low-count rows. Distinct Sender Addresses is what reveals the bulk activity.
CloudAppEvents
| where Timestamp > ago(30d)
| where ActionType == "TeamsImpersonationDetected"
| extend RD = parse_json(RawEventData)
| extend ImpersonationType = tostring(RD.ImpersonationType),
FakeDisplayName = tostring(RD.Sender.DisplayName),
FakeSenderAddress = tostring(RD.Sender.UPN),
TargetUser = tostring(RD.UserId)
| extend FakeSenderDomain = tolower(tostring(split(FakeSenderAddress, "@")[1]))
| where isnotempty(FakeSenderDomain)
| summarize Detections = count(), SenderAddresses = dcount(FakeSenderAddress),
Targets = dcount(TargetUser), FirstSeen = min(Timestamp), LastSeen = max(Timestamp)
by FakeDisplayName, FakeSenderDomain, ImpersonationType
| top 20 by Detections desc
| project ['Fake Display Name']=FakeDisplayName, ['Sender Domain']=FakeSenderDomain,
['Impersonation Type']=ImpersonationType, ['Distinct Sender Addresses']=SenderAddresses,
['Detections']=Detections, ['Targeted Users']=Targets,
['First Seen']=FirstSeen, ['Last Seen']=LastSeen
version: 1.0.0
| Sentinel Table | Notes |
|---|---|
CloudAppEvents | Ensure this data connector is enabled |
Scenario: An IT administrator creates a shared mailbox or resource account (e.g., “IT Support” or “HR Helpdesk”) and configures it to send messages via the Microsoft Graph API or a Power Automate flow, where the From header is set to a generic domain (e.g., @company.com) but the display name is manually overridden to match a specific team member’s name for clarity, or vice versa, causing a mismatch between the authenticated identity and the presented display name.
@shared, @resources, @it-support) or where the sender is a known service principal/application ID.Scenario: A legitimate business application (such as Jira, ServiceNow, or Confluence) integrates with Microsoft Teams via a bot or connector to post notifications. These integrations often use a generic service account (e.g., jira-bot@company.com) but may configure the display name to reflect the specific project or ticket title (e.g., “JIRA - Ticket #1234”) or a generic label like “Automation Bot,” which can appear as an impersonation if the display name doesn’t strictly match the local part of the email address.
bot, connector, integration, api) in the local part, or where the sender domain is a known third-party SaaS domain (e.g., @jira.com, @servicenow.com) if the rule is scoped to internal domains, or explicitly whitelist known application service accounts.Scenario: An employee uses a personal email account (e.g., john.doe@gmail.com) to send a