Detection rules › Sublime MQL
Impersonation: Internal corporate services
Detects phishing attempts that impersonate corporate services such as HR, helpdesk, and benefits, using specific language in the subject or sender's name and containing suspicious links from low-reputation or mass-mailing domains.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Employee, Social engineering |
Event coverage
Rule body MQL
type.inbound
// use distinct "urls" (without query params) to determine number of links
and 0 < length(distinct(body.links,
// strip out query params to determine
// the unique number of links
strings.concat(.href_url.scheme,
.href_url.domain.domain,
.href_url.path
)
)
) <= 8
// HR language found in subject
and (
(
length(subject.subject) > 20
and regex.icontains(subject.subject,
'(time.{0,4}sheet)|(employ|complete|update(?:d| to| regarding our)|workplace).{0,30}(benefit|handbook|comp\b|compensation|salary|\bpay(?:roll)?\b|policy|policies|guidelines?|conduct|acknowl|PTO|vacation|assess|eval)|(HR|Human Resources).{0,5}ADM[il]N',
// shorten the distance to 3 or less words for the word "review"
// special handling of benefits
'\breview\b(?:\w+(?:\s\w+)?|[[:punct:]]+|\s+){0,3}(benefits?(?:$|.?(?:statement|enrollment))|handbook|comp\b|compensation|salary|bonus|\bpay(?:roll)?\b)',
// handle the year in the subject, and expand the distance to 5 or less words
'20\d{2}\b(?:\w+(?:\s\w+)?|[[:punct:]]+|\s+){0,5}(benefits?(?:$|.?(?:statement|enrollment))|handbook|comp\b|compensation|salary|bonus|\bpay(?:roll)?\b)'
)
)
// or HR language found in sender
or (
regex.icontains(sender.display_name,
'(Employ|Time.{0,3}sheet|\bHR\b|Human R|Handbook|\bIT[- ]|Help.{0,3}Desk)|Internal.?Comm|Enroll?ment Service|Open Enroll?ment|Admin Support'
)
and not regex.icontains(sender.display_name,
"forum|employee voice|briefs|newsletter|screening"
)
and not regex.icontains(sender.display_name,
"HR (new|vue|view|tech admin|global)"
)
and not strings.icontains(sender.display_name, "get it")
)
// or assessment report language found in body
or (
regex.icontains(body.current_thread.text,
'20\d{2}(?:[[:punct:]](?:20)?\d{2})? (?:\w+ )?assessment report'
)
)
// or HR department language found in body via NLU
or any(ml.nlu_classifier(body.current_thread.text).entities,
.name in ("org", "sender")
and regex.icontains(.text,
'\bhr\b',
'human resources',
'operations department'
)
)
)
// suspicious display_text
and (
any(body.links,
regex.icontains(.display_text,
'(?:verify|view|click|download|goto|keep|Vιew|release|access|open|allow|deny|new).{0,10}(?:request|handbook|here|report|attachment|current|download|fax|file|document|message|same|doc|access|polic(?:y|ie))s?'
)
and not strings.ilike(.display_text, "*unsub*")
and not strings.ilike(.display_text, "*privacy?policy*")
and not strings.ilike(.href_url.url, "*privacy?policy*")
and not strings.ilike(.display_text, "*REGISTER*")
// from a low reputation link
and (
not .href_url.domain.root_domain in $org_domains
and (
(
.href_url.domain.root_domain not in $tranco_1m
or .href_url.domain.domain in $free_file_hosts
or .href_url.domain.root_domain in $free_file_hosts
or .href_url.domain.root_domain in $free_subdomain_hosts
or .href_url.domain.domain in $url_shorteners
or .href_url.domain.domain in $social_landing_hosts
)
or
// or mass mailer link, masks the actual URL
.href_url.domain.root_domain in (
"hubspotlinks.com",
"mandrillapp.com",
"sendgrid.net",
"rs6.net",
"mailanyone.net",
"perspectivefunnel.co"
)
)
)
)
// or credential theft confidence high
or (
length(body.links) > 0
and any(ml.nlu_classifier(body.current_thread.text).intents,
.name == "cred_theft" and .confidence == "high"
)
and not sender.email.domain.root_domain in (
"servicenowservices.com",
"workplaceextras.com",
"tempo.io",
"or.us",
"proofpoint.com"
)
)
or any(filter(attachments,
.content_type == "message/rfc822" or .file_extension in ('eml')
),
any(file.parse_eml(.).attachments,
any(file.explode(.),
regex.icontains(.scan.ocr.raw, 'scan|camera')
and regex.icontains(.scan.ocr.raw, '\bQR\b|Q\.R\.|barcode')
)
)
)
)
// negate messages where "click here" was found and was a link actually an unsub link
// this method allows for matching on other 'click here' links if they are present
and not (
length(filter(body.links, strings.icontains(.display_text, 'click here'))) > 0
and (
length(filter(body.links, strings.icontains(.display_text, 'click here'))) == strings.icount(body.current_thread.text,
'click here to unsubscribe'
)
)
)
// negate highly trusted sender domains unless they fail DMARC authentication
and (
(
(
sender.email.domain.root_domain in $high_trust_sender_root_domains
or sender.email.domain.root_domain in $org_domains
)
and not headers.auth_summary.dmarc.pass
)
or (
sender.email.domain.root_domain not in $high_trust_sender_root_domains
and sender.email.domain.root_domain not in $org_domains
)
)
// not from sharepointonline actual
and not (
sender.email.domain.root_domain == "sharepointonline.com"
and strings.ends_with(headers.message_id, '@odspnotify>')
and strings.starts_with(headers.message_id, "<Spo")
)
// netate common FP topics
and not any(beta.ml_topic(body.current_thread.text).topics,
.name in (
"Events and Webinars",
"Advertising and Promotions",
"Newsletters and Digests"
)
and .confidence == "high"
)
// negate common helpdesk/HR platforms
and not any(headers.domains,
.root_domain in (
"freshemail.io",
"zendesk.com",
"employeenavigator.com",
"saashr.com" // Kronos owned Saas HR offering
)
)
// negate observed HR newsletters
and not (
any(headers.hops,
strings.icontains(.authentication_results.spf_details.designator,
"constantcontact.com"
)
)
and strings.starts_with(sender.email.local_part, 'newsletters-hr')
and sender.email.domain.root_domain == "ccsend.com"
)
// the message is unsolicited and no false positives
and (
not profile.by_sender_email().solicited
or (
profile.by_sender().any_messages_malicious_or_spam
and not profile.by_sender().any_messages_benign
)
or (
profile.by_sender().any_messages_malicious_or_spam
and profile.by_sender().any_messages_benign
and not (headers.auth_summary.dmarc.pass and headers.auth_summary.spf.pass)
)
)
// negate instances where proofpoint sends a review of a reported message via analyzer
and not (
sender.email.email == "analyzer@analyzer.securityeducation.com"
and any(headers.domains, .root_domain == "pphosted.com")
and headers.auth_summary.spf.pass
and headers.auth_summary.dmarc.pass
)
Detection logic
Scope: inbound message.
Detects phishing attempts that impersonate corporate services such as HR, helpdesk, and benefits, using specific language in the subject or sender's name and containing suspicious links from low-reputation or mass-mailing domains.
- inbound message
all of:
- length(distinct(body.links, strings.concat(.href_url.scheme, .href_url.domain.domain, .href_url.path))) > 0
- length(distinct(body.links, strings.concat(.href_url.scheme, .href_url.domain.domain, .href_url.path))) ≤ 8
any of:
all of:
- length(subject.subject) > 20
subject.subject matches any of 3 patterns
(time.{0,4}sheet)|(employ|complete|update(?:d| to| regarding our)|workplace).{0,30}(benefit|handbook|comp\b|compensation|salary|\bpay(?:roll)?\b|policy|policies|guidelines?|conduct|acknowl|PTO|vacation|assess|eval)|(HR|Human Resources).{0,5}ADM[il]N\breview\b(?:\w+(?:\s\w+)?|[[:punct:]]+|\s+){0,3}(benefits?(?:$|.?(?:statement|enrollment))|handbook|comp\b|compensation|salary|bonus|\bpay(?:roll)?\b)20\d{2}\b(?:\w+(?:\s\w+)?|[[:punct:]]+|\s+){0,5}(benefits?(?:$|.?(?:statement|enrollment))|handbook|comp\b|compensation|salary|bonus|\bpay(?:roll)?\b)
all of:
- sender.display_name matches '(Employ|Time.{0,3}sheet|\\bHR\\b|Human R|Handbook|\\bIT[- ]|Help.{0,3}Desk)|Internal.?Comm|Enroll?ment Service|Open Enroll?ment|Admin Support'
not:
- sender.display_name matches 'forum|employee voice|briefs|newsletter|screening'
not:
- sender.display_name matches 'HR (new|vue|view|tech admin|global)'
not:
- sender.display_name contains 'get it'
- body.current_thread.text matches '20\\d{2}(?:[[:punct:]](?:20)?\\d{2})? (?:\\w+ )?assessment report'
any of
ml.nlu_classifier(body.current_thread.text).entitieswhere all hold:- .name in ('org', 'sender')
.text matches any of 3 patterns
\bhr\bhuman resourcesoperations department
any of:
any of
body.linkswhere all hold:- .display_text matches '(?:verify|view|click|download|goto|keep|Vιew|release|access|open|allow|deny|new).{0,10}(?:request|handbook|here|report|attachment|current|download|fax|file|document|message|same|doc|access|polic(?:y|ie))s?'
not:
- .display_text matches '*unsub*'
not:
- .display_text matches '*privacy?policy*'
not:
- .href_url.url matches '*privacy?policy*'
not:
- .display_text matches '*REGISTER*'
all of:
not:
- .href_url.domain.root_domain in $org_domains
any of:
any of:
- .href_url.domain.root_domain not in $tranco_1m
- .href_url.domain.domain in $free_file_hosts
- .href_url.domain.root_domain in $free_file_hosts
- .href_url.domain.root_domain in $free_subdomain_hosts
- .href_url.domain.domain in $url_shorteners
- .href_url.domain.domain in $social_landing_hosts
- .href_url.domain.root_domain in ('hubspotlinks.com', 'mandrillapp.com', 'sendgrid.net', 'rs6.net', 'mailanyone.net', 'perspectivefunnel.co')
all of:
- length(body.links) > 0
any of
ml.nlu_classifier(body.current_thread.text).intentswhere all hold:- .name is 'cred_theft'
- .confidence is 'high'
not:
- sender.email.domain.root_domain in ('servicenowservices.com', 'workplaceextras.com', 'tempo.io', 'or.us', 'proofpoint.com')
any of
filter(attachments)where:any of
file.parse_eml(.).attachmentswhere:any of
file.explode(.)where all hold:- .scan.ocr.raw matches 'scan|camera'
- .scan.ocr.raw matches '\\bQR\\b|Q\\.R\\.|barcode'
not:
all of:
- length(filter(body.links, strings.icontains(.display_text, 'click here'))) > 0
- length(filter(body.links, strings.icontains(.display_text, 'click here'))) is strings.icount(body.current_thread.text, 'click here to unsubscribe')
any of:
all of:
any of:
- sender.email.domain.root_domain in $high_trust_sender_root_domains
- sender.email.domain.root_domain in $org_domains
not:
- headers.auth_summary.dmarc.pass
all of:
- sender.email.domain.root_domain not in $high_trust_sender_root_domains
- sender.email.domain.root_domain not in $org_domains
not:
all of:
- sender.email.domain.root_domain is 'sharepointonline.com'
- headers.message_id ends with '@odspnotify>'
- headers.message_id starts with '<Spo'
not:
any of
beta.ml_topic(body.current_thread.text).topicswhere all hold:- .name in ('Events and Webinars', 'Advertising and Promotions', 'Newsletters and Digests')
- .confidence is 'high'
not:
any of
headers.domainswhere:- .root_domain in ('freshemail.io', 'zendesk.com', 'employeenavigator.com', 'saashr.com')
not:
all of:
any of
headers.hopswhere:- .authentication_results.spf_details.designator contains 'constantcontact.com'
- sender.email.local_part starts with 'newsletters-hr'
- sender.email.domain.root_domain is 'ccsend.com'
any of:
not:
- profile.by_sender_email().solicited
all of:
- profile.by_sender().any_messages_malicious_or_spam
not:
- profile.by_sender().any_messages_benign
all of:
- profile.by_sender().any_messages_malicious_or_spam
- profile.by_sender().any_messages_benign
not:
all of:
- headers.auth_summary.dmarc.pass
- headers.auth_summary.spf.pass
not:
all of:
- sender.email.email is 'analyzer@analyzer.securityeducation.com'
any of
headers.domainswhere:- .root_domain is 'pphosted.com'
- headers.auth_summary.spf.pass
- headers.auth_summary.dmarc.pass
Inspects: attachments[].content_type, attachments[].file_extension, body.current_thread.text, body.links, body.links[].display_text, body.links[].href_url.domain.domain, body.links[].href_url.domain.root_domain, body.links[].href_url.path, body.links[].href_url.scheme, body.links[].href_url.url, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.domains, headers.domains[].root_domain, headers.hops, headers.hops[].authentication_results.spf_details.designator, headers.message_id, sender.display_name, sender.email.domain.root_domain, sender.email.email, sender.email.local_part, subject.subject, type.inbound. Sensors: beta.ml_topic, file.explode, file.parse_eml, ml.nlu_classifier, profile.by_sender, profile.by_sender_email, regex.icontains, strings.concat, strings.ends_with, strings.icontains, strings.icount, strings.ilike, strings.starts_with. Reference lists: $free_file_hosts, $free_subdomain_hosts, $high_trust_sender_root_domains, $org_domains, $social_landing_hosts, $tranco_1m, $url_shorteners.
Indicators matched (51)
| Field | Match | Value |
|---|---|---|
regex.icontains | regex | (time.{0,4}sheet)|(employ|complete|update(?:d| to| regarding our)|workplace).{0,30}(benefit|handbook|comp\b|compensation|salary|\bpay(?:roll)?\b|policy|policies|guidelines?|conduct|acknowl|PTO|vacation|assess|eval)|(HR|Human Resources).{0,5}ADM[il]N |
regex.icontains | regex | \breview\b(?:\w+(?:\s\w+)?|[[:punct:]]+|\s+){0,3}(benefits?(?:$|.?(?:statement|enrollment))|handbook|comp\b|compensation|salary|bonus|\bpay(?:roll)?\b) |
regex.icontains | regex | 20\d{2}\b(?:\w+(?:\s\w+)?|[[:punct:]]+|\s+){0,5}(benefits?(?:$|.?(?:statement|enrollment))|handbook|comp\b|compensation|salary|bonus|\bpay(?:roll)?\b) |
regex.icontains | regex | (Employ|Time.{0,3}sheet|\bHR\b|Human R|Handbook|\bIT[- ]|Help.{0,3}Desk)|Internal.?Comm|Enroll?ment Service|Open Enroll?ment|Admin Support |
regex.icontains | regex | forum|employee voice|briefs|newsletter|screening |
regex.icontains | regex | HR (new|vue|view|tech admin|global) |
strings.icontains | substring | get it |
regex.icontains | regex | 20\d{2}(?:[[:punct:]](?:20)?\d{2})? (?:\w+ )?assessment report |
ml.nlu_classifier(body.current_thread.text).entities[].name | member | org |
ml.nlu_classifier(body.current_thread.text).entities[].name | member | sender |
regex.icontains | regex | \bhr\b |
regex.icontains | regex | human resources |
39 more
regex.icontains | regex | operations department |
regex.icontains | regex | (?:verify|view|click|download|goto|keep|Vιew|release|access|open|allow|deny|new).{0,10}(?:request|handbook|here|report|attachment|current|download|fax|file|document|message|same|doc|access|polic(?:y|ie))s? |
strings.ilike | substring | *unsub* |
strings.ilike | substring | *privacy?policy* |
strings.ilike | substring | *REGISTER* |
body.links[].href_url.domain.root_domain | member | hubspotlinks.com |
body.links[].href_url.domain.root_domain | member | mandrillapp.com |
body.links[].href_url.domain.root_domain | member | sendgrid.net |
body.links[].href_url.domain.root_domain | member | rs6.net |
body.links[].href_url.domain.root_domain | member | mailanyone.net |
body.links[].href_url.domain.root_domain | member | perspectivefunnel.co |
ml.nlu_classifier(body.current_thread.text).intents[].name | equals | cred_theft |
ml.nlu_classifier(body.current_thread.text).intents[].confidence | equals | high |
sender.email.domain.root_domain | member | servicenowservices.com |
sender.email.domain.root_domain | member | workplaceextras.com |
sender.email.domain.root_domain | member | tempo.io |
sender.email.domain.root_domain | member | or.us |
sender.email.domain.root_domain | member | proofpoint.com |
attachments[].content_type | equals | message/rfc822 |
attachments[].file_extension | member | eml |
regex.icontains | regex | scan|camera |
regex.icontains | regex | \bQR\b|Q\.R\.|barcode |
strings.icontains | substring | click here |
sender.email.domain.root_domain | equals | sharepointonline.com |
strings.ends_with | suffix | @odspnotify> |
strings.starts_with | prefix | <Spo |
beta.ml_topic(body.current_thread.text).topics[].name | member | Events and Webinars |
beta.ml_topic(body.current_thread.text).topics[].name | member | Advertising and Promotions |
beta.ml_topic(body.current_thread.text).topics[].name | member | Newsletters and Digests |
beta.ml_topic(body.current_thread.text).topics[].confidence | equals | high |
headers.domains[].root_domain | member | freshemail.io |
headers.domains[].root_domain | member | zendesk.com |
headers.domains[].root_domain | member | employeenavigator.com |
headers.domains[].root_domain | member | saashr.com |
strings.icontains | substring | constantcontact.com |
strings.starts_with | prefix | newsletters-hr |
sender.email.domain.root_domain | equals | ccsend.com |
sender.email.email | equals | analyzer@analyzer.securityeducation.com |
headers.domains[].root_domain | equals | pphosted.com |