Detection rules › Sublime MQL
Sublime MQL rules: cred
| Rule | Severity |
|---|---|
| Link: Non-standard port 8443 in display URL | medium |
| Suspicious invoice reference with missing or image-only attachments | high |
Link: Non-standard port 8443 in display URL
#Detects links containing port 8443 in the display URL, which may indicate suspicious redirect or hosting infrastructure.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing, Malware/Ransomware |
| Tactics and techniques | Evasion |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
// no previous threads
length(body.previous_threads) == 0
// or is a fake thread
or (
(length(headers.references) == 0 or headers.in_reply_to is null)
and (
subject.is_reply
or subject.is_forward
or length(body.previous_threads) > 0
)
)
)
and any(body.links,
strings.contains(.display_url.url, ':8443')
and network.whois(.href_url.domain).days_old <= 365
)
// Negate noreply-spamdigest senders
and not (
sender.email.email == "noreply-spamdigest@google.com"
and headers.auth_summary.dmarc.pass
)
Detection logic
Scope: inbound message.
Detects links containing port 8443 in the display URL, which may indicate suspicious redirect or hosting infrastructure.
- inbound message
any of:
- length(body.previous_threads) is 0
all of:
any of:
- length(headers.references) is 0
- headers.in_reply_to is missing
any of:
- subject.is_reply
- subject.is_forward
- length(body.previous_threads) > 0
any of
body.linkswhere all hold:- .display_url.url contains ':8443'
- network.whois(.href_url.domain).days_old ≤ 365
not:
all of:
- sender.email.email is 'noreply-spamdigest@google.com'
- headers.auth_summary.dmarc.pass
Inspects: body.links, body.links[].display_url.url, body.links[].href_url.domain, body.previous_threads, headers.auth_summary.dmarc.pass, headers.in_reply_to, headers.references, sender.email.email, subject.is_forward, subject.is_reply, type.inbound. Sensors: network.whois, strings.contains.
Indicators matched (1)
| Field | Match | Value |
|---|---|---|
strings.contains | substring | :8443 |
Stages and Predicates
Stage 1: mql_rule
and
or
and
or
body.previous_threads length_compare "0"
subject.is_forward eq "true"
subject.is_reply eq "true"
or
headers.in_reply_to is_null
headers.references length_compare "0"
body.previous_threads length_compare "0"
any(body.links)
and
body.links.display_url.url contains ":8443"
network.whois func_call "network.whois(body.links[].href_url.domain).days_old <= 365"
not
and
headers.auth_summary.dmarc.pass eq "true"
sender.email.email eq "noreply-spamdigest@google.com"
type.inbound eq "true"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.email | eq | noreply-spamdigest@google.com | excludes:sender.email.email field:"sender.email.email" value:"noreply-spamdigest@google.com" |
Indicators
These rows show field, operator, and value matches.
Suspicious invoice reference with missing or image-only attachments
#This rule flags emails that reference invoices or payments but have suspicious characteristics: attachments are either missing or only images. It also checks for misleading links disguised as attachments and the presence of invoice-related keywords. The rule looks for potential credential theft or unusual requests, making it a strong indicator of phishing attempts.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
// more than 0 but less than 20 links
and 0 < length(body.links) < 20
// all attachments are images or there are 0 attachments
and (
length(attachments) > 0 and all(attachments, .file_type in $file_types_images)
or length(attachments) == 0
)
// subject contains payment/invoice language
and (
any(ml.nlu_classifier(subject.subject).tags, .name in ("payment", "invoice"))
or regex.contains(subject.subject,
'(?:\binv(?:oice|o)\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\brec(?:eipt|pt|iept)\b|rcpt|confirm(?:ation)|cnfrm|cnf|po\b|p\.o\.|purch(?:ase)?-?order|\bord(?:er)?\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\bstmt\b|\bstmnt\b|remit(?:tance)|rmt|remndr|remind|\bdue(?:-date)\b|ovrdue|overdue|\bbal(?:ance)\b|\bpaid(?:-invoice)\b|requires\s+your\s+a(?:ttention|ction)|\b[fF]inal\s+(?:[nN]otice|[uU]npaid).{0,20}[iI]nvoice)',
// suspicious invoice format
'\d{6}\b.{10,30}(\d{2}\.){3}pdf'
)
)
// link display text ends in a file extension or contain common payment terms
and (
any(body.links,
regex.imatch(.display_text,
'.*\.(?:doc|docm|docx|dot|dotm|pdf|ppa|ppam|ppsm|ppt|pptm|pptx|wbk|xla|xlam|xlm|xls|xlsb|xlsm|xlsx|xlt|xltm)$'
)
)
or any(body.links,
regex.icontains(.display_text,
'(?:\binv(?:oice|o)\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\brec(?:eipt|pt|iept)\b|rcpt|req(?:uest)|rqst|\brq\b|\bpo\b|p\.o\.|purch(?:ase)?-?order|\bord(?:er)?\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\bstmt\b|\bstmnt\b|remit(?:tance)|rmt|remndr|remind|\bdue(?:-date)\b|ovrdue|overdue|\bbal(?:ance)\b|\bpaid(?:-invoice)\b|completed\s+doc(?:s|ument|uments)?\b)'
)
)
or (
any(body.links,
regex.icontains(.display_text, '\bview\s+(invoice|attachment)')
)
and any([body.plain.raw, body.html.inner_text],
any(ml.nlu_classifier(.).intents,
.name == "cred_theft" and .confidence == "high"
)
)
)
)
// the body references an attachment
and (
strings.contains(body.current_thread.text, "attach")
// negate warning banners warning about the attachment(s)
and (
not (
(
regex.count(body.current_thread.text, "attach") == 1
and regex.icontains(body.current_thread.text,
"(caution|warning).{0,30}attach"
)
)
or ( // WeTransfer expiry warning notification
sender.email.email == "noreply@wetransfer.com"
and any(body.links,
.display_text == "Don't send me these expiry reminders anymore"
)
)
)
)
)
// body text is determined to contain cred_theft language by nlu or contains a request with suspicious keywords
and (
not (
any(ml.nlu_classifier(body.current_thread.text).topics,
.name in ("Shipping and Package", "Order Confirmations")
and .confidence == "high"
)
)
and (
any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "cred_theft"
)
or any(ml.nlu_classifier(body.current_thread.text).entities,
.name == "request" and (strings.icontains(.text, "kindly"))
)
)
)
// 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
)
and not profile.by_sender().solicited
Detection logic
Scope: inbound message.
This rule flags emails that reference invoices or payments but have suspicious characteristics: attachments are either missing or only images. It also checks for misleading links disguised as attachments and the presence of invoice-related keywords. The rule looks for potential credential theft or unusual requests, making it a strong indicator of phishing attempts.
- inbound message
all of:
- length(body.links) > 0
- length(body.links) < 20
any of:
all of:
- length(attachments) > 0
all of
attachmentswhere:- .file_type in $file_types_images
- length(attachments) is 0
any of:
any of
ml.nlu_classifier(subject.subject).tagswhere:- .name in ('payment', 'invoice')
subject.subject matches any of 2 patterns
(?:\binv(?:oice|o)\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\brec(?:eipt|pt|iept)\b|rcpt|confirm(?:ation)|cnfrm|cnf|po\b|p\.o\.|purch(?:ase)?-?order|\bord(?:er)?\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\bstmt\b|\bstmnt\b|remit(?:tance)|rmt|remndr|remind|\bdue(?:-date)\b|ovrdue|overdue|\bbal(?:ance)\b|\bpaid(?:-invoice)\b|requires\s+your\s+a(?:ttention|ction)|\b[fF]inal\s+(?:[nN]otice|[uU]npaid).{0,20}[iI]nvoice)\d{6}\b.{10,30}(\d{2}\.){3}pdf
any of:
any of
body.linkswhere:- .display_text matches '.*\\.(?:doc|docm|docx|dot|dotm|pdf|ppa|ppam|ppsm|ppt|pptm|pptx|wbk|xla|xlam|xlm|xls|xlsb|xlsm|xlsx|xlt|xltm)$'
any of
body.linkswhere:- .display_text matches '(?:\\binv(?:oice|o)\\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\\brec(?:eipt|pt|iept)\\b|rcpt|req(?:uest)|rqst|\\brq\\b|\\bpo\\b|p\\.o\\.|purch(?:ase)?-?order|\\bord(?:er)?\\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\\bstmt\\b|\\bstmnt\\b|remit(?:tance)|rmt|remndr|remind|\\bdue(?:-date)\\b|ovrdue|overdue|\\bbal(?:ance)\\b|\\bpaid(?:-invoice)\\b|completed\\s+doc(?:s|ument|uments)?\\b)'
all of:
any of
body.linkswhere:- .display_text matches '\\bview\\s+(invoice|attachment)'
any of
[body.plain.raw, body.html.inner_text]where:any of
ml.nlu_classifier(.).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
all of:
- body.current_thread.text contains 'attach'
none of:
all of:
- regex.count(body.current_thread.text, 'attach') is 1
- body.current_thread.text matches '(caution|warning).{0,30}attach'
all of:
- sender.email.email is 'noreply@wetransfer.com'
any of
body.linkswhere:- .display_text is "Don't send me these expiry reminders anymore"
all of:
not:
any of
ml.nlu_classifier(body.current_thread.text).topicswhere all hold:- .name in ('Shipping and Package', 'Order Confirmations')
- .confidence is 'high'
any of:
any of
ml.nlu_classifier(body.current_thread.text).intentswhere:- .name is 'cred_theft'
any of
ml.nlu_classifier(body.current_thread.text).entitieswhere all hold:- .name is 'request'
- .text contains 'kindly'
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
not:
- profile.by_sender().solicited
Inspects: attachments[].file_type, body.current_thread.text, body.html.inner_text, body.links, body.links[].display_text, body.plain.raw, headers.auth_summary.dmarc.pass, sender.email.domain.root_domain, sender.email.email, subject.subject, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, regex.contains, regex.count, regex.icontains, regex.imatch, strings.contains, strings.icontains. Reference lists: $file_types_images, $high_trust_sender_root_domains.
Indicators matched (13)
| Field | Match | Value |
|---|---|---|
ml.nlu_classifier(subject.subject).tags[].name | member | payment |
ml.nlu_classifier(subject.subject).tags[].name | member | invoice |
regex.contains | regex | (?:\binv(?:oice|o)\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\brec(?:eipt|pt|iept)\b|rcpt|confirm(?:ation)|cnfrm|cnf|po\b|p\.o\.|purch(?:ase)?-?order|\bord(?:er)?\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\bstmt\b|\bstmnt\b|remit(?:tance)|rmt|remndr|remind|\bdue(?:-date)\b|ovrdue|overdue|\bbal(?:ance)\b|\bpaid(?:-invoice)\b|requires\s+your\s+a(?:ttention|ction)|\b[fF]inal\s+(?:[nN]otice|[uU]npaid).{0,20}[iI]nvoice) |
regex.contains | regex | \d{6}\b.{10,30}(\d{2}\.){3}pdf |
regex.imatch | regex | .*\.(?:doc|docm|docx|dot|dotm|pdf|ppa|ppam|ppsm|ppt|pptm|pptx|wbk|xla|xlam|xlm|xls|xlsb|xlsm|xlsx|xlt|xltm)$ |
regex.icontains | regex | (?:\binv(?:oice|o)\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\brec(?:eipt|pt|iept)\b|rcpt|req(?:uest)|rqst|\brq\b|\bpo\b|p\.o\.|purch(?:ase)?-?order|\bord(?:er)?\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\bstmt\b|\bstmnt\b|remit(?:tance)|rmt|remndr|remind|\bdue(?:-date)\b|ovrdue|overdue|\bbal(?:ance)\b|\bpaid(?:-invoice)\b|completed\s+doc(?:s|ument|uments)?\b) |
regex.icontains | regex | \bview\s+(invoice|attachment) |
ml.nlu_classifier([body.plain.raw, body.html.inner_text][]).intents[].name | equals | cred_theft |
ml.nlu_classifier([body.plain.raw, body.html.inner_text][]).intents[].confidence | equals | high |
strings.contains | substring | attach |
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | cred_theft |
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | request |
1 more
strings.icontains | substring | kindly |
Stages and Predicates
Stage 1: mql_rule
and
or
and
any([body.plain.raw, body.html.inner_text])
any(ml.nlu_classifier([body.plain.raw, body.html.inner_text]).intents)
and
ml.nlu_classifier([body.plain.raw, body.html.inner_text][]).intents[].confidence eq "high"
ml.nlu_classifier([body.plain.raw, body.html.inner_text][]).intents[].name eq "cred_theft"
any(body.links)
body.links.display_text regex_match "\\bview\\s+(invoice|attachment)"
any(body.links)
body.links.display_text regex_match "(?:\\binv(?:oice|o)\\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\\brec(?:eipt|pt|iept)\\b|rcpt|req(?:uest)|rqst|\\brq\\b|\\bpo\\b|p\\.o\\.|purch(?:ase)?-?order|\\bord(?:er)?\\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\\bstmt\\b|\\bstmnt\\b|remit(?:tance)|rmt|remndr|remind|\\bdue(?:-date)\\b|ovrdue|overdue|\\bbal(?:ance)\\b|\\bpaid(?:-invoice)\\b|completed\\s+doc(?:s|ument|uments)?\\b)"
any(body.links)
body.links.display_text regex_match ".*\\.(?:doc|docm|docx|dot|dotm|pdf|ppa|ppam|ppsm|ppt|pptm|pptx|wbk|xla|xlam|xlm|xls|xlsb|xlsm|xlsx|xlt|xltm)$"
not
or
and
any(body.links)
body.links.display_text eq "Don't send me these expiry reminders anymore"
sender.email.email eq "noreply@wetransfer.com"
and
body.current_thread.text regex_match "(caution|warning).{0,30}attach"
regex.count func_call "regex.count(body.current_thread.text, \"attach\") == 1"
or
and
not
headers.auth_summary.dmarc.pass eq "true"
macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
or
any(ml.nlu_classifier(body.current_thread.text).entities)
and
ml.nlu_classifier(body.current_thread.text).entities.name eq "request"
ml.nlu_classifier(body.current_thread.text).entities.text contains "kindly"
any(ml.nlu_classifier(body.current_thread.text).intents)
ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
not
any(ml.nlu_classifier(body.current_thread.text).topics)
and
ml.nlu_classifier(body.current_thread.text).topics.confidence eq "high"
ml.nlu_classifier(body.current_thread.text).topics.name in ["Order Confirmations", "Shipping and Package"]
or
and
attachments length_compare "0"
macro "all(attachments)"
attachments length_compare "0"
or
any(ml.nlu_classifier(subject.subject).tags)
ml.nlu_classifier(subject.subject).tags.name in ["invoice", "payment"]
subject.subject regex_match "(?:\\binv(?:oice|o)\\b|in_v|in-voice|pay(?:ment|mnt)|pymt|\\brec(?:eipt|pt|iept)\\b|rcpt|confirm(?:ation)|cnfrm|cnf|po\\b|p\\.o\\.|purch(?:ase)?-?order|\\bord(?:er)?\\b|bill(?:ing)|billing-info|transact(?:ion)|txn|trx|\\bstmt\\b|\\bstmnt\\b|remit(?:tance)|rmt|remndr|remind|\\bdue(?:-date)\\b|ovrdue|overdue|\\bbal(?:ance)\\b|\\bpaid(?:-invoice)\\b|requires\\s+your\\s+a(?:ttention|ction)|\\b[fF]inal\\s+(?:[nN]otice|[uU]npaid).{0,20}[iI]nvoice)"
subject.subject regex_match "\\d{6}\\b.{10,30}(\\d{2}\\.){3}pdf"
not
profile.by_sender func_call "profile.by_sender().solicited"
body.current_thread.text contains "attach"
body.links length_compare "0"
body.links length_compare "20"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
body.links | array_any | excludes:body.links | |
sender.email.email | eq | noreply@wetransfer.com | excludes:sender.email.email field:"sender.email.email" value:"noreply@wetransfer.com" |
body.current_thread.text | regex_match | (caution|warning).{0,30}attach | excludes:body.current_thread.text field:"body.current_thread.text" value:"(caution|warning).{0,30}attach" |
ml.nlu_classifier(body.current_thread.text).topics | array_any | excludes:ml.nlu_classifier(body.current_thread.text).topics |
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 value:"attach" |
subject.subject | regex_match |
| field:"subject.subject" kind:regex_match |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |