Detection rules › Sublime MQL
Sublime MQL rules: sender
Free email provider sender with mismatched provider reply-to
#Detects when a sender using a free email provider includes a reply-to address from a different free email provider, which is a common social engineering tactic.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing |
| Tactics and techniques | Free email provider, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and sender.email.domain.root_domain in $free_email_providers
and length(headers.reply_to) > 0
and any(headers.reply_to,
.email.domain.root_domain in $free_email_providers
and .email.domain.root_domain != sender.email.domain.root_domain
and .email.domain.root_domain not in ("googlegroups.com")
)
// secureserver.net seems to rewrite the sender local part to be the reply-to domain for bounces
// observed in many newsletter sent via secureserver.net
and not (
strings.istarts_with(sender.email.domain.domain, 'bounces.')
and sender.email.domain.root_domain == 'secureserver.net'
and all(headers.reply_to,
strings.istarts_with(sender.email.local_part, .email.local_part)
and strings.iends_with(sender.email.local_part, .email.domain.domain)
)
)
// lists.riseup.net send from the list address and use the reply-to of the sender
// the sender is within the X-Original-From header and contains the full "From" header
and not (
sender.email.domain.domain == "lists.riseup.net"
and any(headers.hops,
any(.fields,
.name =~ "X-Original-From"
and any(headers.reply_to,
strings.icontains(..value, .email.email)
)
)
)
)
Detection logic
Scope: inbound message.
Detects when a sender using a free email provider includes a reply-to address from a different free email provider, which is a common social engineering tactic.
- inbound message
- sender.email.domain.root_domain in $free_email_providers
- length(headers.reply_to) > 0
any of
headers.reply_towhere all hold:- .email.domain.root_domain in $free_email_providers
- .email.domain.root_domain is not sender.email.domain.root_domain
- .email.domain.root_domain not in ('googlegroups.com')
not:
all of:
- sender.email.domain.domain starts with 'bounces.'
- sender.email.domain.root_domain is 'secureserver.net'
all of
headers.reply_towhere all hold:- strings.istarts_with(sender.email.local_part)
- strings.iends_with(sender.email.local_part)
not:
all of:
- sender.email.domain.domain is 'lists.riseup.net'
any of
headers.hopswhere:any of
.fieldswhere all hold:- .name is 'X-Original-From'
any of
headers.reply_towhere:- strings.icontains(.value)
Inspects: headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.reply_to, headers.reply_to[].email.domain.domain, headers.reply_to[].email.domain.root_domain, headers.reply_to[].email.email, headers.reply_to[].email.local_part, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.local_part, type.inbound. Sensors: strings.icontains, strings.iends_with, strings.istarts_with. Reference lists: $free_email_providers.
Stages and Predicates
Stage 1: mql_rule
and
not
and
any(headers.hops)
any(headers.hops.fields)
and
any(headers.reply_to)
strings.icontains func_call "strings.icontains(headers.hops[].fields[].value)"
headers.hops.fields[].name eq "X-Original-From"
sender.email.domain.domain eq "lists.riseup.net"
any(headers.reply_to)
and
not
headers.reply_to.email.domain.root_domain eq "googlegroups.com"
headers.reply_to.email.domain.root_domain cross_field_compare "sender.email.domain.root_domain"
macro "headers.reply_to[].email.domain.root_domain in free_email_providers"
not
and
sender.email.domain.domain starts_with "bounces."
sender.email.domain.root_domain eq "secureserver.net"
macro "all(headers.reply_to)"
headers.reply_to length_compare "0"
type.inbound eq "true"
macro "sender.email.domain.root_domain in free_email_providers"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.hops | array_any | excludes:headers.hops | |
sender.email.domain.domain | eq | lists.riseup.net | excludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"lists.riseup.net" |
sender.email.domain.domain | starts_with | bounces. | excludes:sender.email.domain.domain field:"sender.email.domain.domain" value:"bounces." |
sender.email.domain.root_domain | eq | secureserver.net | excludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"secureserver.net" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
New sender domain (<=10d) from untrusted sender
#Detects inbound emails where the sender domain is less than 10 days old from untrusted senders.
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and network.whois(sender.email.domain).days_old <= 10
and not profile.by_sender().solicited
Detection logic
Scope: inbound message.
Detects inbound emails where the sender domain is less than 10 days old from untrusted senders.
- inbound message
- network.whois(sender.email.domain).days_old ≤ 10
not:
- profile.by_sender().solicited
Inspects: sender.email.domain, type.inbound. Sensors: network.whois, profile.by_sender.
Stages and Predicates
Stage 1: mql_rule
and
not
profile.by_sender func_call "profile.by_sender().solicited"
network.whois func_call "network.whois(sender.email.domain).days_old <= 10"
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" |
Sender name contains Active Directory distinguished name
#Sender's display name contains an Active Directory distinguished name or a similar string. This has been observed as a malicious indicator in the wild.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
regex.icontains(sender.display_name, '\b(EX|LABS|OU|CN|EXCHANGE)(=|/)')
or strings.icontains(sender.display_name, "/O=EXCHANGELABS")
)
and sender.email.domain.root_domain not in $org_domains
and not (
sender.email.domain.root_domain in ('fnfcorp.com')
and headers.auth_summary.dmarc.pass
)
Detection logic
Scope: inbound message.
Sender's display name contains an Active Directory distinguished name or a similar string. This has been observed as a malicious indicator in the wild.
- inbound message
any of:
- sender.display_name matches '\\b(EX|LABS|OU|CN|EXCHANGE)(=|/)'
- sender.display_name contains '/O=EXCHANGELABS'
- sender.email.domain.root_domain not in $org_domains
not:
all of:
- sender.email.domain.root_domain in ('fnfcorp.com')
- headers.auth_summary.dmarc.pass
Inspects: headers.auth_summary.dmarc.pass, sender.display_name, sender.email.domain.root_domain, type.inbound. Sensors: regex.icontains, strings.icontains. Reference lists: $org_domains.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | \b(EX|LABS|OU|CN|EXCHANGE)(=|/) |
strings.icontains | substring | /O=EXCHANGELABS |
Stages and Predicates
Stage 1: mql_rule
and
not
and
headers.auth_summary.dmarc.pass eq "true"
sender.email.domain.root_domain eq "fnfcorp.com"
or
sender.display_name contains "/O=EXCHANGELABS"
sender.display_name regex_match "\\b(EX|LABS|OU|CN|EXCHANGE)(=|/)"
type.inbound eq "true"
macro "sender.email.domain.root_domain not in org_domains"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.auth_summary.dmarc.pass | eq | true | excludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true" |
sender.email.domain.root_domain | eq | fnfcorp.com | excludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"fnfcorp.com" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
sender.display_name | contains |
| field:"sender.display_name" kind:contains value:"/O=EXCHANGELABS" |
sender.display_name | regex_match |
| field:"sender.display_name" kind:regex_match value:"\b(EX|LABS|OU|CN|EXCHANGE)(=|/)" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Sender: IP address in local part
#Detects messages where the sender's email local part contains an IPv4 address, which is commonly used in malicious campaigns to bypass filters or appear legitimate.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Spam, Credential Phishing, BEC/Fraud |
| Tactics and techniques | Evasion, Spoofing |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and length(body.current_thread.text) > 100
and regex.icontains(sender.email.local_part,
'(?:\d{1,3}\.){3}\d{1,3}[^\.][[:alpha:]]+',
'[[:alpha:]]+(?:\d{1,3}\.){3}\d{1,3}[^\.]'
)
and not (
strings.ilike(sender.email.local_part, "*report*", "*abuse*")
or any(ml.nlu_classifier(body.current_thread.text).topics,
.name == "Bounce Back and Delivery Failure Notifications"
and .confidence != "low"
)
)
Detection logic
Scope: inbound message.
Detects messages where the sender's email local part contains an IPv4 address, which is commonly used in malicious campaigns to bypass filters or appear legitimate.
- inbound message
- length(body.current_thread.text) > 100
sender.email.local_part matches any of 2 patterns
(?:\d{1,3}\.){3}\d{1,3}[^\.][[:alpha:]]+[[:alpha:]]+(?:\d{1,3}\.){3}\d{1,3}[^\.]
none of:
sender.email.local_part matches any of 2 patterns
*report**abuse*
any of
ml.nlu_classifier(body.current_thread.text).topicswhere all hold:- .name is 'Bounce Back and Delivery Failure Notifications'
- .confidence is not 'low'
Inspects: body.current_thread.text, sender.email.local_part, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.ilike.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | (?:\d{1,3}\.){3}\d{1,3}[^\.][[:alpha:]]+ |
regex.icontains | regex | [[:alpha:]]+(?:\d{1,3}\.){3}\d{1,3}[^\.] |
Stages and Predicates
Stage 1: mql_rule
and
not
or
any(ml.nlu_classifier(body.current_thread.text).topics)
and
ml.nlu_classifier(body.current_thread.text).topics.confidence ne "low"
ml.nlu_classifier(body.current_thread.text).topics.name eq "Bounce Back and Delivery Failure Notifications"
sender.email.local_part match "abuse"
sender.email.local_part match "report"
or
sender.email.local_part regex_match "(?:\\d{1,3}\\.){3}\\d{1,3}[^\\.][[:alpha:]]+"
sender.email.local_part regex_match "[[:alpha:]]+(?:\\d{1,3}\\.){3}\\d{1,3}[^\\.]"
body.current_thread.text length_compare "100"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
ml.nlu_classifier(body.current_thread.text).topics | array_any | excludes:ml.nlu_classifier(body.current_thread.text).topics | |
sender.email.local_part | match | abuse | excludes:sender.email.local_part field:"sender.email.local_part" value:"abuse" |
sender.email.local_part | match | report | excludes:sender.email.local_part field:"sender.email.local_part" value:"report" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
sender.email.local_part | regex_match |
| field:"sender.email.local_part" kind:regex_match |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Suspicious display name: Gmail sender with engaging language
#Detects Gmail senders using display names with suspicious language patterns commonly associated with social engineering tactics, including urgency indicators, contact requests, and verification prompts.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing |
| Tactics and techniques | Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and 2 of (
strings.icontains(sender.display_name, "kindly"),
strings.icontains(sender.display_name, 'phone'),
strings.icontains(sender.display_name, 'cell'),
strings.icontains(sender.display_name, 'expedite'),
strings.icontains(sender.display_name, 'urgent'),
strings.icontains(sender.display_name, 'contact'),
strings.icontains(sender.display_name, 'review'),
strings.icontains(sender.display_name, 'confirm'),
strings.icontains(sender.display_name, 'asap'),
strings.icontains(sender.display_name, 'follow up'),
strings.icontains(sender.display_name, 'nicely'),
strings.icontains(sender.display_name, 'btc'),
strings.icontains(sender.display_name, 'reply'),
strings.icontains(sender.display_name, 'respond'),
strings.icontains(sender.display_name, 'verify'),
strings.icontains(sender.display_name, 'convenience'),
strings.icontains(sender.display_name, 'response'),
strings.icontains(sender.display_name, 'number'),
strings.icontains(sender.display_name, 'mobile'),
strings.icontains(sender.display_name, 'text'),
strings.icontains(sender.display_name, 'request'),
strings.icontains(sender.display_name, 'required'),
strings.icontains(sender.display_name, 'important'),
strings.icontains(sender.display_name, 'need'),
strings.icontains(sender.display_name, 'quick'),
strings.icontains(sender.display_name, 'sensitive'),
strings.icontains(sender.display_name, 'reach'),
strings.icontains(sender.display_name, 'action'),
(
strings.icontains(sender.display_name, 'monday')
or strings.icontains(sender.display_name, 'tuesday')
or strings.icontains(sender.display_name, 'wednesday')
or strings.icontains(sender.display_name, 'thursday')
or strings.icontains(sender.display_name, 'friday')
or strings.icontains(sender.display_name, 'saturday')
or strings.icontains(sender.display_name, 'sunday')
),
(
strings.icontains(sender.display_name, 'january')
or strings.icontains(sender.display_name, 'february')
or strings.icontains(sender.display_name, 'march')
or strings.icontains(sender.display_name, 'april')
or strings.icontains(sender.display_name, 'may')
or strings.icontains(sender.display_name, 'june')
or strings.icontains(sender.display_name, 'july')
or strings.icontains(sender.display_name, 'august')
or strings.icontains(sender.display_name, 'september')
or strings.icontains(sender.display_name, 'october')
or strings.icontains(sender.display_name, 'november')
or strings.icontains(sender.display_name, 'december')
)
)
and sender.email.domain.domain == 'gmail.com'
and length(attachments) == 0
and length(body.current_thread.links) == 0
Detection logic
Scope: inbound message.
Detects Gmail senders using display names with suspicious language patterns commonly associated with social engineering tactics, including urgency indicators, contact requests, and verification prompts.
- inbound message
at least 2 of:
- sender.display_name contains 'kindly'
- sender.display_name contains 'phone'
- sender.display_name contains 'cell'
- sender.display_name contains 'expedite'
- sender.display_name contains 'urgent'
- sender.display_name contains 'contact'
- sender.display_name contains 'review'
- sender.display_name contains 'confirm'
- sender.display_name contains 'asap'
- sender.display_name contains 'follow up'
- sender.display_name contains 'nicely'
- sender.display_name contains 'btc'
- sender.display_name contains 'reply'
- sender.display_name contains 'respond'
- sender.display_name contains 'verify'
- sender.display_name contains 'convenience'
- sender.display_name contains 'response'
- sender.display_name contains 'number'
- sender.display_name contains 'mobile'
- sender.display_name contains 'text'
- sender.display_name contains 'request'
- sender.display_name contains 'required'
- sender.display_name contains 'important'
- sender.display_name contains 'need'
- sender.display_name contains 'quick'
- sender.display_name contains 'sensitive'
- sender.display_name contains 'reach'
- sender.display_name contains 'action'
sender.display_name contains any of 7 patterns
mondaytuesdaywednesdaythursdayfridaysaturdaysunday
sender.display_name contains any of 12 patterns
januaryfebruarymarchaprilmayjunejulyaugustseptemberoctobernovemberdecember
- sender.email.domain.domain is 'gmail.com'
- length(attachments) is 0
- length(body.current_thread.links) is 0
Inspects: body.current_thread.links, sender.display_name, sender.email.domain.domain, type.inbound. Sensors: strings.icontains.
Indicators matched (48)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | kindly |
strings.icontains | substring | phone |
strings.icontains | substring | cell |
strings.icontains | substring | expedite |
strings.icontains | substring | urgent |
strings.icontains | substring | contact |
strings.icontains | substring | review |
strings.icontains | substring | confirm |
strings.icontains | substring | asap |
strings.icontains | substring | follow up |
strings.icontains | substring | nicely |
strings.icontains | substring | btc |
36 more
strings.icontains | substring | reply |
strings.icontains | substring | respond |
strings.icontains | substring | verify |
strings.icontains | substring | convenience |
strings.icontains | substring | response |
strings.icontains | substring | number |
strings.icontains | substring | mobile |
strings.icontains | substring | text |
strings.icontains | substring | request |
strings.icontains | substring | required |
strings.icontains | substring | important |
strings.icontains | substring | need |
strings.icontains | substring | quick |
strings.icontains | substring | sensitive |
strings.icontains | substring | reach |
strings.icontains | substring | action |
strings.icontains | substring | monday |
strings.icontains | substring | tuesday |
strings.icontains | substring | wednesday |
strings.icontains | substring | thursday |
strings.icontains | substring | friday |
strings.icontains | substring | saturday |
strings.icontains | substring | sunday |
strings.icontains | substring | january |
strings.icontains | substring | february |
strings.icontains | substring | march |
strings.icontains | substring | april |
strings.icontains | substring | may |
strings.icontains | substring | june |
strings.icontains | substring | july |
strings.icontains | substring | august |
strings.icontains | substring | september |
strings.icontains | substring | october |
strings.icontains | substring | november |
strings.icontains | substring | december |
sender.email.domain.domain | equals | gmail.com |
Stages and Predicates
Stage 1: mql_rule
and
or
sender.display_name contains "action"
sender.display_name contains "april"
sender.display_name contains "asap"
sender.display_name contains "august"
sender.display_name contains "btc"
sender.display_name contains "cell"
sender.display_name contains "confirm"
sender.display_name contains "contact"
sender.display_name contains "convenience"
sender.display_name contains "december"
sender.display_name contains "expedite"
sender.display_name contains "february"
sender.display_name contains "follow up"
sender.display_name contains "friday"
sender.display_name contains "important"
sender.display_name contains "january"
sender.display_name contains "july"
sender.display_name contains "june"
sender.display_name contains "kindly"
sender.display_name contains "march"
sender.display_name contains "may"
sender.display_name contains "mobile"
sender.display_name contains "monday"
sender.display_name contains "need"
sender.display_name contains "nicely"
sender.display_name contains "november"
sender.display_name contains "number"
sender.display_name contains "october"
sender.display_name contains "phone"
sender.display_name contains "quick"
sender.display_name contains "reach"
sender.display_name contains "reply"
sender.display_name contains "request"
sender.display_name contains "required"
sender.display_name contains "respond"
sender.display_name contains "response"
sender.display_name contains "review"
sender.display_name contains "saturday"
sender.display_name contains "sensitive"
sender.display_name contains "september"
sender.display_name contains "sunday"
sender.display_name contains "text"
sender.display_name contains "thursday"
sender.display_name contains "tuesday"
sender.display_name contains "urgent"
sender.display_name contains "verify"
sender.display_name contains "wednesday"
attachments length_compare "0"
body.current_thread.links length_compare "0"
sender.email.domain.domain eq "gmail.com"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
sender.display_name | contains |
| field:"sender.display_name" kind:contains |
sender.email.domain.domain | eq |
| field:"sender.email.domain.domain" kind:eq value:"gmail.com" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Unusually long local part from untrusted sender address
#Detects messages with unusually long local address parts (before the @) from senders outside trusted domains and without verified authentication.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Spam |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
// max length of the local_part for exchange is 315
// https://learn.microsoft.com/en-us/exchange/mail-flow/mail-routing/recipient-resolution?view=exchserver-2019&viewFallbackFrom=exchonline-ww
100 < length(sender.email.local_part)
// not org_domains
and not (
sender.email.domain.root_domain in $org_domains
and headers.auth_summary.dmarc.pass
)
// negate highly trusted sender domains unless they fail DMARC authentication
and not (
sender.email.domain.root_domain in $high_trust_sender_root_domains
and headers.auth_summary.dmarc.pass
)
// remove common senders, unless marked malicious
and not (
profile.by_sender_email().prevalence == "common"
and profile.by_sender_email().any_messages_malicious_or_spam == false
)
// a common observed benign cases of this due to Internet Mail Connector Encapsulated Address (IMCEA)
and not strings.istarts_with(sender.email.local_part, 'imcea')
// no previous false positives on this specific sender
and not profile.by_sender_email().any_messages_benign
Detection logic
Detects messages with unusually long local address parts (before the @) from senders outside trusted domains and without verified authentication.
- length(sender.email.local_part) > 100
not:
all of:
- sender.email.domain.root_domain in $org_domains
- headers.auth_summary.dmarc.pass
not:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
- headers.auth_summary.dmarc.pass
not:
all of:
- profile.by_sender_email().prevalence is 'common'
- profile.by_sender_email().any_messages_malicious_or_spam is False
not:
- sender.email.local_part starts with 'imcea'
not:
- profile.by_sender_email().any_messages_benign
Inspects: headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, sender.email.local_part. Sensors: profile.by_sender_email, strings.istarts_with. Reference lists: $high_trust_sender_root_domains, $org_domains.
Stages and Predicates
Stage 1: mql_rule
and
not
and
headers.auth_summary.dmarc.pass eq "true"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
not
and
headers.auth_summary.dmarc.pass eq "true"
macro "sender.email.domain.root_domain in org_domains"
not
and
profile.by_sender_email func_call "profile.by_sender_email().any_messages_malicious_or_spam == false"
profile.by_sender_email func_call "profile.by_sender_email().prevalence == common"
not
profile.by_sender_email func_call "profile.by_sender_email().any_messages_benign"
not
sender.email.local_part starts_with "imcea"
sender.email.local_part length_compare "100"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.auth_summary.dmarc.pass | eq | true | excludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true" |
sender.email.local_part | starts_with | imcea | excludes:sender.email.local_part field:"sender.email.local_part" value:"imcea" |