Detection rules › Sublime MQL
Sublime MQL rules: vendor
| Rule | Severity |
|---|---|
| Vendor impersonation: Thread hijacking with typosquat domain | high |
Vendor impersonation: Thread hijacking with typosquat domain
#Detects potential thread hijacking where the sender uses a domain similar to known senders, exhibits BEC behavior, and shows signs of compromised thread continuity through domain spoofing or thread manipulation.
Threat Classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | Lookalike domain, Social engineering, Spoofing |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message Attributes
Rule Body
type.inbound
and subject.is_reply
and sender.email.domain.root_domain not in $sender_domains
// current sender has not been seen in the thread before
and any(body.previous_threads, .sender.email.domain.domain not in $org_domains)
and all(body.previous_threads,
.sender.email.domain.domain != sender.email.domain.domain
and all(.recipients.to,
.email.domain.domain != sender.email.domain.domain
)
and all(.recipients.cc,
.email.domain.domain != sender.email.domain.domain
)
)
and any($sender_domains,
0 < strings.ilevenshtein(., sender.email.domain.root_domain) < 3
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "bec" and .confidence != "low"
)
// risky category
and any(ml.nlu_classifier(body.current_thread.text).topics,
.name in (
"Financial Communications",
"E-Signature",
"Benefit Enrollment"
)
and .confidence == "high"
)
and 1 of (
not network.whois(sender.email.domain).found,
any(body.previous_threads, strings.icontains(.preamble, sender.display_name))
)
and (
profile.by_sender_domain().prevalence == "new"
or profile.by_sender_domain().days_known < 3
)
Detection Logic
Scope: inbound message.
Detects potential thread hijacking where the sender uses a domain similar to known senders, exhibits BEC behavior, and shows signs of compromised thread continuity through domain spoofing or thread manipulation.
- inbound message
- subject.is_reply
- sender.email.domain.root_domain not in $sender_domains
any of
body.previous_threadswhere:- .sender.email.domain.domain not in $org_domains
all of
body.previous_threadswhere all hold:- .sender.email.domain.domain is not sender.email.domain.domain
all of
.recipients.towhere:- .email.domain.domain is not sender.email.domain.domain
all of
.recipients.ccwhere:- .email.domain.domain is not sender.email.domain.domain
- any($sender_domains, 0 < strings.ilevenshtein(., sender.email.domain.root_domain) < 3 )
- any(ml.nlu_classifier(body.current_thread.text).intents, .name == "bec" and .confidence != "low" )
- any(ml.nlu_classifier(body.current_thread.text).topics, .name in ( "Financial Communications", "E-Signature", "Benefit Enrollment" ) and .confidence == "high" )
at least 1 of:
not:
- network.whois(sender.email.domain).found
any of
body.previous_threadswhere:- strings.icontains(.preamble, sender.display_name)
any of:
- profile.by_sender_domain().prevalence == "new"
- profile.by_sender_domain().days_known < 3
Inspects: body.current_thread.text, body.previous_threads, body.previous_threads[].preamble, body.previous_threads[].recipients.cc, body.previous_threads[].recipients.cc[].email.domain.domain, body.previous_threads[].recipients.to, body.previous_threads[].recipients.to[].email.domain.domain, body.previous_threads[].sender.email.domain.domain, sender.display_name, sender.email.domain, sender.email.domain.domain, sender.email.domain.root_domain, subject.is_reply, type.inbound. Sensors: ml.nlu_classifier, network.whois, profile.by_sender_domain, strings.icontains, strings.ilevenshtein. Reference lists: $org_domains, $sender_domains.
Indicators Matched (5)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | bec |
ml.nlu_classifier(body.current_thread.text).topics[].name | member | Financial Communications |
ml.nlu_classifier(body.current_thread.text).topics[].name | member | E-Signature |
ml.nlu_classifier(body.current_thread.text).topics[].name | member | Benefit Enrollment |
ml.nlu_classifier(body.current_thread.text).topics[].confidence | equals | high |
Stages and Predicates
Stage 1: mql_rule
and
or
not
network.whois func_call "network.whois(sender.email.domain).found"
any(body.previous_threads)
strings.icontains func_call "strings.icontains(.preamble, sender.display_name)"
any(body.previous_threads)
body.previous_threads.sender.email.domain.domain macro "body.previous_threads[].sender.email.domain.domain not in org_domains"
or
profile.by_sender_domain func_call "profile.by_sender_domain().days_known < 3"
profile.by_sender_domain func_call "profile.by_sender_domain().prevalence == \"new\""
sender.email.domain.root_domain macro "sender.email.domain.root_domain not in sender_domains"
subject.is_reply eq "true"
type.inbound eq "true"
macro "all(body.previous_threads,\n .sender.email.domain.domain != sender.email.domain.domain\n and all(.recipients.to,\n .email.domain.domain != sender.email.domain.domain\n )\n and all(.recipients.cc,\n .email.domain.domain != sender.email.domain.domain\n )\n)"
macro "any($sender_domains,\n 0 < strings.ilevenshtein(., sender.email.domain.root_domain) < 3\n)"
macro "any(ml.nlu_classifier(body.current_thread.text).intents,\n .name == \"bec\" and .confidence != \"low\"\n)"
macro "any(ml.nlu_classifier(body.current_thread.text).topics,\n .name in (\n \"Financial Communications\",\n \"E-Signature\",\n \"Benefit Enrollment\"\n )\n and .confidence == \"high\"\n)"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
subject.is_reply | eq |
| field:"subject.is_reply" kind:eq value:"true" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |