Credential phishing: Engaging language and other indicators (untrusted sender)
Message contains various suspicious indicators as well as engaging language resembling credential theft from an untrusted sender.
Sublime rule (View on GitHub)
1name: "Credential phishing: Engaging language and other indicators (untrusted sender)"
2description: |
3 Message contains various suspicious indicators as well as engaging language resembling credential theft from an untrusted sender.
4type: "rule"
5severity: "medium"
6source: |
7 type.inbound
8 and (
9 regex.icontains(subject.subject,
10 "termination.*notice",
11 "38417",
12 ":completed",
13 "[il1]{2}mit.*ma[il1]{2} ?bo?x",
14 "[il][il][il]egai[ -]",
15 "[li][li][li]ega[li] attempt",
16 "[ng]-?[io]n .*block",
17 "[ng]-?[io]n .*cancel",
18 "[ng]-?[io]n .*deactiv",
19 "[ng]-?[io]n .*disabl",
20 "action.*required",
21 "abandon.*package",
22 "about.your.account",
23 "acc(ou)?n?t (is )?on ho[li]d",
24 "acc(ou)?n?t.*terminat",
25 "acc(oun)?t.*[il1]{2}mitation",
26 "access.*limitation",
27 "account (will be )?block",
28 "account.*de-?activat",
29 "account.*locked",
30 "account.*re-verification",
31 "account.*security",
32 "account.*suspension",
33 "account.has.expired",
34 "account.will.be.blocked",
35 "account v[il]o[li]at",
36 "activity.*acc(oun)?t",
37 "almost.full",
38 "app[li]e.[il]d",
39 "authenticate.*account",
40 "been.*suspend",
41 "crediential.*notif",
42 "clos.*of.*account.*processed",
43 "confirm.your.account",
44 "courier.*able",
45 "crediential.*notif",
46 "deactivation.*in.*progress",
47 "delivery.*attempt.*failed",
48 "disconnection.*notice",
49 "document.received",
50 "documented.*shared.*with.*you",
51 "dropbox.*document",
52 "e-?ma[il1]+ .{010}suspen",
53 "e-?ma[il1]{1} user",
54 "e-?ma[il1]{2} acc",
55 "e-?ma[il1]{2} preview",
56 "e-?ma[il1]{2}.*up.?grade",
57 "e.?ma[il1]{2}.*server",
58 "e.?ma[il1]{2}.*suspend",
59 "email.update",
60 "faxed you",
61 "fraud(ulent)?.*charge",
62 "from.helpdesk",
63 "fu[il1]{2}.*ma[il1]+[ -]?box",
64 "has.been.*suspended",
65 "has.been.limited",
66 "have.locked",
67 "he[li]p ?desk upgrade",
68 "heipdesk",
69 "i[il]iega[il]",
70 "ii[il]ega[il]",
71 "incoming e?mail",
72 "incoming.*fax",
73 "lock.*security",
74 "ma[il1]{1}[ -]?box.*quo",
75 "ma[il1]{2}[ -]?box.*fu[il1]",
76 "ma[il1]{2}box.*[il1]{2}mit",
77 "ma[il1]{2}box stor",
78 "mail on.?hold",
79 "mail.*box.*migration",
80 "mail.*de-?activat",
81 "mail.update.required",
82 "mails.*pending",
83 "messages.*pending",
84 "missed.*shipping.*notification",
85 "missed.shipment.notification",
86 "must.update.your.account",
87 "new [sl][io]g?[nig][ -]?in from",
88 "new voice ?-?mail",
89 "notifications.*pending",
90 "office.*3.*6.*5.*suspend",
91 "office365",
92 "on google docs with you",
93 "online doc",
94 "password.*compromised",
95 "(?:payroll|salary|bonus).*Distribution",
96 "periodic maintenance",
97 "potential(ly)? unauthorized",
98 "refund not approved",
99 "report",
100 "revised.*policy",
101 "scam",
102 "scanned.?invoice",
103 "secured?.update",
104 "security breach",
105 "securlty",
106 "signed.*delivery",
107 "status of your .{314}? ?delivery",
108 "susp[il1]+c[il1]+ous.*act[il1]+v[il1]+ty",
109 "suspicious.*sign.*[io]n",
110 "suspicious.activit",
111 "temporar(il)?y deactivate",
112 "temporar[il1]{2}y disab[li]ed",
113 "temporarily.*lock",
114 "un-?usua[li].activity",
115 "unable.*deliver",
116 "unauthorized.*activit",
117 "unauthorized.device",
118 "undelivered message",
119 "unread.*doc",
120 "unusual.activity",
121 "(?:unrecognized|Unusual|suspicious|unknown) (?:log|sign).?[io]n attempt",
122 "upgrade.*account",
123 "upgrade.notice",
124 "urgent message",
125 "urgent.verification",
126 "v[il1]o[li1]at[il1]on security",
127 "va[il1]{1}date.*ma[il1]{2}[ -]?box",
128 "verification ?-?require",
129 "verification( )?-?need",
130 "verify.your?.account",
131 "web ?-?ma[il1]{2}",
132 "web[ -]?ma[il1]{2}",
133 "will.be.suspended",
134 "your (customer )?account .as",
135 "your.office.365",
136 "your.online.access",
137 "de.activation",
138 // https://github.com/sublime-security/static-files/blob/master/suspicious_subjects.txt
139 "account has been limited",
140 "action required",
141 "almost full",
142 "apd notifi cation",
143 "are you at your desk",
144 "are you available",
145 "attached file to docusign",
146 "banking is temporarily unavailable",
147 "bankofamerica",
148 "closing statement invoice",
149 "completed: docusign",
150 "de-activation of",
151 "delivery attempt",
152 "delivery stopped for shipment",
153 "detected suspicious",
154 "detected suspicious actvity",
155 "docu sign",
156 "document for you",
157 "document has been sent to you via docusign",
158 "document is ready for signature",
159 "docusign",
160 "encrypted message",
161 "failed delivery",
162 "fedex tracking",
163 "file was shared",
164 "freefax",
165 "fwd: due invoice paid",
166 "has shared",
167 "inbox is full",
168 "invitation to comment",
169 "invitation to edit",
170 "invoice due",
171 "left you a message",
172 "message from",
173 "new message",
174 "new voicemail",
175 "on desk",
176 "out of space",
177 "password reset",
178 "payment status",
179 "pay notification",
180 "quick reply",
181 "re: w-2",
182 "required",
183 "required: completed docusign",
184 "remittance",
185 "ringcentral",
186 "scanned image",
187 "secured files",
188 "secured pdf",
189 "security alert",
190 "new sign-in",
191 "new sign in",
192 "sign-in attempt",
193 "sign in attempt",
194 "staff review",
195 "suspicious activity",
196 "unrecognized login attempt",
197 "unusual signin",
198 "upgrade immediately",
199 "urgent",
200 "wants to share",
201 "w2",
202 "you have notifications pending",
203 "your account",
204 "your amazon order",
205 "your document settlement",
206 "your order with amazon",
207 "your password has been compromised",
208 )
209 or (
210 regex.icontains(subject.subject, 'account.has.been')
211 and not regex.icontains(subject.subject, 'account.has.been.*created')
212 )
213 or (
214 regex.icontains(sender.display_name,
215 "Admin",
216 "Administrator",
217 "Alert",
218 "Assistant",
219 "Authenticat(or|ion)",
220 "Billing",
221 "Benefits",
222 "Bonus",
223 "CEO",
224 "CFO",
225 "CIO",
226 "CTO",
227 "Chairman",
228 "Claim",
229 "Confirm",
230 "Cpanel Mail",
231 "Critical",
232 "Customer Service",
233 "Deal",
234 "Discount",
235 "Director",
236 "Exclusive",
237 "Executive",
238 "Fax",
239 "Free",
240 "Gift",
241 '\bHR\b',
242 "Helpdesk",
243 "Human Resources",
244 "Immediate",
245 "Important",
246 "Info",
247 "Information",
248 "Invoice",
249 '\bIT\b',
250 '\bLegal\b',
251 "Lottery",
252 "Management",
253 "Manager",
254 "Member Services",
255 "Notification",
256 "Offer",
257 "Official Communication",
258 "Operations",
259 "Order",
260 "Partner",
261 "Payment",
262 "Payroll",
263 "Postmaster",
264 "President",
265 "Premium",
266 "Prize",
267 "Receipt",
268 "Refund",
269 "Registrar",
270 "Required",
271 "Reward",
272 "Sales",
273 "Secretary",
274 "Security",
275 "Service",
276 "Storage",
277 "Support",
278 "Sweepstakes",
279 "System",
280 "Tax",
281 "Tech Support",
282 "Update",
283 "Upgrade",
284 "Urgent",
285 "Validate",
286 "Verify",
287 "VIP",
288 "Webmaster",
289 "Winner",
290 )
291 // add negation for common FPs in the sender display_name
292 and not strings.icontains(sender.display_name, "service bulletin")
293 and not strings.icontains(sender.display_name, "automotive service")
294 )
295 )
296 and (
297 4 of (
298 any(recipients.to,
299 .email.domain.valid
300 and (
301 strings.icontains(body.current_thread.text, .email.email)
302 or strings.icontains(body.current_thread.text, .email.local_part)
303 )
304 ),
305 any(ml.nlu_classifier(body.current_thread.text).intents,
306 .name == "cred_theft" and .confidence in ("medium", "high")
307 ),
308 any(ml.nlu_classifier(body.current_thread.text).entities,
309 .name == "request"
310 ),
311 // recipient email address base64 encoded in link
312 any(body.links,
313 any(recipients.to,
314 any(beta.scan_base64(..href_url.url,
315 ignore_padding=true,
316 format="url"
317 ),
318 strings.icontains(., ..email.email)
319 )
320 )
321 ),
322 (
323 // freemail providers should never be sending this type of email
324 sender.email.domain.domain in $free_email_providers
325
326 // if not freemail, it's suspicious if the sender's root domain
327 // doesn't match any links in the body
328 or all(body.links,
329 .href_url.domain.root_domain != sender.email.domain.root_domain
330 and (
331 .href_url.domain.root_domain not in $org_domains
332 // ignore recipient email addresses in the body in relation to this check
333 or (
334 .href_url.domain.root_domain in $org_domains
335 and any(recipients.to,
336 strings.icount(body.current_thread.text, .email.email) == strings.icount(body.current_thread.text,
337 .email.domain.domain
338 )
339 )
340 )
341 )
342 )
343
344 // bulk mailers should also never be sending this type of email
345 or all(filter(body.links,
346 .href_url.domain.domain not in (
347 "aka.ms",
348 "mimecast.com",
349 "mimecastprotect.com",
350 "cisco.com"
351 )
352 ),
353 .href_url.domain.root_domain in $bulk_mailer_url_root_domains
354 )
355 ),
356 // in case it's embedded in an image attachment
357 // note: don't use message_screenshot() because it's not limited to current_thread
358 // and may FP
359 any(attachments,
360 .file_type in $file_types_images
361 and any(file.explode(.),
362 any(ml.nlu_classifier(.scan.ocr.raw).intents,
363 .name == "cred_theft" and .confidence == "high"
364 )
365 )
366 ),
367 strings.contains(body.current_thread.text,
368 "Your mailbox can no longer send or receive messages."
369 ),
370 any(body.links,
371 strings.icontains(.href_url.query_params, 'redirect')
372 or any(.href_url.rewrite.encoders,
373 strings.icontains(., "open_redirect")
374 )
375 ),
376 // multiple entities displaying urgency
377 length(filter(ml.nlu_classifier(body.current_thread.text).entities,
378 .name == "urgency"
379 )
380 ) >= 2
381 // and any body links
382 and any(body.links,
383 // display text contains a request
384 any(ml.nlu_classifier(.display_text).entities, .name == "request")
385 ),
386 any(body.links,
387 // display text contains a request
388 any(ml.nlu_classifier(.display_text).entities, .name == "request")
389 and (
390 .href_url.domain.domain in $url_shorteners
391 or .href_url.domain.root_domain in $url_shorteners
392 or .href_url.domain.domain in $free_file_hosts
393 or (
394 .href_url.domain.root_domain in (
395 "mimecast.com",
396 "mimecastprotect.com"
397 )
398 and any(regex.extract(.href_url.query_params, 'domain=([^&]+)'),
399 any(.groups, . in $url_shorteners)
400 )
401 )
402 )
403 ),
404 // common greetings via email.local_part
405 any(recipients.to,
406 length(.email.local_part) > 2
407 and
408 // use count to ensure the email address is not part of a disclaimer
409 strings.icount(body.current_thread.text, .email.local_part) >
410 // sum allows us to add more logic as needed
411 strings.icount(body.current_thread.text,
412 strings.concat('was sent to ', .email.email)
413 ) + strings.icount(body.current_thread.text,
414 strings.concat('intended for ', .email.email)
415 )
416 )
417 )
418 or (
419 (
420 // recipient's email address is in the body
421 any(recipients.to,
422 // use count to ensure the email address is not part of a disclaimer
423 strings.icount(body.current_thread.text, .email.email) >
424 // sum allows us to add more logic as needed
425 sum([
426 strings.icount(body.current_thread.text,
427 strings.concat('was sent to ', .email.email)
428 ),
429 strings.icount(body.current_thread.text,
430 strings.concat('intended for ', .email.email)
431 )
432 ]
433 )
434 )
435 // suspicious display text
436 or (
437 length(body.links) == 1
438 and all(body.links,
439 strings.ilike(.display_text, "*click here*", "*password*")
440 )
441 )
442 )
443 // link leads to a suspicious TLD or contains an IP address or contains multiple redirects
444 and any(body.links,
445 (
446 ml.link_analysis(., mode="aggressive").effective_url.domain.tld in $suspicious_tlds
447 or length(distinct(map(ml.link_analysis(., mode="aggressive").redirect_history,
448 .domain.root_domain
449 )
450 )
451 ) >= 4
452 or (
453 any(body.ips,
454 any(body.links, strings.icontains(.href_url.url, ..ip))
455 )
456 )
457 )
458 )
459 )
460 )
461 // exclude Google shared calendar messages
462 // Subject: "<sender name> has shared a calendar with you"
463 and headers.return_path.domain.domain != "calendar-server.bounces.google.com"
464 // negate calendar invites
465 and not (
466 0 < length(attachments) < 3
467 and all(attachments, .content_type in ("text/calendar", "application/ics"))
468 )
469 // negate replies
470 and (
471 (
472 (
473 length(headers.references) > 0
474 or not any(headers.hops,
475 any(.fields, strings.ilike(.name, "In-Reply-To"))
476 )
477 )
478 and not (
479 (
480 strings.istarts_with(subject.subject, "RE:")
481 or strings.istarts_with(subject.subject, "R:")
482 or strings.istarts_with(subject.subject, "ODG:")
483 or strings.istarts_with(subject.subject, "答复:")
484 or strings.istarts_with(subject.subject, "AW:")
485 or strings.istarts_with(subject.subject, "TR:")
486 or strings.istarts_with(subject.subject, "FWD:")
487 or regex.icontains(subject.subject,
488 '^(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:'
489 )
490 )
491 )
492 )
493 or length(headers.references) == 0
494 )
495 // bounce-back and DMARC report negations
496 and not (
497 strings.like(sender.email.local_part,
498 "*postmaster*",
499 "*mailer-daemon*",
500 "*administrator*"
501 )
502 and (
503 any(attachments,
504 .content_type in (
505 "message/rfc822",
506 "message/delivery-status",
507 "text/calendar"
508 )
509 )
510 or (
511 length(attachments) == 1
512 and all(attachments, .content_type in ("application/gzip"))
513 and regex.icontains(subject.subject,
514 '(?:(Report\sDomain).*(Submitter).*(Report-ID))'
515 )
516 )
517 )
518 )
519 and (
520 (
521 profile.by_sender().prevalence != "common"
522 and not profile.by_sender_email().solicited
523 )
524 or (
525 profile.by_sender().any_messages_malicious_or_spam
526 and not profile.by_sender().any_false_positives
527 )
528 )
529 // negate highly trusted sender domains unless they fail DMARC authentication
530 and (
531 (
532 sender.email.domain.root_domain in $high_trust_sender_root_domains
533 and not headers.auth_summary.dmarc.pass
534 )
535 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
536 )
537attack_types:
538 - "Credential Phishing"
539tactics_and_techniques:
540 - "Free email provider"
541 - "Social engineering"
542detection_methods:
543 - "Content analysis"
544 - "Header analysis"
545 - "Natural Language Understanding"
546 - "Sender analysis"
547 - "URL analysis"
548id: "c2bc8ca2-d207-5c7d-96e4-a0d3d33b2af5"