Detection rules › Sublime MQL
Impersonation: Human Resources with link or attachment and engaging language
Detects messages impersonating HR that contain at least 1 link or 1 attachment with engaging language in the body from an untrusted sender.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing |
| Tactics and techniques | Impersonation: Employee, Social engineering |
Event coverage
Rule body MQL
type.inbound
and sender.email.domain.domain not in $org_domains
and (
regex.icontains(sender.display_name,
'(\bh\W?r\W?\b|human\s?resources|hr depart(ment)?|employee relations)'
)
or (
length(filter(ml.nlu_classifier(body.current_thread.text).entities,
.name == "sender"
)
) == 1
and any(ml.nlu_classifier(body.current_thread.text).entities,
.name == "sender"
and regex.icontains(.text,
'(\bh\W?r\W?\b|human\s?resources|hr depart(ment)?|employee relations)'
)
)
)
)
and not (
strings.icontains(sender.display_name, sender.email.domain.domain)
and sender.email.domain.tld == "hr"
)
// negate replies
and (length(headers.references) == 0 or headers.in_reply_to is null)
// Negate common marketing mailers
and not (
sender.display_name is not null
and regex.icontains(sender.display_name,
'HR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests)|HR and People Operations'
)
)
and not (
any(headers.hops,
strings.icontains(.authentication_results.spf_details.designator,
"constantcontact.com"
)
)
or any(headers.hops,
strings.icontains(.received_spf.designator, "constantcontact.com")
)
or (
(
any(headers.hops,
.index == 0
and any(.authentication_results.dkim_details,
.domain == "auth.ccsend.com"
)
)
)
and headers.auth_summary.dmarc.pass
)
or any(headers.references, strings.iends_with(., "ccsend.com"))
)
and (
(0 < length(body.links) < 10 or length(attachments) > 0)
// mass-mailer infra abuse results in an inflated link count due to mailer templates that include links for unsubbing, changing preferences, etc.
// loosening the link count check as a result ensures we fire even with these conditions
or (
any(body.links,
strings.ilike(.display_text,
"*unsubscribe*",
"update your preferences",
"add us to your address book"
)
)
and 0 < length(body.links) < 15
)
)
// Request and Urgency
and (
(
length(body.current_thread.text) > 100
and any(ml.nlu_classifier(body.current_thread.text).entities,
.name == "request"
)
and (
any(ml.nlu_classifier(body.current_thread.text).entities,
.name in ("urgency", "financial")
)
or (
any(beta.ml_topic(body.current_thread.text).topics,
.name == "Professional and Career Development"
and .confidence == "high"
)
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name != "benign"
)
)
)
)
or (
length(body.current_thread.text) < 400
and any(attachments,
(.file_type in $file_types_images or .file_type == "pdf")
and any(file.explode(.),
.scan.qr.type == "url"
and .scan.qr.url.domain.root_domain not in $org_domains
)
)
)
)
// additional suspicious indicator
and (
any(ml.nlu_classifier(body.current_thread.text).intents, .name != "benign")
or length(ml.nlu_classifier(body.current_thread.text).intents) == 0 // not benign but not malicious either
// 1-2 all caps body links
or 0 < length(filter(body.links,
not (
strings.ilike(.display_text,
"*unsubscribe*",
"update your preferences",
"add us to your address book"
)
or .href_url.domain.root_domain == 'aka.ms'
)
and regex.match(.display_text, '[A-Z ]+')
),
) < 3
or any(attachments,
(.file_type in $file_types_images or .file_type == "pdf")
and any(file.explode(.),
any(ml.nlu_classifier(.scan.ocr.raw).intents,
.name == "cred_theft" and .confidence == "high"
)
)
)
)
// topic negation
and not any(beta.ml_topic(body.current_thread.text).topics,
.name in (
"Newsletters and Digests",
"Advertising and Promotions",
"Educational and Research",
)
and .confidence == "high"
)
and (
profile.by_sender_email().prevalence in ("new", "outlier")
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
or sender.email.email in (
"adobesign@adobesign.com",
"noreply@salesforce.com",
"support@salesforce.com",
"no-reply@salesforce.com"
) // abused services
)
// 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 (
headers.auth_summary.dmarc.pass is null
and not headers.auth_summary.spf.pass
)
)
)
or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
Detection logic
Scope: inbound message.
Detects messages impersonating HR that contain at least 1 link or 1 attachment with engaging language in the body from an untrusted sender.
- inbound message
- sender.email.domain.domain not in $org_domains
any of:
- sender.display_name matches '(\\bh\\W?r\\W?\\b|human\\s?resources|hr depart(ment)?|employee relations)'
all of:
- length(filter(ml.nlu_classifier(body.current_thread.text).entities, .name == 'sender')) is 1
any of
ml.nlu_classifier(body.current_thread.text).entitieswhere all hold:- .name is 'sender'
- .text matches '(\\bh\\W?r\\W?\\b|human\\s?resources|hr depart(ment)?|employee relations)'
not:
all of:
- strings.icontains(sender.display_name)
- sender.email.domain.tld is 'hr'
any of:
- length(headers.references) is 0
- headers.in_reply_to is missing
not:
all of:
- sender.display_name is set
- sender.display_name matches 'HR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests)|HR and People Operations'
none of:
any of
headers.hopswhere:- .authentication_results.spf_details.designator contains 'constantcontact.com'
any of
headers.hopswhere:- .received_spf.designator contains 'constantcontact.com'
all of:
any of
headers.hopswhere all hold:- .index is 0
any of
.authentication_results.dkim_detailswhere:- .domain is 'auth.ccsend.com'
- headers.auth_summary.dmarc.pass
any of
headers.referenceswhere:- . ends with 'ccsend.com'
any of:
any of:
all of:
- length(body.links) > 0
- length(body.links) < 10
- length(attachments) > 0
all of:
any of
body.linkswhere:.display_text matches any of 3 patterns
*unsubscribe*update your preferencesadd us to your address book
all of:
- length(body.links) > 0
- length(body.links) < 15
any of:
all of:
- length(body.current_thread.text) > 100
any of
ml.nlu_classifier(body.current_thread.text).entitieswhere:- .name is 'request'
any of:
any of
ml.nlu_classifier(body.current_thread.text).entitieswhere:- .name in ('urgency', 'financial')
all of:
any of
beta.ml_topic(body.current_thread.text).topicswhere all hold:- .name is 'Professional and Career Development'
- .confidence is 'high'
any of
ml.nlu_classifier(body.current_thread.text).intentswhere:- .name is not 'benign'
all of:
- length(body.current_thread.text) < 400
any of
attachmentswhere all hold:any of:
- .file_type in $file_types_images
- .file_type is 'pdf'
any of
file.explode(.)where all hold:- .scan.qr.type is 'url'
- .scan.qr.url.domain.root_domain not in $org_domains
any of:
any of
ml.nlu_classifier(body.current_thread.text).intentswhere:- .name is not 'benign'
- length(ml.nlu_classifier(body.current_thread.text).intents) is 0
all of:
- length(filter(body.links, not strings.ilike(.display_text, '*unsubscribe*', 'update your preferences', 'add us to your address book') or .href_url.domain.root_domain == 'aka.ms' and regex.match(.display_text, '[A-Z ]+'))) > 0
- length(filter(body.links, not strings.ilike(.display_text, '*unsubscribe*', 'update your preferences', 'add us to your address book') or .href_url.domain.root_domain == 'aka.ms' and regex.match(.display_text, '[A-Z ]+'))) < 3
any of
attachmentswhere all hold:any of:
- .file_type in $file_types_images
- .file_type is 'pdf'
any of
file.explode(.)where:any of
ml.nlu_classifier(.scan.ocr.raw).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
not:
any of
beta.ml_topic(body.current_thread.text).topicswhere all hold:- .name in ('Newsletters and Digests', 'Advertising and Promotions', 'Educational and Research')
- .confidence is 'high'
any of:
- profile.by_sender_email().prevalence in ('new', 'outlier')
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
- sender.email.email in ('adobesign@adobesign.com', 'noreply@salesforce.com', 'support@salesforce.com', 'no-reply@salesforce.com')
any of:
all of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
any of:
not:
- headers.auth_summary.dmarc.pass
all of:
- headers.auth_summary.dmarc.pass is missing
not:
- headers.auth_summary.spf.pass
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
Inspects: attachments[].file_type, body.current_thread.text, body.links, body.links[].display_text, body.links[].href_url.domain.root_domain, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.hops, headers.hops[].authentication_results.dkim_details, headers.hops[].authentication_results.dkim_details[].domain, headers.hops[].authentication_results.spf_details.designator, headers.hops[].index, headers.hops[].received_spf.designator, headers.in_reply_to, headers.references, sender.display_name, sender.email.domain.domain, sender.email.domain.root_domain, sender.email.domain.tld, sender.email.email, type.inbound. Sensors: beta.ml_topic, file.explode, ml.nlu_classifier, profile.by_sender, profile.by_sender_email, regex.icontains, regex.match, strings.icontains, strings.iends_with, strings.ilike. Reference lists: $file_types_images, $high_trust_sender_root_domains, $org_domains.
Indicators matched (28)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | (\bh\W?r\W?\b|human\s?resources|hr depart(ment)?|employee relations) |
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | sender |
sender.email.domain.tld | equals | hr |
regex.icontains | regex | HR (?:Events|Expert|Support Center|Studies|Knowledge Cloud|News Library|Crowd|Solutions|Interests)|HR and People Operations |
strings.icontains | substring | constantcontact.com |
headers.hops[].authentication_results.dkim_details[].domain | equals | auth.ccsend.com |
strings.iends_with | suffix | ccsend.com |
strings.ilike | substring | *unsubscribe* |
strings.ilike | substring | update your preferences |
strings.ilike | substring | add us to your address book |
ml.nlu_classifier(body.current_thread.text).entities[].name | equals | request |
ml.nlu_classifier(body.current_thread.text).entities[].name | member | urgency |
16 more
ml.nlu_classifier(body.current_thread.text).entities[].name | member | financial |
beta.ml_topic(body.current_thread.text).topics[].name | equals | Professional and Career Development |
beta.ml_topic(body.current_thread.text).topics[].confidence | equals | high |
attachments[].file_type | equals | pdf |
file.explode(attachments[])[].scan.qr.type | equals | url |
body.links[].href_url.domain.root_domain | equals | aka.ms |
regex.match | regex | [A-Z ]+ |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].name | equals | cred_theft |
ml.nlu_classifier(file.explode(attachments[])[].scan.ocr.raw).intents[].confidence | equals | high |
beta.ml_topic(body.current_thread.text).topics[].name | member | Newsletters and Digests |
beta.ml_topic(body.current_thread.text).topics[].name | member | Advertising and Promotions |
beta.ml_topic(body.current_thread.text).topics[].name | member | Educational and Research |
sender.email.email | member | adobesign@adobesign.com |
sender.email.email | member | noreply@salesforce.com |
sender.email.email | member | support@salesforce.com |
sender.email.email | member | no-reply@salesforce.com |