Detection rules › Sublime MQL
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 |
Event coverage
Rule body MQL
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 of
$sender_domainswhere all hold:- strings.ilevenshtein(.) > 0
- strings.ilevenshtein(.) < 3
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'bec'
- .confidence is not 'low'
any of
ml.nlu_classifier(body.current_thread.text).topicswhere all hold:- .name in ('Financial Communications', 'E-Signature', 'Benefit Enrollment')
- .confidence is 'high'
at least 1 of:
not:
- network.whois(sender.email.domain).found
any of
body.previous_threadswhere:- strings.icontains(.preamble)
any of:
- profile.by_sender_domain().prevalence is '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 |