Adversaries frequently leverage low-reputation top-level domains in Microsoft Teams messages to distribute phishing links or malware payloads, exploiting the platform’s high user engagement to maximize initial compromise. Proactively hunting for these indicators allows the SOC to identify and isolate suspicious communications before users interact with malicious content, thereby reducing the mean time to detection for social engineering attacks.
//This query lists URL domains shared in Microsoft Teams over the last 30 days that use top level domains commonly
//abused for phishing and malware, ranked by how many distinct Teams messages they reached.
//Treat this as a review list of candidate indicators, not a blocklist: legitimate services use these TLDs too.
//.zip and .mov are worth extra attention because a link reads like a file name.
let suspTlds = dynamic(["top","xyz","click","link","shop","online","site","live","icu","cyou","sbs","rest","quest","cfd","bond","buzz","fun","space","monster","work","tk","ml","ga","cf","gq","dev","app","zip","mov","info","win","loan","men","stream","country"]);
MessageUrlInfo
| where Timestamp > ago(30d)
| where isnotempty(UrlDomain)
| extend Tld = tostring(split(UrlDomain, ".")[-1])
| where Tld in (suspTlds)
| summarize TeamsMessages = dcount(TeamsMessageId), FirstSeen = min(Timestamp), LastSeen = max(Timestamp)
by UrlDomain, Tld
| top 20 by TeamsMessages desc
| project ['URL Domain']=UrlDomain, ['Top Level Domain']=Tld, ['Teams Messages']=TeamsMessages,
['First Seen']=FirstSeen, ['Last Seen']=LastSeen
id: 8ed7068a-0b5f-43a0-87c5-1d99bef03531
name: Low-Reputation URL Domains Shared in Microsoft Teams
description: |
This query lists URL domains shared in Microsoft Teams that use top level domains commonly abused for phishing and malware, ranked by message reach.
description-detailed: |
This query lists URL domains shared in Microsoft Teams messages over the last 30 days whose top level domain is one commonly abused for phishing and malware delivery, using Advanced hunting in Microsoft Defender XDR. Domains are ranked by the number of distinct Teams messages they appeared in, with the top level domain and first and last seen. Treat the output as a review list of candidate indicators rather than a blocklist, since legitimate services do use these top level domains. Two deserve particular attention: .zip and .mov read like file names, so a link to one can be mistaken for an attachment by users who have been trained to distrust attachments but not links.
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- MessageUrlInfo
tactics:
- InitialAccess
relevantTechniques:
- T1566
query: |
//This query lists URL domains shared in Microsoft Teams over the last 30 days that use top level domains commonly
//abused for phishing and malware, ranked by how many distinct Teams messages they reached.
//Treat this as a review list of candidate indicators, not a blocklist: legitimate services use these TLDs too.
//.zip and .mov are worth extra attention because a link reads like a file name.
let suspTlds = dynamic(["top","xyz","click","link","shop","online","site","live","icu","cyou","sbs","rest","quest","cfd","bond","buzz","fun","space","monster","work","tk","ml","ga","cf","gq","dev","app","zip","mov","info","win","loan","men","stream","country"]);
MessageUrlInfo
| where Timestamp > ago(30d)
| where isnotempty(UrlDomain)
| extend Tld = tostring(split(UrlDomain, ".")[-1])
| where Tld in (suspTlds)
| summarize TeamsMessages = dcount(TeamsMessageId), FirstSeen = min(Timestamp), LastSeen = max(Timestamp)
by UrlDomain, Tld
| top 20 by TeamsMessages desc
| project ['URL Domain']=UrlDomain, ['Top Level Domain']=Tld, ['Teams Messages']=TeamsMessages,
['First Seen']=FirstSeen, ['Last Seen']=LastSeen
version: 1.0.0
Scenario: The DevOps team shares a link to a temporary staging environment or CI/CD artifact host (e.g., https://build-artifacts-xyz123.s3.amazonaws.com or a custom domain like staging-app.internal.dev) during a sprint review. If the TLD is a newer or less common one (e.g., .dev, .io, or a specific cloud provider’s dynamic TLD), it may be flagged as low-reputation.
*.internal, *.staging, *.dev) or specific cloud provider dynamic TLDs (e.g., *.amazonaws.com, *.cloudapp.net, *.azurewebsites.net) if they are part of the approved internal infrastructure list.Scenario: The IT Helpdesk or Security Team shares a link to a temporary file share or diagnostic tool hosted on a public but low-reputation domain for a specific client issue (e.g., https://diag-tools-2024.qa or a short-lived URL shortener like bit.ly or t.co used for quick sharing of logs).
bit.ly, t.co, ow.ly) if they are governed by an internal policy, or exclude domains ending in .qa or .test if they are part of the internal QA infrastructure.Scenario: A marketing or product team shares a link to a new landing page or beta feature hosted on a modern TLD (e.g., https://beta-feature-2024.app or https://promo-2024.site) for internal feedback before public launch. These TLDs may have lower reputation scores in threat intelligence feeds due to higher