Brand impersonation: Microsoft Planner with suspicious link

Impersonation of Microsoft Planner, a component of the Microsoft 365 software suite.

Sublime rule (View on GitHub)

  1name: "Brand impersonation: Microsoft Planner with suspicious link"
  2description: "Impersonation of Microsoft Planner, a component of the Microsoft 365 software suite."
  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 .href_url.domain.domain in $social_landing_hosts
 16             or .href_url.domain.root_domain in $social_landing_hosts
 17   
 18             // mass mailer link, masks the actual URL
 19             or .href_url.domain.root_domain in (
 20               "hubspotlinks.com",
 21               "mandrillapp.com",
 22               "sendgrid.net",
 23               "rs6.net"
 24             )
 25   
 26             // Google AMP redirect
 27             or (
 28               .href_url.domain.sld == "google"
 29               and strings.starts_with(.href_url.path, "/amp/")
 30             )
 31   
 32             // Recipient email address in link
 33             or any(recipients.to,
 34                    strings.icontains(..href_url.url, .email.email)
 35                    and .email.domain.valid
 36             )
 37             or .href_url.domain.root_domain == "beehiiv.com"
 38           )
 39   
 40           // exclude sources of potential FPs
 41           and (
 42             .href_url.domain.root_domain not in (
 43               "svc.ms",
 44               "sharepoint.com",
 45               "1drv.ms",
 46               "microsoft.com",
 47               "aka.ms",
 48               "msftauthimages.net",
 49               "mimecastprotect.com",
 50               "office.com",
 51               "microsoftproject.com"
 52             )
 53             or any(body.links, .href_url.domain.domain in $free_file_hosts)
 54           )
 55           and .href_url.domain.root_domain not in $org_domains
 56           and .href_url.domain.valid
 57           and regex.icontains(.display_text,
 58                               "(?:go.?to|view|show|display|access|open.?in|review.?on) (teams?|planner|group|task|intranet|discussions?)"
 59           )
 60   )
 61   
 62   // not a reply
 63   and (length(headers.references) == 0 or headers.in_reply_to is null)
 64   
 65   // Planner logo
 66   // LogoDetect coming soon
 67   and (
 68     all(attachments,
 69         .file_type in $file_types_images
 70         and 
 71         // small, relatively square image
 72         //
 73         // This rule makes use of a beta feature and is subject to change without notice
 74         // using the beta feature in custom rules is not suggested until it has been formally released
 75         //
 76         (
 77           beta.parse_exif(.).image_height / beta.parse_exif(.).image_width
 78         ) > 0.9
 79         and (beta.parse_exif(.).image_height + beta.parse_exif(.).image_width) < 500
 80     )
 81   )
 82   
 83   // suspicious content
 84   and (
 85     2 of (
 86       strings.ilike(body.current_thread.text, "*assigned*new team*"),
 87       strings.ilike(body.current_thread.text, "*Microsoft Office 365*"),
 88       strings.ilike(body.current_thread.text, "*internal planner*"),
 89       strings.ilike(body.current_thread.text, "*internal task*"),
 90       any(recipients.to,
 91           strings.icontains(body.current_thread.text, .email.domain.sld)
 92       )
 93     )
 94     or (
 95       any(ml.nlu_classifier(body.current_thread.text).intents,
 96           .name == "cred_theft" and .confidence in~ ("medium", "high")
 97       )
 98     )
 99     // multiple links, but all the same root domain
100     or (
101       length(distinct(body.links, .href_url.domain.root_domain)) == 1
102       and 2 < length(body.links) < 10
103       and all(body.links,
104               .href_url.domain.root_domain != sender.email.domain.root_domain
105       )
106     )
107   )
108   // skip senders 
109   and not (
110     headers.auth_summary.dmarc.pass
111     and sender.email.domain.root_domain in (
112       "bing.com",
113       "microsoft.com",
114       "microsoftonline.com",
115       "microsoftproject.com",
116       "microsoftstoreemail.com",
117       "microsoftsupport.com",
118       "microsoft365.com",
119       "office.com",
120       "office365.com",
121       "onedrive.com",
122       "sharepointonline.com",
123       "yammer.com",
124       "outlign.co"
125     )
126   )
127   
128   // negate highly trusted sender domains unless they fail DMARC authentication
129   and (
130     (
131       sender.email.domain.root_domain in $high_trust_sender_root_domains
132       and not headers.auth_summary.dmarc.pass
133     )
134     or sender.email.domain.root_domain not in $high_trust_sender_root_domains
135   )
136   and (
137     not profile.by_sender().solicited
138     or (
139       profile.by_sender().any_messages_malicious_or_spam
140       and not profile.by_sender().any_messages_benign
141     )
142   )
143   and not profile.by_sender().any_messages_benign
144   
145   // exclude marketing jargon from ms partners
146   and not regex.icontains(body.current_thread.text,
147                           '(schedul(e|ing)|set up).{0,20}(call|meeting|demo|zoom|conversation|time|tool|discussion)|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|if you no longer want|if you wish to opt out|low-code (development|approach|solution|journey|platform)|invite.{0,30}(webinar|presentation)'
148   )   
149attack_types:
150  - "Credential Phishing"
151tactics_and_techniques:
152  - "Evasion"
153  - "Image as content"
154  - "Impersonation: Brand"
155  - "Social engineering"
156detection_methods:
157  - "Content analysis"
158  - "Header analysis"
159  - "Natural Language Understanding"
160  - "Sender analysis"
161  - "URL analysis"
162id: "ea363c08-479f-5437-9b5d-3d9e07098200"
to-top