Credential phishing: 'Secure message' and engaging language
Body contains language resembling credential theft, and a "secure message" from an untrusted sender.
Sublime rule (View on GitHub)
1name: "Credential phishing: 'Secure message' and engaging language"
2description: |
3 Body contains language resembling credential theft, and a "secure message" from an untrusted sender.
4type: "rule"
5severity: "medium"
6source: |
7 type.inbound
8 and (
9 (
10 any(ml.nlu_classifier(body.current_thread.text).intents,
11 .name == "cred_theft" and .confidence == "high"
12 )
13 // add fallback when NLU doesn't pick up cred theft to check for suspicious links
14 or any(body.current_thread.links,
15 regex.icontains(.display_text, '(?:read|view|open) the message')
16 and (
17 .href_url.domain.root_domain not in $tranco_1m
18 or .href_url.domain.domain in $free_file_hosts
19 or .href_url.domain.root_domain in $free_file_hosts
20 or .href_url.domain.root_domain in $free_subdomain_hosts
21 or .href_url.domain.domain in $url_shorteners
22 or .href_url.domain.domain in $social_landing_hosts
23 )
24 )
25 )
26 or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
27 .name == "cred_theft" and .confidence in ("medium", "high")
28 )
29 )
30
31 // ----- other suspicious signals here -----
32 and (
33 (
34 regex.icontains(body.current_thread.text,
35 "secured? (message|directory|document)"
36 )
37 or strings.icontains(body.current_thread.text, "document portal")
38 or strings.icontains(body.current_thread.text, "encrypted message")
39 or strings.icontains(body.current_thread.text, "protected message")
40 )
41 or any(body.previous_threads,
42 regex.icontains(.text, "secured? (message|directory|document)")
43 or strings.icontains(.text, "document portal")
44 or strings.icontains(.text, "encrypted message")
45 or strings.icontains(.text, "protected message")
46 )
47 or any(body.current_thread.links,
48 regex.icontains(ml.link_analysis(.).final_dom.display_text,
49 'secured? (message|directory|document) access'
50 )
51 )
52 or (
53 length(filter(ml.nlu_classifier(body.current_thread.text).entities,
54 .name == "urgency"
55 )
56 ) >= 2
57 and any(ml.nlu_classifier(body.current_thread.text).topics,
58 .name == "Secure Message" and .confidence != "low"
59 )
60 )
61 )
62 // todo: automated display name / human local part
63 // todo: suspicious link (unfurl click trackers)
64
65 // ----------
66
67 // has at least 1 link
68 and length(body.links) > 0
69
70 // negate legitimate message senders
71 and (
72 sender.email.domain.root_domain not in ("protectedtrust.com")
73 and any(body.links,
74 .href_url.domain.root_domain != sender.email.domain.root_domain
75 )
76 // negate known secure mailers
77 and not all(body.links,
78 .href_url.domain.root_domain in (
79 "mimecast.com",
80 "cisco.com",
81 "csiesafe.com"
82 )
83 )
84 and any(headers.hops,
85 .index == 0
86 and not any(.fields,
87 strings.contains(.value,
88 'multipart/mixed; boundary="PROOFPOINT_BOUNDARY_1"'
89 )
90 )
91 )
92 and not (
93 length(filter(attachments,
94 strings.ilike(.file_name,
95 "logo.*",
96 "lock.gif",
97 "SecureMessageAtt.html"
98 )
99 )
100 ) == 3
101 and any(attachments,
102 .file_type == "html"
103 and any(file.explode(.),
104 .scan.html.title == "Proofpoint Encryption"
105 and any(.scan.url.urls,
106 strings.iends_with(.path,
107 'formpostdir/safeformpost.aspx'
108 )
109 )
110 )
111 and strings.count(file.parse_html(.).raw, 'name="msg') > 3
112 )
113 )
114 and not (
115 any(headers.hops,
116 any(.fields,
117 .name in (
118 'X-ZixNet',
119 'X-VPM-MIV',
120 'X-VPM-ActionCode',
121 'X-VPM-SmtpTo'
122 )
123 )
124 )
125 and any(headers.domains,
126 .root_domain in (
127 "zixport.com",
128 "zixcorp.com",
129 "zixmail.net",
130 "zixworks.com"
131 )
132 )
133 )
134 and not (
135 any(headers.hops, any(.fields, .name == 'X-SendInc-Message-Id'))
136 and any(headers.domains, .root_domain in ("sendinc.net"))
137 )
138 // negating Mimecast sends with MS banner and/or sender's email pulled out as a link
139 and not length(filter(body.links,
140 (
141 .display_text is null
142 and .display_url.url == sender.email.domain.root_domain
143 )
144 or .href_url.domain.root_domain in (
145 "aka.ms",
146 "mimecast.com",
147 "cisco.com"
148 )
149 )
150 ) == length(body.links)
151 )
152 and (
153 (
154 profile.by_sender().prevalence in ("new", "outlier")
155 and not profile.by_sender().solicited
156 )
157 or (
158 profile.by_sender().any_messages_malicious_or_spam
159 and not profile.by_sender().any_messages_benign
160 )
161 // or the sender is all undisclosed or there are no recipients
162 or (
163 length(recipients.to) == 0
164 or all(recipients.to,
165 strings.ilike(.display_name, "undisclosed?recipients")
166 )
167 )
168 // or the sender exhibits a "self sender" pattern
169 or (
170 length(recipients.to) == 1
171 and any(recipients.to, .email.email == sender.email.email)
172 )
173 )
174 and not profile.by_sender().any_messages_benign
175
176 // negate highly trusted sender domains unless they fail DMARC authentication
177 and (
178 (
179 sender.email.domain.root_domain in $high_trust_sender_root_domains
180 and not headers.auth_summary.dmarc.pass
181 )
182 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
183 )
184
185attack_types:
186 - "Credential Phishing"
187tactics_and_techniques:
188 - "Social engineering"
189detection_methods:
190 - "Natural Language Understanding"
191 - "Sender analysis"
192id: "bd95a7b1-dc96-53c1-bb7c-3a0f98b04744"