Brand impersonation: Microsoft with low reputation links

Detects low reputation links with Microsoft specific indicators in the body.

Sublime rule (View on GitHub)

  1name: "Brand impersonation: Microsoft with low reputation links"
  2description: "Detects low reputation links with Microsoft specific indicators in the body."
  3type: "rule"
  4severity: "medium"
  5source: |
  6 type.inbound
  7 // suspicious link 
  8 and any(body.links,
  9         (
 10           .href_url.domain.root_domain not in $tranco_1m
 11           or .href_url.domain.domain in $free_file_hosts
 12           or .href_url.domain.root_domain in $free_file_hosts
 13           or .href_url.domain.root_domain in $free_subdomain_hosts
 14           or .href_url.domain.domain in $url_shorteners
 15           or 
 16 
 17           // mass mailer link, masks the actual URL
 18           .href_url.domain.root_domain in (
 19             "hubspotlinks.com",
 20             "mandrillapp.com",
 21             "sendgrid.net",
 22             "rs6.net"
 23           )
 24 
 25           // Google AMP redirect
 26           or (
 27             .href_url.domain.sld == "google"
 28             and strings.starts_with(.href_url.path, "/amp/")
 29           )
 30         )
 31 
 32         // exclude sources of potential FPs
 33         and (
 34           .href_url.domain.root_domain not in (
 35             "svc.ms",
 36             "sharepoint.com",
 37             "1drv.ms",
 38             "microsoft.com",
 39             "aka.ms",
 40             "msftauthimages.net",
 41             "mimecastprotect.com"
 42           )
 43           or any(body.links, .href_url.domain.domain in $free_file_hosts)
 44         )
 45         and .href_url.domain.root_domain not in $org_domains
 46 )
 47 
 48 // not a reply
 49 and (
 50   length(headers.references) == 0
 51   or not any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To")))
 52 )
 53 
 54 // Microsoft logo
 55 and (
 56   any(attachments,
 57       .file_type in $file_types_images
 58       and any(ml.logo_detect(.).brands, strings.starts_with(.name, "Microsoft"))
 59   )
 60   or any(ml.logo_detect(beta.message_screenshot()).brands,
 61          strings.starts_with(.name, "Microsoft")
 62   )
 63   or (
 64     regex.icontains(body.html.raw,
 65                     '<table[^>]*>\s*<tbody[^>]*>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s*&nbsp;\s*</td>\s*){2}\s*</tr>\s*<tr[^>]*>\s*(<td[^>]*bgcolor="#[0-9A-Fa-f]{6}"[^>]*>\s*&nbsp;\s*</td>\s*){2}'
 66     )
 67     or regex.icontains(body.html.raw,
 68                        '<td style="background:\s*rgb\(246,\s*93,\s*53\);\s*height:\d+px;">.*?<td style="background:\s*rgb\(129,\s*187,\s*5\);\s*height:\d+px;">.*?<td style="background:\s*rgb\(4,\s*165,\s*240\);\s*height:\d+px;">.*?<td style="background:\s*rgb\(255,\s*186,\s*7\);\s*height:\d+px;">'
 69     )
 70     or 4 of (
 71       regex.icontains(body.html.raw,
 72                       '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(245, 189, 67\);">.{0,10}</td>'
 73       ),
 74       regex.icontains(body.html.raw,
 75                       '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(137, 184, 57\);">.{0,10}</td>'
 76       ),
 77       regex.icontains(body.html.raw,
 78                       '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(217, 83, 51\);">.{0,10}</td>'
 79       ),
 80       regex.icontains(body.html.raw,
 81                       '<td style="width:.\d.px;.height:.\d.px;.background-color:.rgb\(71, 160, 218\);">.{0,10}</td>'
 82       )
 83     )
 84   )
 85 )
 86 
 87 // suspicious content
 88 and (
 89   (
 90     strings.ilike(body.plain.raw,
 91                   "*password*",
 92                   "*document*",
 93                   "*voicemail*",
 94                   "*cache*",
 95                   "*fax*",
 96                   "*storage*",
 97                   "*quota*",
 98                   "*message*"
 99     )
100     and strings.ilike(body.plain.raw,
101                       "*terminated*",
102                       "*review*",
103                       "*expire*",
104                       "*click*",
105                       "*view*",
106                       "*exceed*",
107                       "*clear*",
108                       "*only works*",
109                       "*failed*",
110                       "*deleted*",
111                       "*revalidated*"
112     )
113   )
114   or (
115     any(attachments,
116         .file_type in $file_types_images
117         and any(file.explode(.),
118                 strings.ilike(.scan.ocr.raw,
119                               "*password*",
120                               "*document*",
121                               "*voicemail*",
122                               "*cache*",
123                               "*fax*",
124                               "*storage*",
125                               "*quota*",
126                               "*messages*"
127                 )
128                 and strings.ilike(.scan.ocr.raw,
129                                   "*terminated*",
130                                   "*review*",
131                                   "*expire*",
132                                   "*click*",
133                                   "*view*",
134                                   "*exceed*",
135                                   "*clear*",
136                                   "*only works*",
137                                   "*failed*",
138                                   "*deleted*"
139                 )
140         )
141     )
142   )
143   or (
144     any(file.explode(beta.message_screenshot()),
145         strings.ilike(.scan.ocr.raw,
146                       "*password*",
147                       "*document*",
148                       "*voicemail*",
149                       "*cache*",
150                       "*fax*",
151                       "*storage*",
152                       "*quota*",
153                       "*messages*"
154         )
155         and strings.ilike(.scan.ocr.raw,
156                           "*terminated*",
157                           "*review*",
158                           "*expire*",
159                           "*click*",
160                           "*view*",
161                           "*exceed*",
162                           "*clear*",
163                           "*only works*",
164                           "*failed*",
165                           "*deleted*",
166                           "*revalidated"
167         )
168     )
169   )
170   or (
171     any(ml.nlu_classifier(body.current_thread.text).intents,
172         .name == "cred_theft" and .confidence in~ ("medium", "high")
173     )
174     or any(attachments,
175            .file_type in $file_types_images
176            and any(file.explode(.),
177                    any(ml.nlu_classifier(.scan.ocr.raw).intents,
178                        .name == "cred_theft"
179                        and .confidence in ("medium", "high")
180                    )
181            )
182     )
183   )
184 )
185 and sender.email.domain.root_domain not in (
186   "bing.com",
187   "microsoft.com",
188   "microsoftonline.com",
189   "microsoftstoreemail.com",
190   "microsoftsupport.com",
191   "microsoft365.com",
192   "office.com",
193   "onedrive.com",
194   "sharepointonline.com",
195   "yammer.com"
196 )
197 
198 // negate highly trusted sender domains unless they fail DMARC authentication
199 and (
200   (
201     sender.email.domain.root_domain in $high_trust_sender_root_domains
202     and (
203       any(distinct(headers.hops, .authentication_results.dmarc is not null),
204           strings.ilike(.authentication_results.dmarc, "*fail")
205       )
206     )
207   )
208   or sender.email.domain.root_domain not in $high_trust_sender_root_domains
209 )
210 and (
211   not profile.by_sender().solicited
212   or (
213     profile.by_sender().any_messages_malicious_or_spam
214     and not profile.by_sender().any_false_positives
215   )
216 )
217 and not profile.by_sender().any_false_positives
218 
219 // exclude marketing jargen from ms partners
220 and not regex.icontains(body.current_thread.text,
221                         'schedul(e|ing).{0,10}(call|meeting|demo|zoom|conversation|time|tool)|book.{0,10}(meeting|demo|call|slot|time)|connect.{0,12}(with me|phone|email)|my.{0,10}(calendar|cal)|reserve.{0,10}s[pl]ot|break the ice|want to know more?|miss your chance|if you no longer wish|low-code (development|approach|solution|journey|platform)'
222 )
223  
224attack_types:
225  - "Credential Phishing"
226tactics_and_techniques:
227  - "Free file host"
228  - "Image as content"
229  - "Impersonation: Brand"
230  - "Social engineering"
231detection_methods:
232  - "Computer Vision"
233  - "Content analysis"
234  - "File analysis"
235  - "Header analysis"
236  - "Natural Language Understanding"
237  - "Optical Character Recognition"
238  - "Sender analysis"
239  - "URL analysis"
240id: "b59201b6-f253-55a6-9c0a-e1500a32a751"
to-top