Detection rules › Sublime MQL
Sublime MQL rules: mass
| Rule | Severity |
|---|---|
| Mass campaign: Cross Site Scripting (XSS) attempt | medium |
| Mass campaign: recipient address in subject, body, and link (untrusted sender) | medium |
Mass campaign: Cross Site Scripting (XSS) attempt
#Message subject or body contains Cross Site Scripting (XSS) indicators, and was sent to multiple unknown senders. Known spam technique.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Malware/Ransomware, Spam |
| Tactics and techniques | Exploit, Free email provider, Scripting, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
Rule body
type.inbound
and (
length(recipients.to) > 10
and length(filter(recipients.to,
.email.domain.domain not in $org_domains
and .email.email not in $recipient_emails
and (
.email.domain.valid
or strings.icontains(.display_name, "undisclosed")
)
)
) >= 10
)
and (
strings.ilike(subject.subject,
'*<*script*>*',
'*xss.report*',
'*eval(atob*',
'*<*onload*>*',
'*<*onerror*>*'
)
or strings.ilike(body.current_thread.text,
'*<*script*>*',
'*xss.report*',
'*eval(atob*',
'*<*onload*>*',
'*<*onerror*>*'
)
)
and (
length(body.links) == 0
or (
length(body.links) == 1
and all(body.links, .href_url.domain.domain == "this.id")
)
)
and profile.by_sender().prevalence != "common"
and not profile.by_sender().solicited
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 (
any(distinct(headers.hops, .authentication_results.dmarc is not null),
strings.ilike(.authentication_results.dmarc, "*fail")
)
)
)
or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
Detection logic
Scope: inbound message.
Message subject or body contains Cross Site Scripting (XSS) indicators, and was sent to multiple unknown senders. Known spam technique.
- inbound message
all of:
- length(recipients.to) > 10
- length(filter(recipients.to, .email.domain.domain not in $org_domains and .email.email not in $recipient_emails and .email.domain.valid or strings.icontains(.display_name, 'undisclosed'))) ≥ 10
any of:
subject.subject matches any of 5 patterns
*<*script*>**xss.report**eval(atob**<*onload*>**<*onerror*>*
body.current_thread.text matches any of 5 patterns
*<*script*>**xss.report**eval(atob**<*onload*>**<*onerror*>*
any of:
- length(body.links) is 0
all of:
- length(body.links) is 1
all of
body.linkswhere:- .href_url.domain.domain is 'this.id'
- profile.by_sender().prevalence is not 'common'
not:
- profile.by_sender().solicited
not:
- profile.by_sender().any_messages_benign
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
any of
distinct(headers.hops)where:- .authentication_results.dmarc matches '*fail'
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: body.current_thread.text, body.links, body.links[].href_url.domain.domain, headers.hops, headers.hops[].authentication_results.dmarc, recipients.to, recipients.to[].display_name, recipients.to[].email.domain.domain, recipients.to[].email.domain.valid, recipients.to[].email.email, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: profile.by_sender, strings.icontains, strings.ilike. Reference lists: $high_trust_sender_root_domains, $org_domains, $recipient_emails.
Indicators matched (8)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | undisclosed |
strings.ilike | substring | *<*script*>* |
strings.ilike | substring | *xss.report* |
strings.ilike | substring | *eval(atob* |
strings.ilike | substring | *<*onload*>* |
strings.ilike | substring | *<*onerror*>* |
body.links[].href_url.domain.domain | equals | this.id |
strings.ilike | substring | *fail |
Stages and Predicates
Stage 1: mql_rule
and
or
and
any(distinct(headers.hops))
distinct(headers.hops).authentication_results.dmarc ends_with "fail"
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
and
body.links length_compare "1"
macro "all(body.links)"
body.links length_compare "0"
or
body.current_thread.text match "eval(atob"
body.current_thread.text match "xss.report"
body.current_thread.text wildcard "*<*onerror*>*"
body.current_thread.text wildcard "*<*onload*>*"
body.current_thread.text wildcard "*<*script*>*"
subject.subject match "eval(atob"
subject.subject match "xss.report"
subject.subject wildcard "*<*onerror*>*"
subject.subject wildcard "*<*onload*>*"
subject.subject wildcard "*<*script*>*"
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
not
profile.by_sender func_call "profile.by_sender().solicited"
filter(recipients.to, .email.domain.domain not in $org_domains and .email.email not in $recipient_emails and .email.domain.valid or strings.icontains(.display_name, 'undisclosed')) length_compare "10"
profile.by_sender func_call "profile.by_sender().prevalence != common"
recipients.to length_compare "10"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | wildcard |
| field:"body.current_thread.text" kind:wildcard |
subject.subject | wildcard |
| field:"subject.subject" kind:wildcard |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Mass campaign: recipient address in subject, body, and link (untrusted sender)
#This detects a pattern commonly observed in mass phishing campaigns. The local_part or the full email address of the recipient is used in the subject, body, and link query parameter to "personalize" the attack.
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
and length(recipients.to) + length(recipients.bcc) + length(recipients.cc) == 1
// exclude To: Undisclosed recipients:;
// since we won't have a valid recipient email
and any(recipients.to, .email.domain.valid == true)
and (
profile.by_sender().prevalence in ("new", "outlier")
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
)
and (
any(recipients.to,
(
strings.icontains(subject.subject, .email.email)
or strings.icontains(subject.subject, .email.local_part)
)
and (
.email.domain.valid or strings.icontains(.display_name, "undisclosed")
)
)
)
and any(recipients.to,
strings.icontains(body.current_thread.text, .email.email)
)
and any(body.links,
any(recipients.to,
strings.icontains(..href_url.query_params, .email.email)
)
and (
(
not strings.icontains(.display_text, "unsubscribe")
and not strings.icontains(.href_url.path, "unsubscribe")
)
)
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name in ("cred_theft") and .confidence == "high"
)
// 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.
This detects a pattern commonly observed in mass phishing campaigns. The local_part or the full email address of the recipient is used in the subject, body, and link query parameter to "personalize" the attack.
- inbound message
- length(recipients.to) + length(recipients.bcc) + length(recipients.cc) is 1
any of
recipients.towhere:- .email.domain.valid is True
any of:
- profile.by_sender().prevalence in ('new', 'outlier')
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
any of
recipients.towhere all hold:any of:
- strings.icontains(subject.subject)
- strings.icontains(subject.subject)
any of:
- .email.domain.valid
- .display_name contains 'undisclosed'
any of
recipients.towhere:- strings.icontains(body.current_thread.text)
any of
body.linkswhere all hold:any of
recipients.towhere:- strings.icontains(.href_url.query_params)
all of:
not:
- .display_text contains 'unsubscribe'
not:
- .href_url.path contains 'unsubscribe'
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name in ('cred_theft')
- .confidence is 'high'
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, body.links[].display_text, body.links[].href_url.path, body.links[].href_url.query_params, headers.auth_summary.dmarc.pass, recipients.to, recipients.to[].display_name, recipients.to[].email.domain.valid, recipients.to[].email.email, recipients.to[].email.local_part, sender.email.domain.root_domain, subject.subject, type.inbound. Sensors: ml.nlu_classifier, profile.by_sender, strings.icontains. Reference lists: $high_trust_sender_root_domains.
Indicators matched (3)
| Field | Match | Value |
|---|---|---|
strings.icontains | substring | undisclosed |
ml.nlu_classifier(body.current_thread.text).intents[].name | member | cred_theft |
ml.nlu_classifier(body.current_thread.text).intents[].confidence | equals | high |
Stages and Predicates
Stage 1: mql_rule
and
any(body.links)
and
not
body.links.display_text contains "unsubscribe"
not
body.links.href_url.path contains "unsubscribe"
any(recipients.to)
strings.icontains func_call "strings.icontains(body.links[].href_url.query_params)"
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
and
not
profile.by_sender func_call "profile.by_sender().any_messages_benign"
profile.by_sender func_call "profile.by_sender().any_messages_malicious_or_spam"
profile.by_sender func_call "profile.by_sender().prevalence in (new, outlier)"
any(recipients.to)
and
or
recipients.to.display_name contains "undisclosed"
recipients.to.email.domain.valid eq "true"
strings.icontains func_call "strings.icontains(subject.subject)"
any(ml.nlu_classifier(body.current_thread.text).intents)
and
ml.nlu_classifier(body.current_thread.text).intents.confidence eq "high"
ml.nlu_classifier(body.current_thread.text).intents.name eq "cred_theft"
any(recipients.to)
recipients.to.email.domain.valid eq "true"
any(recipients.to)
strings.icontains func_call "strings.icontains(body.current_thread.text)"
type.inbound eq "true"
macro "((length(recipients.to) + length(recipients.bcc)) + length(recipients.cc)) == 1"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |