Detection rules › Sublime MQL
Sublime MQL rules: deceptive
| Rule | Severity |
|---|---|
| Deceptive Dropbox mention | medium |
| Self-sent fake PDF attachment with misleading link | low |
Deceptive Dropbox mention
#Detects when a message mentions Dropbox but comes from non-Dropbox infrastructure, contains links to suspicious domains, shows discrepancies in sender identity, and contains language patterns associated with credential theft.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, Free file host, Free subdomain host, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and strings.icontains(body.current_thread.text, 'dropbox')
and any(beta.ml_topic(coalesce(body.html.display_text, body.current_thread.text)
).topics,
.name == "File Sharing and Cloud Services" and .confidence != "low"
)
and (
// Email address discrepancy detection - looking for matches in the domain name from the sender but not the current thread proposed sender name
any(regex.iextract(body.current_thread.text,
'(?P<whole_email>(?P<local_part>[a-zA-Z0-9._%-]+)@(?P<domain_name>[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}))'
),
strings.parse_email(.named_groups["whole_email"]).domain.domain == sender.email.domain.domain
and strings.parse_email(.named_groups["whole_email"]).local_part != sender.email.local_part
and not strings.parse_email(.named_groups["whole_email"]).email in~ map(filter(recipients.to,
.email.domain.valid
),
.email.email
)
)
// self sender
or (
length(recipients.to) == 1
and sender.email.email == recipients.to[0].email.email
)
)
// Not from legitimate Dropbox infrastructure
and sender.email.domain.root_domain not in~ (
'dropbox.com',
'docsend.com',
'box.com',
'wetransfer.com',
// tuning: exlude hellosign emails that are covered in another rule
'hellosign.com'
)
// Contains suspicious links to non-Dropbox/file-sharing domains
and any(body.links,
(
.href_url.domain.root_domain in~ $free_subdomain_hosts
or .href_url.domain.root_domain in~ $free_file_hosts
)
and .href_url.domain.valid
)
// ML indicates potential credential theft
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "cred_theft" and .confidence != "low"
)
Detection logic
Scope: inbound message.
Detects when a message mentions Dropbox but comes from non-Dropbox infrastructure, contains links to suspicious domains, shows discrepancies in sender identity, and contains language patterns associated with credential theft.
- inbound message
- body.current_thread.text contains 'dropbox'
any of
beta.ml_topic(coalesce(body.html.display_text, body.current_thread.text)).topicswhere all hold:- .name is 'File Sharing and Cloud Services'
- .confidence is not 'low'
any of:
any of
regex.iextract(body.current_thread.text)where all hold:- strings.parse_email(.named_groups['whole_email']).domain.domain is sender.email.domain.domain
- strings.parse_email(.named_groups['whole_email']).local_part is not sender.email.local_part
not:
- strings.parse_email(.named_groups['whole_email']).email in map(filter(recipients.to, .email.domain.valid), .email.email)
all of:
- length(recipients.to) is 1
- sender.email.email is recipients.to[0].email.email
- sender.email.domain.root_domain not in ('dropbox.com', 'docsend.com', 'box.com', 'wetransfer.com', 'hellosign.com')
any of
body.linkswhere all hold:any of:
- .href_url.domain.root_domain in $free_subdomain_hosts
- .href_url.domain.root_domain in $free_file_hosts
- .href_url.domain.valid
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence is not 'low'
Inspects: body.current_thread.text, body.html.display_text, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.domain.valid, recipients.to, recipients.to[0].email.email, recipients.to[].email.domain.valid, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.email, sender.email.local_part, type.inbound. Sensors: beta.ml_topic, ml.nlu_classifier, regex.iextract, strings.icontains, strings.parse_email. Reference lists: $free_file_hosts, $free_subdomain_hosts.
Indicators matched (4)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | dropbox |
beta.ml_topic(coalesce(body.html.display_text, body.current_thread.text)).topics[].name | equals | File Sharing and Cloud Services |
regex.iextract | regex | (?P<whole_email>(?P<local_part>[a-zA-Z0-9._%-]+)@(?P<domain_name>[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})) |
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | cred_theft |
Stages and Predicates
Stage 1: mql_rule
and
or
any(regex.iextract(body.current_thread.text))
and
not
strings.parse_email func_call "strings.parse_email(regex.iextract(body.current_thread.text)[].named_groups['whole_email']).email in~ map(filter(recipients.to, regex.iextract(body.current_thread.text)[].email.domain.valid), regex.iextract(body.current_thread.text)[].email.email)"
strings.parse_email func_call "strings.parse_email(regex.iextract(body.current_thread.text)[].named_groups['whole_email']).domain.domain == sender.email.domain.domain"
strings.parse_email func_call "strings.parse_email(regex.iextract(body.current_thread.text)[].named_groups['whole_email']).local_part != sender.email.local_part"
and
recipients.to length_compare "1"
sender.email.email cross_field_compare "recipients.to[0].email.email"
any(body.links)
and
or
macro "body.links[].href_url.domain.root_domain in free_file_hosts"
macro "body.links[].href_url.domain.root_domain in free_subdomain_hosts"
body.links.href_url.domain.valid eq "true"
any(beta.ml_topic(coalesce(body.html.display_text, body.current_thread.text)).topics)
and
beta.ml_topic(coalesce(body.html.display_text, body.current_thread.text)).topics.confidence ne "low"
beta.ml_topic(coalesce(body.html.display_text, body.current_thread.text)).topics.name eq "File Sharing and Cloud Services"
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
sender.email.domain.root_domain in ["box.com", "docsend.com", "dropbox.com", "hellosign.com", "wetransfer.com"]
body.current_thread.text contains "dropbox"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
sender.email.domain.root_domain | in | box.com, docsend.com, dropbox.com, hellosign.com, wetransfer.com | excludes:sender.email.domain.root_domain |
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:"dropbox" |
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-sent fake PDF attachment with misleading link
#Detects messages sent from a user to themselves containing a fake PDF icon from Google's CDN, claiming to have an attachment while only containing images, and including links that appear to be PDF files.
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
// pdf image
and strings.contains(body.html.raw,
'https://ci3.googleusercontent.com/meips/ADKq_Naq6rm1GwC4XYZepCUQtEMnJ-r-HjyX_C5lBU7lpxQk1OIDV7vvQYvSJQWYmQCzG8moTgX3Wak625OtyHWRinVeUJs7K710JiIZ4JNXVpTmC8PJjV4K34GsBA=s0-d-e1-ft#https://res-1.cdn.office.net/assets/mail/file-icon/png/pdf_16x16.png'
)
// mentions attachments but there are none or just images with no pdfs
and strings.starts_with(body.current_thread.text, 'Please see attached.')
and all(attachments, .file_type in $file_types_images)
// self sender
and (
length(recipients.to) == 1
and sender.email.email == recipients.to[0].email.email
)
// display text ends with .pdf
and any(body.current_thread.links,
strings.ends_with(.display_text, '.pdf')
and .href_url.domain.subdomain is not null
and .visible
and not (
.href_url.domain.root_domain == "googleusercontent.com"
and strings.istarts_with(.href_url.path, "/mail-sig")
)
)
Detection logic
Scope: inbound message.
Detects messages sent from a user to themselves containing a fake PDF icon from Google's CDN, claiming to have an attachment while only containing images, and including links that appear to be PDF files.
- inbound message
- body.html.raw contains 'https://ci3.googleusercontent.com/meips/ADKq_Naq6rm1GwC4XYZepCUQtEMnJ-r-HjyX_C5lBU7lpxQk1OIDV7vvQYvSJQWYmQCzG8moTgX3Wak625OtyHWRinVeUJs7K710JiIZ4JNXVpTmC8PJjV4K34GsBA=s0-d-e1-ft#https://res-1.cdn.office.net/assets/mail/file-icon/png/pdf_16x16.png'
- body.current_thread.text starts with 'Please see attached.'
all of
attachmentswhere:- .file_type in $file_types_images
all of:
- length(recipients.to) is 1
- sender.email.email is recipients.to[0].email.email
any of
body.current_thread.linkswhere all hold:- .display_text ends with '.pdf'
- .href_url.domain.subdomain is set
- .visible
not:
all of:
- .href_url.domain.root_domain is 'googleusercontent.com'
- .href_url.path starts with '/mail-sig'
Inspects: attachments[].file_type, body.current_thread.links, body.current_thread.links[].display_text, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.domain.subdomain, body.current_thread.links[].href_url.path, body.current_thread.links[].visible, body.current_thread.text, body.html.raw, recipients.to, recipients.to[0].email.email, sender.email.email, type.inbound. Sensors: strings.contains, strings.ends_with, strings.istarts_with, strings.starts_with. Reference lists: $file_types_images.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
strings.contains | substring | https://ci3.googleusercontent.com/meips/ADKq_Naq6rm1GwC4XYZepCUQtEMnJ-r-HjyX_C5lBU7lpxQk1OIDV7vvQYvSJQWYmQCzG8moTgX3Wak625OtyHWRinVeUJs7K710JiIZ4JNXVpTmC8PJjV4K34GsBA=s0-d-e1-ft#https://res-1.cdn.office.net/assets/mail/file-icon/png/pdf_16x16.png |
strings.starts_with | prefix | Please see attached. |
strings.ends_with | suffix | .pdf |
Stages and Predicates
Stage 1: mql_rule
and
any(body.current_thread.links)
and
not
and
body.current_thread.links.href_url.domain.root_domain eq "googleusercontent.com"
body.current_thread.links.href_url.path starts_with "/mail-sig"
body.current_thread.links.display_text ends_with ".pdf"
body.current_thread.links.href_url.domain.subdomain is_not_null
body.current_thread.links.visible eq "true"
body.current_thread.text starts_with "Please see attached."
body.html.raw contains "https://ci3.googleusercontent.com/meips/ADKq_Naq6rm1GwC4XYZepCUQtEMnJ-r-HjyX_C5lBU7lpxQk1OIDV7vvQYvSJQWYmQCzG8moTgX3Wak625OtyHWRinVeUJs7K710JiIZ4JNXVpTmC8PJjV4K34GsBA=s0-d-e1-ft#https://res-1.cdn.office.net/assets/mail/file-icon/png/pdf_16x16.png"
recipients.to length_compare "1"
sender.email.email cross_field_compare "recipients.to[0].email.email"
type.inbound eq "true"
macro "all(attachments)"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | starts_with |
| field:"body.current_thread.text" kind:starts_with value:"Please see attached." |
body.html.raw | contains |
| field:"body.html.raw" kind:contains value:"https://ci3.googleusercontent.com/meips/ADKq_Naq6rm1GwC4XYZepCUQtEMnJ-r-HjyX_C5lBU7lpxQk1OIDV7vvQYvSJQWYmQCzG8moTgX3Wak625OtyHWRinVeUJs7K710JiIZ4JNXVpTmC8PJjV4K34GsBA=s0-d-e1-ft#https://res-1.cdn.office.net/assets/mail/file-icon/png/pdf_16x16.png" |
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" |