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 or any(body.current_thread.links,
14 regex.icontains(.display_text, '(?:read|view|open) the message')
15 and (
16 .href_url.domain.root_domain not in $tranco_1m
17 or .href_url.domain.domain in $free_file_hosts
18 or .href_url.domain.root_domain in $free_file_hosts
19 or .href_url.domain.root_domain in $free_subdomain_hosts
20 or .href_url.domain.domain in $url_shorteners
21 or .href_url.domain.domain in $social_landing_hosts
22 )
23 )
24 )
25 or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
26 .name == "cred_theft" and .confidence in ("medium", "high")
27 )
28 )
29 and (
30 (
31 regex.icontains(body.current_thread.text,
32 "secured? (message|directory|document|file)"
33 )
34 or regex.icontains(subject.base,
35 "secured? (message|directory|document|file)"
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|file)")
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|file) access'
50 )
51 or regex.icontains(ml.link_analysis(.).final_dom.inner_text,
52 'secured? (?:message|directory|document|file) access'
53 )
54 )
55 or (
56 (
57 length(filter(ml.nlu_classifier(body.current_thread.text).entities,
58 .name == "urgency"
59 )
60 ) >= 2
61 // two-step instructions
62 or (
63 strings.icontains(body.current_thread.text, "view your message")
64 and strings.icontains(body.current_thread.text, "after that,")
65 )
66 )
67 and any(ml.nlu_classifier(body.current_thread.text).topics,
68 .name == "Secure Message" and .confidence != "low"
69 )
70 )
71 )
72 // has at least 1 link
73 and length(body.links) > 0
74
75 // negate legitimate message senders
76 and (
77 sender.email.domain.root_domain not in ("protectedtrust.com")
78 and any(body.links,
79 .href_url.domain.root_domain != sender.email.domain.root_domain
80 )
81 // negate known secure mailers
82 and not all(body.links,
83 .href_url.domain.root_domain in (
84 "mimecast.com",
85 "cisco.com",
86 "csiesafe.com"
87 )
88 )
89 and any(headers.hops,
90 .index == 0
91 and not any(.fields,
92 strings.contains(.value,
93 'multipart/mixed; boundary="PROOFPOINT_BOUNDARY_1"'
94 )
95 )
96 )
97 and not (
98 length(filter(attachments,
99 strings.ilike(.file_name,
100 "logo.*",
101 "lock.gif",
102 "SecureMessageAtt.html"
103 )
104 )
105 ) == 3
106 and any(attachments,
107 .file_type == "html"
108 and any(file.explode(.),
109 .scan.html.title == "Proofpoint Encryption"
110 and any(.scan.url.urls,
111 strings.iends_with(.path,
112 'formpostdir/safeformpost.aspx'
113 )
114 )
115 )
116 and strings.count(file.parse_html(.).raw, 'name="msg') > 3
117 )
118 )
119 and not (
120 any(headers.hops,
121 any(.fields,
122 .name in (
123 'X-ZixNet',
124 'X-VPM-MIV',
125 'X-VPM-ActionCode',
126 'X-VPM-SmtpTo'
127 )
128 )
129 )
130 and any(headers.domains,
131 .root_domain in (
132 "zixport.com",
133 "zixcorp.com",
134 "zixmail.net",
135 "zixworks.com"
136 )
137 )
138 )
139 and not (
140 any(headers.hops, any(.fields, .name == 'X-SendInc-Message-Id'))
141 and any(headers.domains, .root_domain in ("sendinc.net"))
142 )
143 // negating Mimecast sends with MS banner and/or sender's email pulled out as a link
144 and not length(filter(body.links,
145 (
146 .display_text is null
147 and .display_url.url == sender.email.domain.root_domain
148 )
149 or .href_url.domain.root_domain in (
150 "aka.ms",
151 "mimecast.com",
152 "cisco.com"
153 )
154 )
155 ) == length(body.links)
156 )
157 and (
158 (
159 profile.by_sender().prevalence in ("new", "outlier")
160 and not profile.by_sender().solicited
161 )
162 or (
163 profile.by_sender().any_messages_malicious_or_spam
164 and not profile.by_sender().any_messages_benign
165 )
166 // or the sender is all undisclosed or there are no recipients
167 or (
168 length(recipients.to) == 0
169 or all(recipients.to,
170 strings.ilike(.display_name, "undisclosed?recipients")
171 )
172 )
173 // or the sender exhibits a "self sender" pattern
174 or (
175 length(recipients.to) == 1
176 and any(recipients.to, .email.email == sender.email.email)
177 )
178 )
179 and not profile.by_sender().any_messages_benign
180 and not (
181 sender.email.domain.root_domain in $high_trust_sender_root_domains
182 and coalesce(headers.auth_summary.dmarc.pass, false)
183 )
184attack_types:
185 - "Credential Phishing"
186tactics_and_techniques:
187 - "Social engineering"
188detection_methods:
189 - "Natural Language Understanding"
190 - "Sender analysis"
191id: "bd95a7b1-dc96-53c1-bb7c-3a0f98b04744"