Detection rules › Sublime MQL
Sublime MQL rules: self
Headers: Self-sender using Microsoft CompAuth bypass with credential theft content
#Detects messages sent to self or invalid domains containing credential theft content that bypass Microsoft's CompAuth while failing both SPF and DMARC authentication checks.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Spoofing, Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// self sender
and length(recipients.to) == 1
and length(recipients.cc) == 0
and length(recipients.bcc) == 0
and (
sender.email.email == recipients.to[0].email.email
or recipients.to[0].email.domain.valid == false
)
// cred theft
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "cred_theft" and .confidence != "low"
)
// microsoft compauth pass, but spf and dmarc fail
and any(headers.hops, any(.fields, strings.icontains(.value, 'compauth=pass')))
and not coalesce(headers.auth_summary.dmarc.pass, false)
and not coalesce(headers.auth_summary.spf.pass, false)
Detection logic
Scope: inbound message.
Detects messages sent to self or invalid domains containing credential theft content that bypass Microsoft's CompAuth while failing both SPF and DMARC authentication checks.
- inbound message
- length(recipients.to) is 1
- length(recipients.cc) is 0
- length(recipients.bcc) is 0
any of:
- sender.email.email is recipients.to[0].email.email
- recipients.to[0].email.domain.valid is False
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence is not 'low'
any of
headers.hopswhere:any of
.fieldswhere:- .value contains 'compauth=pass'
not:
- coalesce(headers.auth_summary.dmarc.pass)
not:
- coalesce(headers.auth_summary.spf.pass)
Inspects: body.current_thread.text, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.hops, headers.hops[].fields, headers.hops[].fields[].value, recipients.bcc, recipients.cc, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, strings.icontains.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | cred_theft |
strings.icontains | substring | compauth=pass |
Stages and Predicates
Stage 1: mql_rule
and
any(headers.hops)
any(headers.hops.fields)
headers.hops.fields.value contains "compauth=pass"
any(ml.nlu_classifier(body.current_thread.text).intents)
and
ml.nlu_classifier(body.current_thread.text).intents.confidence ne "low"
ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
not
coalesce func_call "coalesce(headers.auth_summary.dmarc.pass)"
not
coalesce func_call "coalesce(headers.auth_summary.spf.pass)"
or
recipients.to[0].email.domain.valid eq "false"
sender.email.email cross_field_compare "recipients.to[0].email.email"
recipients.bcc length_compare "0"
recipients.cc length_compare "0"
recipients.to length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
recipients.to[0].email.domain.valid | eq |
| field:"recipients.to[0].email.domain.valid" kind:eq value:"false" |
sender.email.email | cross_field_compare |
| field:"sender.email.email" kind:cross_field_compare value:"recipients.to[0].email.email" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Link: Single character path with credential theft body and self sender behavior or invalid recipient
#Message where the sender and recipient are the same or the recipient domain is invalid, contains a link with a single character path and no query parameters or fragments, and includes credential theft language.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// self sender or invaild recipent domain
and length(recipients.to) == 1
and (
sender.email.email == recipients.to[0].email.email
or recipients.to[0].email.domain.valid == false
)
// path contains 1 character
and any(body.current_thread.links,
regex.imatch(.href_url.path, '\/[A-Za-z0-9]')
and .href_url.query_params is null
and .href_url.fragment is null
and .display_url.url is null
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "cred_theft" and .confidence != "low"
)
Detection logic
Scope: inbound message.
Message where the sender and recipient are the same or the recipient domain is invalid, contains a link with a single character path and no query parameters or fragments, and includes credential theft language.
- inbound message
- length(recipients.to) is 1
any of:
- sender.email.email is recipients.to[0].email.email
- recipients.to[0].email.domain.valid is False
any of
body.current_thread.linkswhere all hold:- .href_url.path matches '\\/[A-Za-z0-9]'
- .href_url.query_params is missing
- .href_url.fragment is missing
- .display_url.url is missing
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence is not 'low'
Inspects: body.current_thread.links, body.current_thread.links[].display_url.url, body.current_thread.links[].href_url.fragment, body.current_thread.links[].href_url.path, body.current_thread.links[].href_url.query_params, body.current_thread.text, recipients.to, recipients.to[0].email.domain.valid, recipients.to[0].email.email, sender.email.email, type.inbound. Sensors: ml.nlu_classifier, regex.imatch.
Indicators matched (2)
| Field | Match | Value |
|---|---|---|
regex.imatch | regex | \/[A-Za-z0-9] |
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | cred_theft |
Stages and Predicates
Stage 1: mql_rule
and
any(body.current_thread.links)
and
body.current_thread.links.display_url.url is_null
body.current_thread.links.href_url.fragment is_null
body.current_thread.links.href_url.path regex_match "\\/[A-Za-z0-9]"
body.current_thread.links.href_url.query_params is_null
any(ml.nlu_classifier(body.current_thread.text).intents)
and
ml.nlu_classifier(body.current_thread.text).intents.confidence ne "low"
ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
or
recipients.to[0].email.domain.valid eq "false"
sender.email.email cross_field_compare "recipients.to[0].email.email"
recipients.to length_compare "1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
recipients.to[0].email.domain.valid | eq |
| field:"recipients.to[0].email.domain.valid" kind:eq value:"false" |
sender.email.email | cross_field_compare |
| field:"sender.email.email" kind:cross_field_compare value:"recipients.to[0].email.email" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Self-sender with copy/paste instructions and suspicious domains (French/Français)
#Detects messages where the sender emails themselves with French text containing 'copier' (copy) and 'coller' (paste) instructions, along with suspicious domains like pages.dev or web.app. The subject line contains both the sender's email and display name, which are different values.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Free subdomain host, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// self sender
and (
length(recipients.to) == 1
and length(recipients.cc) == 0
and sender.email.email in map(recipients.to, .email.email)
)
and strings.icontains(subject.subject, sender.email.email)
and strings.icontains(subject.subject, sender.display_name)
and sender.email.email != sender.display_name
// copy
and strings.icontains(body.current_thread.text, 'copier')
// paste
and strings.icontains(body.current_thread.text, 'coller')
and (
strings.contains(body.current_thread.text, '.pages.dev')
or strings.contains(body.current_thread.text, '.web.app')
)
Detection logic
Scope: inbound message.
Detects messages where the sender emails themselves with French text containing 'copier' (copy) and 'coller' (paste) instructions, along with suspicious domains like pages.dev or web.app. The subject line contains both the sender's email and display name, which are different values.
- inbound message
all of:
- length(recipients.to) is 1
- length(recipients.cc) is 0
- sender.email.email in map(recipients.to, .email.email)
- strings.icontains(subject.subject)
- strings.icontains(subject.subject)
- sender.email.email is not sender.display_name
- body.current_thread.text contains 'copier'
- body.current_thread.text contains 'coller'
any of:
- body.current_thread.text contains '.pages.dev'
- body.current_thread.text contains '.web.app'
Inspects: body.current_thread.text, recipients.cc, recipients.to, recipients.to[].email.email, sender.display_name, sender.email.email, subject.subject, type.inbound. Sensors: strings.contains, strings.icontains.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | copier |
strings.icontains | substring | coller |
strings.contains | substring | .pages.dev |
strings.contains | substring | .web.app |
Stages and Predicates
Stage 1: mql_rule
and
or
body.current_thread.text contains ".pages.dev"
body.current_thread.text contains ".web.app"
body.current_thread.text contains "coller"
body.current_thread.text contains "copier"
recipients.cc length_compare "0"
recipients.to length_compare "1"
sender.email.email cross_field_compare "sender.display_name"
strings.icontains func_call "strings.icontains(subject.subject)"
type.inbound eq "true"
macro "sender.email.email in map(recipients.to, .email.email)"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | contains |
| field:"body.current_thread.text" kind:contains |
sender.email.email | cross_field_compare |
| field:"sender.email.email" kind:cross_field_compare value:"sender.display_name" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |