THREAT-Infra-HomoglyphTyposquatDomainResolution Elastic Security · Elastic

Detect Lookalike and Typosquatted Domain Resolution in Corporate DNS (Edit-Distance and Homoglyph) in Elastic Security

Before phishing, business email compromise, or credential-harvesting operations, adversaries register domains that are visually or typographically confusable with the target organization's own domain. The three dominant families are (1) typosquats produced by a single edit operation on the registrable label — omission (exmple), insertion (exampple), transposition (exapmle), or adjacent-key substitution; (2) ASCII homoglyphs that exploit glyph confusability in common sans-serif fonts — 'rn' for 'm', '1'/'l'/'I', '0'/'O', 'vv' for 'w', '3' for 'e'; and (3) internationalized domain names (IDN) whose punycode 'xn--' A-label decodes to a Unicode string rendering identically to the brand (the classic Cyrillic-'a' attack). Because this infrastructure is acquired during Resource Development, the only telemetry the defender owns before the phish lands is their own recursive DNS: the first resolution of a lookalike domain from inside the corporate network is frequently the earliest observable in the intrusion. This detection scores every resolved second-level label against the organization's own registrable label using a character-set distance approximation of edit distance, an organization-specific ASCII-confusable regex, an enumerated single-edit permutation set (dnstwist-style), and a first-seen-in-environment filter on punycode A-labels. It deliberately does not depend on external threat intelligence feeds, which lag domain registration by days.

MITRE ATT&CK

Tactic
Resource Development

Elastic Detection Query

Elastic Security (Elastic)
eql
dns where event.type == "connection" and
  not dns.question.name : ("example.com", "*.example.com", "example.net", "*.example.net", "example.org", "*.example.org") and
  (
    dns.question.name : ("xn--*", "*.xn--*") or
    dns.question.name : ("exarnple.*", "exannple.*", "examp1e.*", "exampie.*", "exampl3.*", "3xample.*", "ex4mple.*") or
    dns.question.name : ("xample.*", "eample.*", "exmple.*", "exaple.*", "examle.*", "exampe.*", "exampl.*") or
    dns.question.name : ("xeample.*", "eaxmple.*", "exmaple.*", "exapmle.*", "examlpe.*", "exampel.*")
  )
high severity medium confidence

Elastic EQL detection over DNS events for lookalike registrable labels, organized as four wildcard families: punycode IDN A-labels, ASCII homoglyph substitutions, single-character omissions, and single-character transpositions. EQL's ':' operator is a case-insensitive wildcard match, so no case normalization is required. The omission and transposition families are enumerated rather than computed because EQL has no string-distance function; regenerate all four lists with dnstwist for the deployment's own brand and replace the example.* exclusions with the organization's real domain portfolio.

Data Sources

Elastic Defend endpoint DNS eventsPacketbeat DNSNetwork Traffic: DNS Resolution

Required Tables

logs-endpoint.events.network-*packetbeat-*

False Positives & Tuning

  • Organization-owned defensive registrations not listed in the exclusion clause
  • Legitimate international domains using punycode A-labels, which dominate the xn--* family in organizations with non-Latin-script users or partners
  • Brand-protection and phishing-simulation vendors resolving lookalike domains as part of contracted monitoring
  • Security tooling detonating URLs from a managed endpoint, which resolves attacker domains legitimately

Other platforms for THREAT-Infra-HomoglyphTyposquatDomainResolution


Testing Methodology

Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Resolve an ASCII Homoglyph Lookalike Domain (rn for m)

    Expected signal: Sysmon Event ID 22 (DNS Query) with QueryName='exarnple.com'. The corresponding DnsEvents row records Name='exarnple.com' with the resolving ClientIP and Computer. The lookup will likely return NXDOMAIN; the query attempt is logged regardless, and neither query is filtered on ResultCode.

  2. Test 2Resolve a Character-Transposition Typosquat Domain

    Expected signal: Sysmon Event ID 22 with QueryName='exampel.com' and Image pointing at powershell.exe. DnsEvents records Name='exampel.com' for the resolving client.

  3. Test 3Resolve a Punycode IDN A-Label

    Expected signal: A DNS query for 'xn--exmple-4nf.com' recorded by the recursive resolver and, on Windows endpoints running the equivalent lookup, Sysmon Event ID 22 with the same QueryName. The A-label is stored verbatim in the log; no Unicode decoding is performed by the logging pipeline.

  4. Test 4Sweep an Enumerated Single-Edit Permutation Set

    Expected signal: Four DNS queries within a few seconds from a single client for exmple.com, exaple.com, examle.com, and exampl.com. Most will return NXDOMAIN, which is why neither detection filters on ResultCode / QueryStatus.


Response Playbook

Triage

  1. Pull WHOIS/RDAP for the flagged domain and record the creation date, registrar, registrant privacy status, and nameservers. A registrable label within two edits of your brand that was created in the last 30 days and sits behind privacy protection is high-confidence malicious infrastructure.
  2. Check certificate transparency logs (crt.sh, Censys) for the domain: a TLS certificate issued within hours of registration, especially a free ACME certificate covering a login-themed subdomain, indicates the phishing page is already staged.
  3. Determine which users and endpoints resolved the domain and by what means — check the requesting process (Sysmon Image field) to distinguish a browser navigation, an Outlook link preview, a mail-security detonation sandbox, and a scripted resolution.
  4. Retrieve the resolved IP and pivot: check whether the same IP or ASN hosts other lookalike domains for your brand, which converts a single hit into a campaign-scoped infrastructure cluster.
  5. Search mail gateway logs for inbound messages whose sender domain, envelope-from, reply-to, or embedded link matches the flagged domain, and quarantine any that are still in user mailboxes.
  6. If the domain resolves to a live page, retrieve it from an isolated analysis host and determine whether it clones your SSO/login branding, and whether it proxies credentials in real time (evilginx/Modlishka-style reverse proxy) versus statically harvesting them — real-time proxies defeat MFA and change the severity materially.
  7. Verify the domain is not an organization-owned defensive registration or a contracted brand-protection vendor asset before escalating; confirm against the domain portfolio inventory, not memory.

Containment

  1. Sinkhole or block the domain and any sibling domains on the same registration cluster at the recursive resolver, secure web gateway, and mail gateway, including wildcard coverage for subdomains.
  2. Submit an abuse/takedown request to the registrar and hosting provider, and where the domain is a plain trademark impersonation, open a UDRP or registrar trademark-abuse case in parallel — takedown is usually faster through the hosting provider than the registrar.
  3. For any user who resolved the domain, force a password reset and revoke active sessions and refresh tokens if there is any evidence of credential submission; treat an evilginx-style reverse proxy hit as a confirmed session-token compromise regardless of MFA.
  4. Add the domain to the mail gateway's impersonation-protection and lookalike-domain policy so subsequent sending attempts from that domain are rejected rather than merely flagged.
  5. Register or monitor the remaining unregistered permutations in the same edit-distance neighbourhood if the campaign shows the actor is walking the permutation set.
  6. Notify the brand-protection, legal, and communications teams if the domain hosts customer-facing impersonation content, since external customers cannot be protected by internal DNS blocking.

Evidence Collection

  1. Full DNS resolution records for the domain: querying host, user, requesting process, timestamp of the first and last resolution, and every resolved IP.
  2. WHOIS/RDAP registration record and its history, plus certificate transparency entries establishing the registration and TLS issuance timeline.
  3. A preserved copy of the hosted content (HTML, JavaScript, any credential POST endpoint) retrieved from an isolated analysis host, with the retrieval timestamp and source IP recorded.
  4. Mail gateway records for any message referencing the domain: full headers, authentication results (SPF/DKIM/DMARC), recipients, and delivery disposition.
  5. Proxy and endpoint network telemetry for any HTTP/HTTPS session to the resolved IP, including request method and bytes transferred, to establish whether credentials were actually submitted.
  6. Identity provider sign-in and audit logs for every user who resolved the domain, covering the surrounding 48 hours, including MFA method registrations and impossible-travel or unfamiliar-device signals.

