Detection rules › Sublime MQL
Sublime MQL rules: lookalike
| Rule | Severity |
|---|---|
| Lookalike sender domain (untrusted sender) | high |
| Suspected lookalike domain with suspicious language | medium |
Lookalike sender domain (untrusted sender)
#Sender's domain is a lookalike of one of your organization's domains and is untrusted.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Lookalike domain, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(sender.email.domain.sld) > 3
and sender.email.domain.domain not in $org_domains
and any($org_domains,
// this rule can be duplicated in order to tune the threshold
strings.ilevenshtein(sender.email.domain.domain, .) == 1
)
and (
(
profile.by_sender_email().prevalence in ("new", "outlier")
and not profile.by_sender_email().solicited
)
or (
profile.by_sender_email().any_messages_malicious_or_spam
and not profile.by_sender_email().any_messages_benign
)
)
// negate highly trusted sender domains unless they fail DMARC authentication
and (
(
sender.email.domain.root_domain in $high_trust_sender_root_domains
and not headers.auth_summary.dmarc.pass
)
or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
and not profile.by_sender_email().any_messages_benign
Detection logic
Scope: inbound message.
Sender's domain is a lookalike of one of your organization's domains and is untrusted.
- inbound message
- length(sender.email.domain.sld) > 3
- sender.email.domain.domain not in $org_domains
any of
$org_domainswhere:- strings.ilevenshtein(sender.email.domain.domain) is 1
any of:
all of:
- profile.by_sender_email().prevalence in ('new', 'outlier')
not:
- profile.by_sender_email().solicited
all of:
- profile.by_sender_email().any_messages_malicious_or_spam
not:
- profile.by_sender_email().any_messages_benign
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
not:
- headers.auth_summary.dmarc.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
not:
- profile.by_sender_email().any_messages_benign
Inspects: headers.auth_summary.dmarc.pass, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.sld, type.inbound. Sensors: profile.by_sender_email, strings.ilevenshtein. Reference lists: $high_trust_sender_root_domains, $org_domains.
Stages and Predicates
Stage 1: mql_rule
and
or
and
not
headers.auth_summary.dmarc.pass eq "true"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
or
and
not
profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
profile.by_sender_email func_call "profile.by_sender_email().any_messages_malicious_or_spam"
and
not
profile.by_sender_email func_call "profile.by_sender_email().solicited"
profile.by_sender_email func_call "profile.by_sender_email().prevalence in (new, outlier)"
not
profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
any($org_domains)
strings.ilevenshtein func_call "strings.ilevenshtein(sender.email.domain.domain) == 1"
sender.email.domain.sld length_compare "3"
type.inbound eq "true"
macro "sender.email.domain.domain not in org_domains"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Suspected lookalike domain with suspicious language
#This rule identifies messages where links use typosquatting or lookalike domains similar to the sender domain, with at least one domain being either unregistered or recently registered (≤90 days). The messages must also contain indicators of business email compromise (BEC), credential theft, or abusive language patterns like financial terms or polite phrasing such as kindly. This layered approach targets phishing attempts combining domain deception with manipulative content
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | Evasion, Lookalike domain, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// levenshtein distance (edit distance) between the SLD of the link and the sender domain is greater than 0 and less than or equal to 2.
// This detects typosquatting or domains that are deceptively similar to the sender.
and any(body.links,
length(.href_url.domain.sld) > 3
and 0 < strings.levenshtein(.href_url.domain.sld,
sender.email.domain.sld
) <= 2
// exclude onmicrosoft.com
and not sender.email.domain.root_domain == "onmicrosoft.com"
and (
// domains are not registered or registered within 90d
// network.whois(.href_url.domain).found == false
network.whois(.href_url.domain).days_old <= 90
or network.whois(sender.email.domain).found == false
or network.whois(sender.email.domain).days_old <= 90
)
)
// the mesasge is intent is BEC or Cred Theft, or is talking about financial invoicing/banking language, or a request contains "kindly"
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name in ("bec", "cred_theft")
or any(ml.nlu_classifier(body.current_thread.text).entities,
.name == "financial"
and (
.text in ("invoice", "banking information")
or .name == "request" and strings.icontains(.text, "kindly")
)
)
)
Detection logic
Scope: inbound message.
This rule identifies messages where links use typosquatting or lookalike domains similar to the sender domain, with at least one domain being either unregistered or recently registered (≤90 days). The messages must also contain indicators of business email compromise (BEC), credential theft, or abusive language patterns like financial terms or polite phrasing such as kindly. This layered approach targets phishing attempts combining domain deception with manipulative content
- inbound message
any of
body.linkswhere all hold:- length(.href_url.domain.sld) > 3
all of:
- strings.levenshtein(.href_url.domain.sld) > 0
- strings.levenshtein(.href_url.domain.sld) ≤ 2
not:
- sender.email.domain.root_domain is 'onmicrosoft.com'
any of:
- network.whois(.href_url.domain).days_old ≤ 90
- network.whois(sender.email.domain).found is False
- network.whois(sender.email.domain).days_old ≤ 90
any of
ml.nlu_classifier(body.current_thread.text).intentswhere any holds:- .name in ('bec', 'cred_theft')
any of
ml.nlu_classifier(body.current_thread.text).entitieswhere all hold:- .name is 'financial'
any of:
- .text in ('invoice', 'banking information')
all of:
- .name is 'request'
- .text contains 'kindly'
Inspects: body.current_thread.text, body.links, body.links[].href_url.domain, body.links[].href_url.domain.sld, sender.email.domain, sender.email.domain.root_domain, sender.email.domain.sld, type.inbound. Sensors: ml.nlu_classifier, network.whois, strings.icontains, strings.levenshtein.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(body.current_thread.text).intents[].name | member | bec |
ml.nlu_classifier(body.current_thread.text).intents[].name | member | cred_theft |
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | financial |
ml.nlu_classifier(body.current_thread.text).entities[].text | member | invoice |
ml.nlu_classifier(body.current_thread.text).entities[].text | member | banking information |
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | request |
strings.icontains | substring | kindly |
Stages and Predicates
Stage 1: mql_rule
and
any(ml.nlu_classifier(body.current_thread.text).intents)
or
any(ml.nlu_classifier(body.current_thread.text).entities)
and
or
and
ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
ml.nlu_classifier(body.current_thread.text).entities.text contains "kindly"
ml.nlu_classifier(body.current_thread.text).entities.text in ["banking information", "invoice"]
ml.nlu_classifier(body.current_thread.text).entities.name eq "financial"
ml.nlu_classifier(body.current_thread.text).intents.name in ["bec", "cred_theft"]
any(body.links)
and
or
network.whois func_call "network.whois(body.links[].href_url.domain).days_old <= 90"
network.whois func_call "network.whois(sender.email.domain).days_old <= 90"
network.whois func_call "network.whois(sender.email.domain).found == false"
not
sender.email.domain.root_domain eq "onmicrosoft.com"
body.links.href_url.domain.sld length_compare "3"
strings.levenshtein func_call "strings.levenshtein(body.links[].href_url.domain.sld) <= 2"
strings.levenshtein func_call "strings.levenshtein(body.links[].href_url.domain.sld) > 0"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |