Query Details
# *Potential Display Name Spoofing*
## Query Information
#### MITRE ATT&CK Technique(s)
| Technique ID | Title | Link |
| --- | --- | --- |
| T1566| Phishing | https://attack.mitre.org/tactics/T1566/ |
| T1656 | Impersonation | https://attack.mitre.org/tactics/T1656/ |
#### Description
This rule detects inbound emails that are delivered and are the first contact from a sender, where the sender's display name and email address exhibit characteristics often associated with phishing or impersonation attempts. Specifically, it flags emails where the local part of the sender's email address does not contain parts of their display name (first or last name) and has a high number of digits or a high digit-to-length ratio, suggesting a generated or obfuscated address.
#### Author <Optional>
- **Name: Benjamin Zulliger**
- **Github: https://github.com/benscha/KQLAdvancedHunting**
- **LinkedIn: https://www.linkedin.com/in/benjamin-zulliger/**
#### References
## Defender XDR
```KQL
let OwnDomains = dynamic(["mydomain1.ch", "mydomain2.ch"]);
let ExcludedDomains = dynamic(["host.docker.internal", "bounces.google.com"]);
let ExcludedSenderFragments = dynamic(["dmarc-request", "+"]);
IdentityInfo
| project AccountDisplayName
| join EmailEvents on $left.AccountDisplayName == $right.SenderDisplayName
| where EmailDirection == "Inbound"
| where DeliveryAction == "Delivered"
| where IsFirstContact == 1
// Normalize and extract local part early for reuse
| extend LocalPart = tostring(split(tolower(SenderFromAddress), "@")[0])
| extend SenderDomain = tostring(split(tolower(SenderFromAddress), "@")[1])
// Exclude own and whitelisted domains — use SenderFromAddress-derived domain consistently
| where not(SenderDomain has_any (OwnDomains))
| where not(SenderMailFromDomain has_any (ExcludedDomains))
// Exclude addresses containing whitelisted fragments (substring match)
| where not(LocalPart has_any (ExcludedSenderFragments))
| where not(SenderFromAddress has_any (ExcludedSenderFragments))
// Name matching: check if local part contains first or last name
| extend NameParts = split(tolower(SenderDisplayName), " ")
| extend FirstName = tostring(NameParts[0]), LastName = tostring(NameParts[1])
| extend NameMatch = iff(
(LocalPart contains FirstName and isnotempty(FirstName)) or
(LocalPart contains LastName and isnotempty(LastName)),
true, false)
// Digit ratio check
| extend DigitCount = strlen(replace_regex(LocalPart, @'[^0-9]', ''))
| extend LocalPartLength = strlen(LocalPart)
// Flag suspicious: no name match + too many digits
| where NameMatch == false
and (DigitCount > 4 or (DigitCount * 1.0 / LocalPartLength) > 0.4)
```
This query is designed to identify potential phishing or impersonation attempts in inbound emails. It specifically looks for emails that are the first contact from a sender and have suspicious characteristics in the sender's display name and email address. Here's a simplified breakdown of what the query does:
Domain Filtering: It excludes emails from known safe domains (like your own organization's domains and some whitelisted domains).
Sender Address Analysis: It examines the local part of the sender's email address (the part before the '@' symbol) to see if it contains parts of the sender's display name (like their first or last name). If it doesn't, this might be suspicious.
Digit Analysis: It checks if the local part of the email address contains a high number of digits or if the ratio of digits to the total length of the local part is high. This could indicate that the address is generated or obfuscated, which is common in phishing attempts.
Suspicion Flagging: An email is flagged as suspicious if the local part of the email address does not match the sender's name and has too many digits.
Overall, this query helps in detecting emails that might be trying to impersonate someone or are part of a phishing attack by analyzing the structure and content of the sender's email address.

Benjamin Zulliger
Released: May 19, 2026
Tables
Keywords
Operators