Escalation Criteria

  • !The domain was registered within the last 30 days, holds a valid TLS certificate, and serves a page cloning the organization's login or SSO branding.
  • !Any evidence of credential submission to the domain, or an identity provider sign-in for the same user from an unfamiliar device, IP, or ASN shortly after the resolution.
  • !The hosted page behaves as a real-time reverse proxy against the genuine identity provider, which implies session-token theft and MFA bypass rather than static credential capture.
  • !Multiple distinct lookalike domains for the same brand resolve within a short window, or the resolutions come from many distinct users, indicating an active campaign wave rather than an isolated click.
  • !A resolving user holds privileged access (tenant or domain administrator, help desk staff with reset authority, finance staff with payment-release authority) — the latter is the standard BEC target profile for lookalike sender domains.
  • !The domain is used as a sending domain for inbound mail that passed SPF/DKIM/DMARC on its own namespace, which means recipients see an authenticated message from a near-identical domain.

Investigation Guide

Related Techniques

Forensic Artifacts

  • >Recursive resolver logs and Sysmon Event ID 22 records establishing the first and last resolution of the lookalike domain inside the environment.
  • >WHOIS/RDAP creation and update timestamps, registrar, nameserver history, and certificate transparency issuance records for the domain.
  • >Secure web gateway and proxy logs showing HTTP method, URI path, and response size for any session to the domain, which distinguishes a page view from a credential POST.
  • >Browser history, cache, and saved-form artifacts on the resolving endpoint, plus any credential manager prompt or autofill decline recorded by the browser.
  • >Mail gateway message tracking and quarantine records for messages referencing or sent from the domain, including full authentication results.
  • >Identity provider sign-in logs, refresh-token issuance records, and MFA method registration events for every affected user in the surrounding window.
  • >Passive DNS and hosting-neighbourhood data for the resolved IP, which frequently exposes the rest of the campaign's domain cluster.

Tuning Guidance

This detection is unusable until the four organization-specific variables are populated, and its false-positive rate is dominated by how well they are populated. Deployment order: (1) Set OrgLabel to your primary registrable label and add a separate scheduled rule per additional brand rather than trying to handle several brands in one query — the character-set arithmetic is per-brand. (2) Build OrgOwnedRegex from the authoritative domain portfolio inventory, not from memory; every defensive registration you own will otherwise match on every run and train analysts to ignore the rule. (3) Generate the enumerated omission/transposition alternations in the SPL search with dnstwist (dnstwist --format csv yourbrand.com) and regenerate them whenever the brand changes; the hand-written sets in this rule are for the label 'example' only. (4) Tune HomoglyphRegex to the fonts your users actually see — 'rn' for 'm' and '1'/'l' matter in sans-serif mail clients, while '0'/'O' confusion matters more in monospace contexts. Threshold guidance: the CharacterSetDistanceLE2 pillar scales badly for short labels — for a registrable label of six characters or fewer the benign base rate is high enough that you should either tighten it to a combined difference of 1 with a length delta of 1, or disable that pillar and rely on the enumerated permutation set instead. The set_difference arithmetic operates on distinct character sets rather than multisets, so it is an approximation of Levenshtein distance: it will not distinguish 'exampple' from 'example' by count alone (the length delta guard covers that case) and it will over-match labels that reuse the brand's characters in a different arrangement. Treat PriorHistory == false / NewToEnvironment == true as the alerting tier and everything else as a hunting queue; a lookalike domain with 30 days of resolution history is far more likely to be a benign neighbour brand than live phishing infrastructure. Finally, do not gate this rule behind a threat-intelligence feed match — the entire value of DNS-side lookalike detection is that it fires days before the domain appears in any feed.


Hunting Queries

Enumerates every internationalized domain name resolved in the environment over 30 days and keeps only those seen by five or fewer clients. Punycode A-labels cannot be compared to the brand inside the SIEM without Unicode confusable-skeleton normalization, so this hunt produces a small manual review queue instead: decode each xn-- label offline (idna/punycode decode) and check whether the rendered Unicode string is visually confusable with the organization's brand. Broad-reach punycode domains are almost always legitimate international infrastructure; narrow-reach ones are the interesting tail.

Hunting — KQL
kql
// Hunt: full 30-day inventory of punycode (IDN) A-labels resolved in the environment, ranked by first appearance
DnsEvents
| where TimeGenerated > ago(30d)
| extend Fqdn = tolower(Name)
| where Fqdn startswith "xn--" or Fqdn contains ".xn--"
| summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), QueryCount = count(),
            DistinctClients = dcount(ClientIP), SampleClients = make_set(ClientIP, 20), ResolvedIPs = make_set(IPAddresses, 10)
        by Fqdn
| where DistinctClients <= 5
| sort by FirstSeen desc
Hunting — SPL
spl
index=sysmon sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=22 earliest=-30d
| eval Fqdn=lower(QueryName)
| where match(Fqdn, "(^|\\.)xn--")
| stats count as QueryCount, dc(host) as DistinctHosts, values(host) as SampleHosts, values(QueryResults) as ResolvedIPs, min(_time) as FirstSeen, max(_time) as LastSeen by Fqdn
| where DistinctHosts<=5
| eval FirstSeen=strftime(FirstSeen, "%Y-%m-%d %H:%M:%S")
| sort - FirstSeen

Escalates from resolution to actual interaction. A DNS hit alone may be a link preview or a sandbox detonation; an HTTP session — particularly a POST with meaningful outbound bytes — indicates a user reached the page and may have submitted credentials. Run this immediately after any confirmed lookalike hit to scope which users actually interacted, and use BytesOut/http_method to separate page views from form submissions.

Hunting — KQL
kql
// Hunt: HTTP/S sessions from managed endpoints to hosts within two character edits of the organization's registrable label
let OrgLabel = "example";
let OrgOwnedRegex = @"(^|\.)example\.(com|net|org)$";
let BrandChars = extract_all(@"(.)", OrgLabel);
DeviceNetworkEvents
| where Timestamp > ago(14d)
| where isnotempty(RemoteUrl)
| extend Host = tolower(tostring(split(replace_string(replace_string(RemoteUrl, "https://", ""), "http://", ""), "/")[0]))
| where isnotempty(Host) and not(Host matches regex OrgOwnedRegex)
| extend Labels = split(Host, ".")
| extend RegLabel = tostring(Labels[array_length(Labels) - 2])
| where isnotempty(RegLabel) and RegLabel != OrgLabel
| extend LabelChars = extract_all(@"(.)", RegLabel)
| where abs(strlen(RegLabel) - strlen(OrgLabel)) <= 2
| where array_length(set_difference(BrandChars, LabelChars)) + array_length(set_difference(LabelChars, BrandChars)) <= 2
| summarize Sessions = count(), Users = make_set(InitiatingProcessAccountName, 20), Devices = make_set(DeviceName, 20), FirstSeen = min(Timestamp) by Host
| sort by FirstSeen desc
Hunting — SPL
spl
index=proxy sourcetype="proxy:web" earliest=-14d
| eval Host=lower(dest_host)
| where NOT match(Host, "(^|\\.)example\\.(com|net|org)$")
| eval RegLabel=mvindex(split(Host, "."), -2)
| where match(RegLabel, "^[e3][x][a4@](m|rn|nn)[p][l1i!][e3]$") OR match(RegLabel, "^(xample|eample|exmple|exaple|examle|exampe|exampl|xeample|eaxmple|exmaple|exapmle|examlpe|exampel)$") OR (match(RegLabel, "^e.?x.?a.?m.?p.?l.?e$") AND RegLabel!="example")
| stats count as Sessions, values(user) as Users, values(src_ip) as Sources, values(http_method) as Methods, sum(bytes_out) as BytesOut, min(_time) as FirstSeen by Host
| eval FirstSeen=strftime(FirstSeen, "%Y-%m-%d %H:%M:%S")
| sort - FirstSeen

Atomic Red Team Tests

Test 1 Resolve an ASCII Homoglyph Lookalike Domain (rn for m)
windows

Resolves a domain in which the letter 'm' of the brand label is replaced by the confusable pair 'rn', the single most common ASCII homoglyph substitution in phishing registrations, generating the DNS telemetry the homoglyph pillar is built to catch.

Command

powershell
nslookup exarnple.com 8.8.8.8

Expected Telemetry

Sysmon Event ID 22 (DNS Query) with QueryName='exarnple.com'. The corresponding DnsEvents row records Name='exarnple.com' with the resolving ClientIP and Computer. The lookup will likely return NXDOMAIN; the query attempt is logged regardless, and neither query is filtered on ResultCode.

Expected Detection

SquatType='AsciiHomoglyphSubstitution' in both the KQL and SPL detections, matched by the HomoglyphRegex alternation (m|rn|nn). Set OrgLabel to 'example' and OrgOwnedRegex to the example.(com|net|org) pattern shipped in the rule before running, or substitute your own brand's homoglyph variant.

Test 2 Resolve a Character-Transposition Typosquat Domain
windows

Resolves a domain whose registrable label is the brand with two adjacent characters swapped ('exampel' for 'example'), exercising the transposition pillar — in KQL via sorted-character multiset equality, in SPL via the enumerated dnstwist permutation set.

Command

powershell
powershell.exe -Command "Resolve-DnsName 'exampel.com' -Type A -ErrorAction SilentlyContinue"

Expected Telemetry

Sysmon Event ID 22 with QueryName='exampel.com' and Image pointing at powershell.exe. DnsEvents records Name='exampel.com' for the resolving client.

Expected Detection

SquatType='CharacterTransposition' in both detections. In KQL the sorted character string of 'exampel' is identical to that of 'example' while the labels differ; in SPL the label matches the enumerated transposition alternation. With no prior 30-day resolution history the row should also carry PriorHistory=false / NewToEnvironment=true, which is the intended alerting tier.

Test 3 Resolve a Punycode IDN A-Label
linux

Resolves an internationalized domain name in its punycode 'xn--' A-label form, simulating the Unicode homoglyph family that cannot be compared to the brand inside the SIEM and is instead surfaced by the first-seen punycode pillar for manual decode.

Command

bash
dig +short xn--exmple-4nf.com A @8.8.8.8

Expected Telemetry

A DNS query for 'xn--exmple-4nf.com' recorded by the recursive resolver and, on Windows endpoints running the equivalent lookup, Sysmon Event ID 22 with the same QueryName. The A-label is stored verbatim in the log; no Unicode decoding is performed by the logging pipeline.

Expected Detection

SquatType='IdnPunycodeFirstSeen' in KQL (the leftanti join against the prior 30 days succeeds because the label has never been resolved in the environment) and SquatType='IdnPunycode' in the SPL search. Because this pillar cannot assess confusability, the expected outcome is a low-volume manual review queue entry, not a high-confidence alert — decode the label offline to confirm whether it renders as the brand.

Test 4 Sweep an Enumerated Single-Edit Permutation Set
linux

Resolves several single-character-omission permutations of the brand label in quick succession, reproducing the pattern seen when an actor or a researcher walks a dnstwist permutation set, and validating that the detection aggregates multiple lookalike domains into a reviewable cluster rather than firing on only one.

Command

bash
for d in exmple.com exaple.com examle.com exampl.com; do dig +short "$d" A @8.8.8.8 >/dev/null; done

Expected Telemetry

Four DNS queries within a few seconds from a single client for exmple.com, exaple.com, examle.com, and exampl.com. Most will return NXDOMAIN, which is why neither detection filters on ResultCode / QueryStatus.

Expected Detection

Four rows with SquatType='CharacterSetDistanceLE2' (KQL, via length delta <= 2 and combined character-set difference <= 2) and SquatType='SingleCharacterOmission' (SPL, via the enumerated omission alternation), all with PriorHistory=false. Several distinct lookalike labels resolving from one client in a short window is the campaign-wave signal called out in the escalation criteria.

Related Detections