← Back to SOC feed Coverage →

Suspicious Microsoft Teams Callers by Impersonation-Style Identity

kql MEDIUM Azure-Sentinel
T1566
CloudAppEventsEmailEvents
huntingmicrosoftofficial
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at Azure-Sentinel →
Retrieved: 2026-09-07T23:00:00Z · Confidence: medium

Hunt Hypothesis

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.

KQL 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)
| 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

Analytic Rule Definition

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)

Required Data Sources

Sentinel TableNotes
CloudAppEventsEnsure this data connector is enabled
EmailEventsEnsure this data connector is enabled

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Hunting Queries/Microsoft 365 Defender/Email and Collaboration Queries/Microsoft Teams protection/Suspicious Microsoft Teams Callers by Impersonation-Style Identity.yaml