Credential phishing: Generic document share template
Detects messages that incorporate recipient-specific information (email domain, local part, or domain elements) alongside document-themed Unicode symbols and keywords. The rule identifies various targeting patterns including greeting-based personalization, attention-grabbing prefixes and multiple recipient elements. It also catches broken template attacks where recipient placeholders remain visible.
Sublime rule (View on GitHub)
1name: "Credential phishing: Generic document share template"
2description: "Detects messages that incorporate recipient-specific information (email domain, local part, or domain elements) alongside document-themed Unicode symbols and keywords. The rule identifies various targeting patterns including greeting-based personalization, attention-grabbing prefixes and multiple recipient elements. It also catches broken template attacks where recipient placeholders remain visible."
3type: "rule"
4severity: "low"
5source: |
6 type.inbound
7 and (
8 // nlu capture for wide scope of greetings to reduce evasion
9 any(filter(ml.nlu_classifier(body.current_thread.text).entities,
10 .name == "greeting"
11 ),
12 any([
13 recipients.to[0].email.domain.sld,
14 recipients.to[0].email.local_part,
15 recipients.to[0].email.domain.domain
16 ],
17 strings.icontains(body.current_thread.text,
18 strings.concat(..text, " ", .)
19 )
20 )
21 )
22 or any([
23 recipients.to[0].email.domain.sld,
24 recipients.to[0].email.local_part,
25 recipients.to[0].email.domain.domain
26 ],
27 // strings logic for non-greeting body starter
28 strings.icontains(body.current_thread.text,
29 strings.concat("attn: ", .)
30 )
31 // strings logic for recipient as starter
32 or strings.icontains(body.current_thread.text,
33 strings.concat(., " balance statement")
34 )
35 )
36 // count of all recipient elements is higher 2 or greater
37 or length(filter([
38 recipients.to[0].email.domain.sld,
39 recipients.to[0].email.local_part,
40 recipients.to[0].email.domain.domain
41 ],
42 strings.icontains(body.current_thread.text, .)
43 )
44 ) >= 2
45
46 // logic for broken attack
47 or any(ml.nlu_classifier(body.current_thread.text).entities,
48 .name == "recipient" and regex.icontains(.text, '[{}]')
49 )
50 )
51
52 // unicode + keyword generic template
53 and (
54 regex.icontains(body.current_thread.text,
55 '(?:\x{270e}|\x{270f}|\x{2710}|\x{270d}|\x{1f589}|\x{1F4C4}|\x{1F4D1}|\x{1F4C1}|\x{1F4EC}).{0,15}(?:document|completion|remit|review|statement|agree|shar(?:ed|ing)|receiv|\bmail\b)',
56 '(?:document|completion|remit|review|statement|agree|shar(?:ed|ing)|receiv|\bmail\b).{0,15}(?:\x{270e}|\x{270f}|\x{2710}|\x{270d}|\x{1f589}|\x{1F4C4}|\x{1F4D1}|\x{1F4C1}|\x{1F4EC})'
57 )
58 // negate sharepoint paths with unicode
59 and not any(body.links,
60 regex.icontains(.display_url.path,
61 '(?:\x{270e}|\x{270f}|\x{2710}|\x{270d}|\x{1f589}|\x{1F4C4}|\x{1F4D1}|\x{1F4C1}|\x{1F4EC})'
62 )
63 )
64 )
65
66 // nlu negation for FP's
67 and any(ml.nlu_classifier(body.current_thread.text).intents, .name != "benign")
68
69 // negate highly trusted sender domains unless they fail DMARC authentication
70 and (
71 (
72 sender.email.domain.root_domain in $high_trust_sender_root_domains
73 and not headers.auth_summary.dmarc.pass
74 )
75 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
76 )
77
78tags:
79 - "Attack surface reduction"
80attack_types:
81 - "BEC/Fraud"
82 - "Credential Phishing"
83tactics_and_techniques:
84 - "Social engineering"
85 - "Evasion"
86detection_methods:
87 - "Content analysis"
88 - "Natural Language Understanding"
89id: "f5bee657-53bc-501f-9b7a-ea51da73a716"