Detection rules › Sublime MQL
Business Email Compromise (BEC) attempt from untrusted sender (French/Français)
Detects potential Business Email Compromise (BEC) attacks by searching for common French BEC language within the email body from first-time senders.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud |
| Tactics and techniques | Social engineering |
Event coverage
Rule body MQL
type.inbound
and length(body.links) == 0
and ml.nlu_classifier(body.current_thread.text).language == "french"
and 1 of (
regex.icontains(subject.subject,
'(mise (a|à) jour|changé|changement).{0,20}(bancaire|de banque)'
),
regex.icontains(body.current_thread.text,
'(changement|changé) de (banque)|changement bancaire|coordonnées.{0,20}(compte|banque|bancaire|salaire)',
),
(regex.icontains(body.current_thread.text, 'parler.{0,20}confiance'))
)
// negating legit replies
and not (
(
strings.istarts_with(subject.subject, "RE:")
// out of office auto-reply
// the NLU model will handle these better natively soon
or strings.istarts_with(subject.subject, "Automatic reply:")
or regex.imatch(subject.subject,
'(\[[^\]]+\]\s?){0,3}(re|fwd?|automat.*)\s?:.*'
)
)
and (length(headers.references) > 0 or headers.in_reply_to is not null)
)
and (
not profile.by_sender().solicited
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().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
)
Detection logic
Scope: inbound message.
Detects potential Business Email Compromise (BEC) attacks by searching for common French BEC language within the email body from first-time senders.
- inbound message
- length(body.links) is 0
- ml.nlu_classifier(body.current_thread.text).language is 'french'
at least 1 of:
- subject.subject matches '(mise (a|à) jour|changé|changement).{0,20}(bancaire|de banque)'
- body.current_thread.text matches '(changement|changé) de (banque)|changement bancaire|coordonnées.{0,20}(compte|banque|bancaire|salaire)'
- body.current_thread.text matches 'parler.{0,20}confiance'
not:
all of:
any of:
- subject.subject starts with 'RE:'
- subject.subject starts with 'Automatic reply:'
- subject.subject matches '(\\[[^\\]]+\\]\\s?){0,3}(re|fwd?|automat.*)\\s?:.*'
any of:
- length(headers.references) > 0
- headers.in_reply_to is set
any of:
not:
- profile.by_sender().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().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
Inspects: body.current_thread.text, body.links, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, regex.icontains, regex.imatch, strings.istarts_with. Reference lists: $high_trust_sender_root_domains.
Indicators matched (6)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | (mise (a|à) jour|changé|changement).{0,20}(bancaire|de banque) |
regex.icontains | regex | (changement|changé) de (banque)|changement bancaire|coordonnées.{0,20}(compte|banque|bancaire|salaire) |
regex.icontains | regex | parler.{0,20}confiance |
strings.istarts_with | prefix | RE: |
strings.istarts_with | prefix | Automatic reply: |
regex.imatch | regex | (\[[^\]]+\]\s?){0,3}(re|fwd?|automat.*)\s?:.* |