This hypothesis targets adversaries leveraging phishing (T1566) to establish social engineering footholds by spoofing trusted IT support identities within Microsoft Teams, often using disposable tenants to evade initial scrutiny. Proactively hunting for these impersonation patterns in Azure Sentinel allows the SOC to identify potential voice-based social engineering attacks before they progress to credential harvesting or unauthorized access.
//This query surfaces Microsoft Teams callers whose display name or address impersonates IT support, helpdesk,
//security or account maintenance, over the last 30 days, and flags calls placed from throwaway tenants.
//Origin is derived from the organisation's own accepted domains (inbound mail recipients), not a tenant-id anchor,
//so no editing is needed to run it in any tenant.
//Background: Microsoft Threat Intelligence, "Impersonating IT support: how threat actors turn a remote session into
//enterprise-wide access" (2 September 2026)
//https://www.microsoft.com/en-us/security/blog/2026/09/02/impersonating-it-support-threat-actors-turn-remote-session-into-enterprise-wide-access/
let suspRegex = @"(?i)help ?desk|helpdesk|it ?support|service ?desk|sys ?admin|administrator|security|microsoft|google|apple|amazon|paypal|support|update|verif|account|password|mfa|maintenance";
let ownDomains = toscalar(EmailEvents
| where Timestamp > ago(30d)
| where EmailDirection == "Inbound"
| extend RecipientDomain = tolower(tostring(split(RecipientEmailAddress, "@")[1]))
| where isnotempty(RecipientDomain)
| summarize make_set(RecipientDomain, 200));
CloudAppEvents
| where Timestamp > ago(30d)
| where ActionType == "CallParticipantDetail"
| extend R = parse_json(RawEventData)
| extend CallId = tostring(R.CallId), JoinTime = todatetime(R.JoinTime), Attendees = R.Attendees
| where isnotempty(CallId) and isnotempty(JoinTime)
| summarize Attendees = take_any(Attendees), JoinTime = min(JoinTime) by CallId
| mv-expand Attendee = Attendees
| extend CallerAddress = tolower(tostring(Attendee.UPN)), CallerName = tostring(Attendee.DisplayName)
| where isnotempty(CallerAddress)
| extend CallerDomain = tostring(split(CallerAddress, "@")[1])
| extend SuspName = CallerName matches regex suspRegex or CallerAddress matches regex suspRegex
| where SuspName or CallerDomain endswith ".onmicrosoft.com"
| extend Origin = case(CallerDomain endswith ".onmicrosoft.com", "External (.onmicrosoft throwaway)",
set_has_element(ownDomains, CallerDomain), "Own tenant",
"External")
| summarize CallsPlaced = dcount(CallId), FirstSeen = min(JoinTime), LastSeen = max(JoinTime)
by CallerName, CallerAddress, CallerDomain, Origin
| extend OriginRank = case(Origin == "External (.onmicrosoft throwaway)", 0, Origin == "External", 1, 2)
| sort by OriginRank asc, CallsPlaced desc
| take 20
| project ['Teams Caller Display Name']=CallerName, ['Teams Caller Address']=CallerAddress,
['Caller Domain']=CallerDomain, ['Origin']=Origin, ['Teams Calls Placed']=CallsPlaced,
['First Seen']=FirstSeen, ['Last Seen']=LastSeen
id: f905bb00-9c5f-4889-bc39-7d0765521228
name: Suspicious Microsoft Teams Callers by Impersonation-Style Identity
description: |
This query surfaces Microsoft Teams callers whose display name or address impersonates IT support, and calls placed from throwaway tenants.
description-detailed: |
This query surfaces Microsoft Teams callers whose display name or address matches common IT support, helpdesk, security or account-maintenance impersonation themes over the last 30 days, using Advanced hunting in Microsoft Defender XDR. Each caller is classified by origin: a throwaway .onmicrosoft.com tenant, an external domain, or the organisation's own tenant. The organisation's accepted domains are derived from inbound mail recipients rather than a hard-coded tenant identifier, so the query is portable to any tenant without editing. Helpdesk impersonation over a Teams call is a common opening move because the malicious instructions are spoken and never appear in a chat log, making the caller identity itself one of the few durable artefacts available for hunting.
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- CloudAppEvents
- EmailEvents
tactics:
- InitialAccess
relevantTechniques:
- T1566
query: |
//This query surfaces Microsoft Teams callers whose display name or address impersonates IT support, helpdesk,
//security or account maintenance, over the last 30 days, and flags calls placed from throwaway tenants.
//Origin is derived from the organisation's own accepted domains (inbound mail recipients), not a tenant-id anchor,
//so no editing is needed to run it in any tenant.
//Background: Microsoft Threat Intelligence, "Impersonating IT support: how threat actors turn a remote session into
//enterprise-wide access" (2 September 2026)
//https://www.microsoft.com/en-us/security/blog/2026/09/02/impersonating-it-support-threat-actors-turn-remote-session-into-enterprise-wide-access/
let suspRegex = @"(?i)help ?desk|helpdesk|it ?support|service ?desk|sys ?admin|administrator|security|microsoft|google|apple|amazon|paypal|support|update|verif|account|password|mfa|maintenance";
let ownDomains = toscalar(EmailEvents
| where Timestamp > ago(30d)
| where EmailDirection == "Inbound"
| extend RecipientDomain = tolower(tostring(split(RecipientEmailAddress, "@")[1]))
| where isnotempty(RecipientDomain)
| summarize make_set(RecipientDomain, 200));
CloudAppEvents
| where Timestamp > ago(30d)
| where ActionType == "CallParticipantDetail"
| extend R = parse_json(RawEventData)
| extend CallId = tostring(R.CallId), JoinTime = todatetime(R.JoinTime), Attendees = R.Attendees
| where isnotempty(CallId) and isnotempty(JoinTime)
| summarize Attendees = take_any(Attendees), JoinTime = min(JoinTime) by CallId
| mv-expand Attendee = Attendees
| extend CallerAddress = tolower(tostring(Attendee.UPN)), CallerName = tostring(Attendee.DisplayName)
| where isnotempty(CallerAddress)
| Sentinel Table | Notes |
|---|---|
CloudAppEvents | Ensure this data connector is enabled |
EmailEvents | Ensure this data connector is enabled |
IT Support - [Agent Name]) during scheduled shift handovers or bulk status updates to large distribution lists.
tenantId matches the primary enterprise tenant ID and the displayName contains the specific organizational prefix (e.g., IT Support -) but does not contain common impersonation typos (like IT Supprt or IT Supportt).IT Support Bot or Helpdesk Alert.
bot type in the Teams API metadata, or exclude specific known application IDs (client IDs) registered in the Azure AD App Registrations for internal monitoring tools.IT Support Contact or similar by the inviting admin, and who make calls from their own external (throwaway) tenant during the initial setup phase.
userType is Guest and the tenantId is in a pre-approved list of known vendor or partner tenant IDs, or where the call duration is less than 30 seconds (indicating a quick connection test rather than a sustained impersonation session).IT Support to mimic the