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