Skip to content

Commit a4398c6

Browse files
[PR sublime-security#3722] added rule: PR# 3722 - Impersonation: Internal corporate services
1 parent 2dc831c commit a4398c6

File tree

1 file changed

+221
-0
lines changed

1 file changed

+221
-0
lines changed
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
name: "PR# 3722 - Impersonation: Internal corporate services"
2+
description: "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."
3+
type: "rule"
4+
severity: "high"
5+
source: |
6+
type.inbound
7+
// use distinct "urls" (without query params) to determine number of links
8+
and 0 < length(distinct(body.links,
9+
// strip out query params to determine
10+
// the unique number of links
11+
strings.concat(.href_url.scheme,
12+
.href_url.domain.domain,
13+
.href_url.path
14+
)
15+
)
16+
) <= 8
17+
18+
// HR language found in subject
19+
and (
20+
(
21+
length(subject.subject) > 20
22+
and regex.icontains(subject.subject,
23+
'(time.{0,4}sheet)|(employ|complete|update(?:d| to| regarding our)).{0,30}(benefit|handbook|comp\b|compensation|salary|\bpay(?:roll)?\b|policy|policies|conduct|acknowl|PTO|vacation|assess|eval)|(HR|Human Resources).{0,5}ADM[il]N',
24+
// shorten the distance to 3 or less words for the word "review"
25+
// special handling of benefits
26+
'\breview\b(?:\w+(?:\s\w+)?|[[:punct:]]+|\s+){0,3}(benefits?(?:$|.?(?:statement|enrollment))|handbook|comp\b|compensation|salary|bonus|\bpay(?:roll)?\b)',
27+
// handle the year in the subject, and expand the distance to 5 or less words
28+
'20\d{2}\b(?:\w+(?:\s\w+)?|[[:punct:]]+|\s+){0,5}(benefits?(?:$|.?(?:statement|enrollment))|handbook|comp\b|compensation|salary|bonus|\bpay(?:roll)?\b)'
29+
)
30+
)
31+
32+
// or HR language found in sender
33+
or (
34+
regex.icontains(sender.display_name,
35+
'(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'
36+
)
37+
and not regex.icontains(sender.display_name,
38+
"forum|employee voice|briefs|newsletter|screening"
39+
)
40+
and not regex.icontains(sender.display_name,
41+
"HR (new|vue|view|tech admin|global)"
42+
)
43+
and not strings.icontains(sender.display_name, "get it")
44+
)
45+
46+
// or assessment report language found in body
47+
or (
48+
regex.icontains(body.current_thread.text,
49+
'20\d{2}(?:[[:punct:]](?:20)?\d{2})? (?:\w+ )?assessment report'
50+
)
51+
)
52+
53+
// or HR department language found in body via NLU
54+
or any(ml.nlu_classifier(body.current_thread.text).entities,
55+
.name in ("org", "sender")
56+
and regex.icontains(.text,
57+
'\bhr\b',
58+
'human resources',
59+
'operations department'
60+
)
61+
)
62+
)
63+
64+
// suspicious display_text
65+
and (
66+
any(body.links,
67+
regex.icontains(.display_text,
68+
'(?:verify|view|click|download|goto|keep|Vιew|release|access|open|allow|deny|new).{0,10}(?:request|here|report|attachment|current|download|fax|file|document|message|same|doc|access|polic(?:y|ie))s?'
69+
)
70+
and not strings.ilike(.display_text, "*unsub*")
71+
and not strings.ilike(.display_text, "*privacy?policy*")
72+
and not strings.ilike(.href_url.url, "*privacy?policy*")
73+
and not strings.ilike(.display_text, "*REGISTER*")
74+
75+
// from a low reputation link
76+
and (
77+
not .href_url.domain.root_domain in $org_domains
78+
and (
79+
(
80+
.href_url.domain.root_domain not in $tranco_1m
81+
or .href_url.domain.domain in $free_file_hosts
82+
or .href_url.domain.root_domain in $free_file_hosts
83+
or .href_url.domain.root_domain in $free_subdomain_hosts
84+
or .href_url.domain.domain in $url_shorteners
85+
or .href_url.domain.domain in $social_landing_hosts
86+
)
87+
or
88+
// or mass mailer link, masks the actual URL
89+
.href_url.domain.root_domain in (
90+
"hubspotlinks.com",
91+
"mandrillapp.com",
92+
"sendgrid.net",
93+
"rs6.net",
94+
"mailanyone.net",
95+
"perspectivefunnel.co"
96+
)
97+
)
98+
)
99+
)
100+
// or credential theft confidence high
101+
or (
102+
length(body.links) > 0
103+
and any(ml.nlu_classifier(body.current_thread.text).intents,
104+
.name == "cred_theft" and .confidence == "high"
105+
)
106+
and not sender.email.domain.root_domain in (
107+
"servicenowservices.com",
108+
"workplaceextras.com",
109+
"tempo.io",
110+
"or.us",
111+
"proofpoint.com"
112+
)
113+
)
114+
or any(filter(attachments,
115+
.content_type == "message/rfc822" or .file_extension in ('eml')
116+
),
117+
any(file.parse_eml(.).attachments,
118+
any(file.explode(.),
119+
regex.icontains(.scan.ocr.raw, 'scan|camera')
120+
and regex.icontains(.scan.ocr.raw, '\bQR\b|Q\.R\.|barcode')
121+
)
122+
)
123+
)
124+
)
125+
// negate messages where "click here" was found and was a link actually an unsub link
126+
// this method allows for matching on other 'click here' links if they are present
127+
and not (
128+
length(filter(body.links, strings.icontains(.display_text, 'click here'))) > 0
129+
and (
130+
length(filter(body.links, strings.icontains(.display_text, 'click here'))) == strings.icount(body.current_thread.text,
131+
'click here to unsubscribe'
132+
)
133+
)
134+
)
135+
136+
// negate highly trusted sender domains unless they fail DMARC authentication
137+
and (
138+
(
139+
(
140+
sender.email.domain.root_domain in $high_trust_sender_root_domains
141+
or sender.email.domain.root_domain in $org_domains
142+
)
143+
and not headers.auth_summary.dmarc.pass
144+
)
145+
or (
146+
sender.email.domain.root_domain not in $high_trust_sender_root_domains
147+
and sender.email.domain.root_domain not in $org_domains
148+
)
149+
)
150+
// not from sharepointonline actual
151+
and not (
152+
sender.email.domain.root_domain == "sharepointonline.com"
153+
and strings.ends_with(headers.message_id, '@odspnotify>')
154+
and strings.starts_with(headers.message_id, "<Spo")
155+
)
156+
// netate common FP topics
157+
and not any(beta.ml_topic(body.current_thread.text).topics,
158+
.name in (
159+
"Events and Webinars",
160+
"Advertising and Promotions",
161+
"Newsletters and Digests"
162+
)
163+
and .confidence == "high"
164+
)
165+
// negate common helpdesk/HR platforms
166+
and not any(headers.domains,
167+
.root_domain in (
168+
"freshemail.io",
169+
"zendesk.com",
170+
"employeenavigator.com",
171+
"saashr.com" // Kronos owned Saas HR offering
172+
)
173+
)
174+
// negate observed HR newsletters
175+
and not (
176+
any(headers.hops,
177+
strings.icontains(.authentication_results.spf_details.designator,
178+
"constantcontact.com"
179+
)
180+
)
181+
and strings.starts_with(sender.email.local_part, 'newsletters-hr')
182+
and sender.email.domain.root_domain == "ccsend.com"
183+
)
184+
// the message is unsolicited and no false positives
185+
and (
186+
not profile.by_sender_email().solicited
187+
or (
188+
profile.by_sender().any_messages_malicious_or_spam
189+
and not profile.by_sender().any_messages_benign
190+
)
191+
or (
192+
profile.by_sender().any_messages_malicious_or_spam
193+
and profile.by_sender().any_messages_benign
194+
and not headers.auth_summary.dmarc.pass
195+
and not headers.auth_summary.spf.pass
196+
)
197+
)
198+
// negate instances where proofpoint sends a review of a reported message via analyzer
199+
and not (
200+
sender.email.email == "analyzer@analyzer.securityeducation.com"
201+
and any(headers.domains, .root_domain == "pphosted.com")
202+
and headers.auth_summary.spf.pass
203+
and headers.auth_summary.dmarc.pass
204+
)
205+
attack_types:
206+
- "Credential Phishing"
207+
tactics_and_techniques:
208+
- "Impersonation: Employee"
209+
- "Social engineering"
210+
detection_methods:
211+
- "Content analysis"
212+
- "Header analysis"
213+
- "Natural Language Understanding"
214+
- "Sender analysis"
215+
id: "b5f2cd97-6b5f-5528-9fdb-ef4c5dc8535a"
216+
tags:
217+
- created_from_open_prs
218+
- rule_status_modified
219+
- pr_author_missingn0pe
220+
references:
221+
- https://github.com/sublime-security/sublime-rules/pull/3722

0 commit comments

Comments
 (0)