Brand impersonation: Sharepoint fake file share
This rule detects messages impersonating a Sharepoint file sharing email where no links point to known Microsoft domains.
Sublime rule (View on GitHub)
1name: "Brand impersonation: Sharepoint fake file share"
2description: |
3 This rule detects messages impersonating a Sharepoint file sharing email where no links point to known Microsoft domains.
4type: "rule"
5severity: "medium"
6source: |
7 type.inbound
8
9 // Sharepoint body content looks like this
10 and (
11 (
12 (
13 any([body.current_thread.text, body.plain.raw],
14 strings.ilike(.,
15 "*shared a file with you*",
16 "*shared with you*",
17 "*invited you to access a file*",
18 "*you've received a document*"
19 )
20 )
21 or any(file.explode(beta.message_screenshot()),
22 strings.ilike(.scan.ocr.raw,
23 "*shared a file with you*",
24 "*shared with you*",
25 "*invited you to access a file*",
26 "*you've received a document*"
27 )
28 )
29 )
30 and (
31 strings.ilike(subject.subject,
32 "*shared*",
33 "*updated*",
34 "*sign*",
35 "*review*"
36 )
37 or strings.ilike(subject.subject,
38 "*Excel*",
39 "*SharePoint*",
40 "*PowerPoint*",
41 "*OneNote*"
42 )
43 or subject.subject is null
44 or subject.subject == ""
45 )
46 )
47 or any([
48 "Contigo", // Spanish
49 "Avec vous", // French
50 "Mit Ihnen", // German
51 "Con te", // Italian
52 "Com você", // Portuguese
53 "Met u", // Dutch
54 "С вами", // Russian
55 "与你", // Chinese (Simplified)
56 "與您", // Chinese (Traditional)
57 "あなたと", // Japanese
58 "당신과", // Korean
59 "معك", // Arabic
60 "آپ کے ساتھ", // Urdu
61 "আপনার সাথে", // Bengali
62 "आपके साथ", // Hindi
63 "Sizinle", // Turkish // Azerbaijani
64 "Med dig", // Swedish
65 "Z tobą", // Polish
66 "З вами", // Ukrainian
67 "Önnel", // Hungarian
68 "Μαζί σας", // Greek
69 "איתך", // Hebrew
70 "กับคุณ", // Thai
71 "Với bạn", // Vietnamese
72 "Dengan Anda", // Indonesian // Malay
73 "Nawe", // Swahili
74 "Cu dumneavoastră", // Romanian
75 "S vámi", // Czech
76 "Med deg", // Norwegian
77 "S vami", // Slovak
78 "Med dig", // Danish
79 "Amb vostè", // Catalan
80 "Teiega", // Estonian
81 "S vama", // Serbian
82 ],
83 strings.icontains(subject.subject, .)
84 )
85 )
86
87 // contains logic that impersonates Microsoft
88 and (
89 any(ml.logo_detect(beta.message_screenshot()).brands,
90 strings.starts_with(.name, "Microsoft")
91 )
92 or any(attachments,
93 .file_type in $file_types_images
94 and any(ml.logo_detect(.).brands,
95 strings.starts_with(.name, "Microsoft")
96 )
97 )
98 or (
99 regex.icontains(body.html.raw,
100 '<table[^>]*>\s*<tbody[^>]*>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s* \s*</td>\s*){2}\s*</tr>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s* \s*</td>\s*){2}'
101 )
102 or 3 of (
103 regex.icontains(body.html.raw, '.password-expiration'),
104 regex.icontains(body.html.raw, 'color: #2672ec;'),
105 regex.icontains(body.html.raw, 'Microsoft')
106 )
107 or 4 of (
108 regex.icontains(body.html.raw, 'rgb\(246,\s?93,\s?53\)'),
109 regex.icontains(body.html.raw, 'rgb\(129,\s?187,\s?5\)'),
110 regex.icontains(body.html.raw, 'rgb\(4,\s?165,\s?240\)'),
111 regex.icontains(body.html.raw, 'rgb\(255,\s?186,\s?7\)'),
112 )
113 or 4 of (
114 regex.icontains(body.html.raw,
115 '(background-color:|background:|bgcolor=)(.)red'
116 ),
117 regex.icontains(body.html.raw, 'rgb\(19,\s?186,\s?132\)'),
118 regex.icontains(body.html.raw, 'rgb\(4,\s?166,\s?240\)'),
119 regex.icontains(body.html.raw, 'rgb\(255,\s?186,\s?8\)'),
120 )
121 or 4 of (
122 regex.icontains(body.html.raw, 'rgb\(245,\s?189,\s?67\)'),
123 regex.icontains(body.html.raw, 'rgb\(137,\s?184,\s?57\)'),
124 regex.icontains(body.html.raw, 'rgb\(217,\s?83,\s?51\)'),
125 regex.icontains(body.html.raw, 'rgb\(71,\s?160,\s?218\)')
126 )
127 or 4 of (
128 regex.icontains(body.html.raw, 'rgb\(73,\s?161,\s?232\)'),
129 regex.icontains(body.html.raw, 'rgb\(224,\s?92,\s?53\)'),
130 regex.icontains(body.html.raw, 'rgb\(139,\s?183,\s?55\)'),
131 regex.icontains(body.html.raw, 'rgb\(244,\s?188,\s?65\)')
132 )
133 or 4 of (
134 regex.icontains(body.html.raw, 'rgb\(213,\s?56,\s?62\)'),
135 regex.icontains(body.html.raw, 'rgb\(0,\s?114,\s?30\)'),
136 regex.icontains(body.html.raw, 'rgb\(0,\s?110,\s?173\)'),
137 regex.icontains(body.html.raw, 'rgb\(227,\s?209,\s?43\)'),
138 )
139 or 4 of (
140 regex.icontains(body.html.raw, 'rgb\(246,\s?93,\s?53\)'),
141 regex.icontains(body.html.raw, 'rgb\(129,\s?187,\s?5\)'),
142 regex.icontains(body.html.raw, 'rgb\(4,\s?165,\s?240\)'),
143 regex.icontains(body.html.raw, 'rgb\(255,\s?186,\s?7\)')
144 )
145 or 4 of (
146 regex.icontains(body.html.raw, 'rgb\(242,\s?80,\s?34\)'),
147 regex.icontains(body.html.raw, 'rgb\(127,\s?186,\s?0\)'),
148 regex.icontains(body.html.raw, 'rgb\(0,\s?164,\s?239\)'),
149 regex.icontains(body.html.raw, 'rgb\(255,\s?185,\s?0\)'),
150 )
151 or 4 of (
152 regex.icontains(body.html.raw, 'rgb\(243,\s?83,\s?37\)'),
153 regex.icontains(body.html.raw, 'rgb\(129,\s?188,\s?6\)'),
154 regex.icontains(body.html.raw, 'rgb\(5,\s?166,\s?240\)'),
155 regex.icontains(body.html.raw, 'rgb\(255,\s?186,\s?8\)')
156 )
157 or 4 of (
158 regex.icontains(body.html.raw, 'rgb\(243,\s?80,\s?34\)'),
159 regex.icontains(body.html.raw, 'rgb\(128,\s?187,\s?3\)'),
160 regex.icontains(body.html.raw, 'rgb\(3,\s?165,\s?240\)'),
161 regex.icontains(body.html.raw, 'rgb\(255,\s?185,\s?3\)')
162 )
163 or 4 of (
164 regex.icontains(body.html.raw,
165 '(background-color:|background:|bgcolor=)(.)?(#)?(FF1940|eb5024|F25022|FF1941|red)'
166 ),
167 regex.icontains(body.html.raw,
168 '(background-color:|background:|bgcolor=)(.)?(#)?(36ba57|3eb55d|7db606|7FBA00|36ba58|green)'
169 ),
170 regex.icontains(body.html.raw,
171 '(background-color:|background:|bgcolor=)(.)?#(04a1d6|04B5F0|05a1e8|00A4EF|01a4ef|04a5f0)'
172 ),
173 regex.icontains(body.html.raw,
174 '(background-color:|background:|bgcolor=)(.)?#(FFCA07|f7b408|FFB900|FFCA08|ffb901|ffba07)'
175 ),
176 )
177 or 4 of (
178 regex.icontains(body.html.raw,
179 '(background-color:|background:|bgcolor=)(.)?#(f65314|f65d35|49a1e8|E74F23|F35325)'
180 ),
181 regex.icontains(body.html.raw,
182 '(background-color:|background:|bgcolor=)(.)?#(7cbf42|81bb05|e05c35|7AB206|81BC06)'
183 ),
184 regex.icontains(body.html.raw,
185 '(background-color:|background:|bgcolor=)(.)?#(00a4ef|0078d7|8bb737|04a5f0|059EE4|05A6F0)'
186 ),
187 regex.icontains(body.html.raw,
188 '(background-color:|background:|bgcolor=)(.)?#(ffb900|ffba07|f4bc41|F2B108|FFBA08)'
189 ),
190 )
191 // fuzzy approach
192 or 4 of (
193 regex.icontains(body.html.raw,
194 'rgb\((2[1-4][0-9]|250),\s?(7[0-9]|8[0-9]|9[0-3]),\s?(3[0-9]|4[0-9]|5[0-3])\)'
195 ),
196 regex.icontains(body.html.raw,
197 'rgb\((12[0-9]|13[0-9]),\s?(18[0-9]|190),\s?([0-9]|10)\)'
198 ),
199 regex.icontains(body.html.raw,
200 'rgb\(([0-9]|1[0-5]),\s?(16[0-5]|166),\s?(23[0-9]|240)\)'
201 ),
202 regex.icontains(body.html.raw,
203 'rgb\((25[0-5]),\s?(18[5-9]|19[0-9]),\s?([0-9]|10)\)'
204 )
205 )
206 or 4 of (
207 regex.icontains(body.html.raw, 'rgb\((25[0-5]),\s?(2[0-5]),\s?(6[0-4])\)'),
208 regex.icontains(body.html.raw, 'rgb\((6[0-2]),\s?(18[0-1]),\s?(9[0-3])\)'),
209 regex.icontains(body.html.raw, 'rgb\(([0-4]),\s?(18[0-1]),\s?(24[0])\)'),
210 regex.icontains(body.html.raw, 'rgb\((25[0-5]),\s?(20[0-2]),\s?([0-7])\)')
211 )
212 or regex.icontains(body.html.raw,
213 '<a[^>]+style="[^"]*background-color:\s*#[0-9A-F]{2}[5-9A-F]{2}[0-9A-F]{2}[^"]*"[^>]*>[^<]*(?:open)[^<]*</a>' // blue button containing the word "open"
214 )
215 or (
216 any(recipients.to,
217 strings.icontains(body.current_thread.text,
218 strings.concat(.email.domain.sld,
219 " shared a file with you"
220 )
221 )
222 )
223 )
224 )
225 )
226
227 // Negate messages when the message-id indciates the message is from MS actual. DKIM/SPF domains can be custom and therefore are unpredictable.
228 and not (
229 strings.starts_with(headers.message_id, '<Share-')
230 and strings.ends_with(headers.message_id, '@odspnotify>')
231 )
232
233 // fake Sharepoint shares are easy to identify if there are any links
234 // that don't point to microsoft[.]com or *.sharepoint[.]com
235 and not all(body.links,
236 .href_url.domain.root_domain in (
237 "1drv.ms",
238 "aka.ms",
239 "microsoft.com",
240 "sharepoint.com"
241 )
242 )
243 and sender.email.domain.root_domain not in $org_domains
244 and sender.email.domain.root_domain not in (
245 "bing.com",
246 "microsoft.com",
247 "microsoftonline.com",
248 "microsoftsupport.com",
249 "microsoft365.com",
250 "office.com",
251 "onedrive.com",
252 "sharepointonline.com",
253 "yammer.com",
254 // ignore microsoft privacy statement links
255 "aka.ms"
256 )
257
258 // negate highly trusted sender domains unless they fail DMARC authentication
259 and (
260 (
261 sender.email.domain.root_domain in $high_trust_sender_root_domains
262 and not headers.auth_summary.dmarc.pass
263 )
264 or sender.email.domain.root_domain not in $high_trust_sender_root_domains
265 )
266 and (
267 (not profile.by_sender().solicited)
268 or (
269 profile.by_sender().any_messages_malicious_or_spam
270 and not profile.by_sender().any_false_positives
271 )
272 )
273 and not profile.by_sender().any_false_positives
274attack_types:
275 - "Credential Phishing"
276 - "Malware/Ransomware"
277detection_methods:
278 - "Content analysis"
279 - "Header analysis"
280 - "URL analysis"
281 - "Computer Vision"
282tactics_and_techniques:
283 - "Impersonation: Brand"
284 - "Social engineering"
285id: "ff8b296b-aa0d-5df0-b4d2-0e599b688f6a"