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             or 
 18   
 19             // mass mailer link, masks the actual URL
 20             .href_url.domain.root_domain in (
 21               "hubspotlinks.com",
 22               "mandrillapp.com",
 23               "sendgrid.net",
 24               "rs6.net"
 25             )
 26   
 27             // Google AMP redirect
 28             or (
 29               .href_url.domain.sld == "google"
 30               and strings.starts_with(.href_url.path, "/amp/")
 31             )
 32   
 33             // Recipient email address in link
 34             or any(body.links,
 35                    any(recipients.to,
 36                        strings.icontains(..href_url.url, .email.email)
 37                        and any(recipients.to, .email.domain.valid)
 38                    )
 39             )
 40             or .href_url.domain.root_domain == "beehiiv.com"
 41           )
 42   
 43           // exclude sources of potential FPs
 44           and (
 45             .href_url.domain.root_domain not in (
 46               "svc.ms",
 47               "sharepoint.com",
 48               "1drv.ms",
 49               "microsoft.com",
 50               "aka.ms",
 51               "msftauthimages.net",
 52               "mimecastprotect.com",
 53               "office.com",
 54               "microsoftproject.com"
 55             )
 56             or any(body.links, .href_url.domain.domain in $free_file_hosts)
 57           )
 58           and .href_url.domain.root_domain not in $org_domains
 59           and .href_url.domain.valid
 60           and regex.icontains(.display_text,
 61                               "(?:go.?to|view|show|display|access|open.?in|review.?on) (teams?|planner|group|task|intranet|discussions?)"
 62           )
 63   )
 64   
 65   // not a reply
 66   and (
 67     length(headers.references) == 0
 68     or not any(headers.hops, any(.fields, strings.ilike(.name, "In-Reply-To")))
 69   )
 70   
 71   // Planner logo
 72   // LogoDetect coming soon
 73   and (
 74     all(attachments,
 75         .file_type in $file_types_images
 76         and any(file.explode(.),
 77                 // small, relatively square image
 78                 (
 79                   .scan.exiftool.image_height / .scan.exiftool.image_width
 80                 ) > 0.9
 81                 and (.scan.exiftool.image_height + .scan.exiftool.image_width) < 500
 82         )
 83     )
 84   )
 85   
 86   // suspicious content
 87   and (
 88     2 of (
 89       strings.ilike(body.current_thread.text, "*assigned*new team*"),
 90       strings.ilike(body.current_thread.text, "*Microsoft Office 365*"),
 91       strings.ilike(body.current_thread.text, "*internal planner*"),
 92       strings.ilike(body.current_thread.text, "*internal task*"),
 93       any(recipients.to,
 94           strings.icontains(body.current_thread.text, .email.domain.sld)
 95       )
 96     )
 97     or (
 98       any(ml.nlu_classifier(body.current_thread.text).intents,
 99           .name == "cred_theft" and .confidence in~ ("medium", "high")
100       )
101     )
102     // multiple links, but all the same root domain
103     or (
104       length(distinct(body.links, .href_url.domain.root_domain)) == 1
105       and 2 < length(body.links) < 10
106       and all(body.links,
107               .href_url.domain.root_domain != sender.email.domain.root_domain
108       )
109     )
110   )
111   and sender.email.domain.root_domain not 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   )
125   
126   // negate highly trusted sender domains unless they fail DMARC authentication
127   and (
128     (
129       sender.email.domain.root_domain in $high_trust_sender_root_domains
130       and not headers.auth_summary.dmarc.pass
131     )
132     or sender.email.domain.root_domain not in $high_trust_sender_root_domains
133   )
134   and (
135     not profile.by_sender().solicited
136     or (
137       profile.by_sender().any_messages_malicious_or_spam
138       and not profile.by_sender().any_messages_benign
139     )
140   )
141   and not profile.by_sender().any_messages_benign
142   
143   // exclude marketing jargon from ms partners
144   and not regex.icontains(body.current_thread.text,
145                           '(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)'
146   )
147      
148attack_types:
149  - "Credential Phishing"
150tactics_and_techniques:
151  - "Evasion"
152  - "Image as content"
153  - "Impersonation: Brand"
154  - "Social engineering"
155detection_methods:
156  - "Content analysis"
157  - "Header analysis"
158  - "Natural Language Understanding"
159  - "Sender analysis"
160  - "URL analysis"
161id: "ea363c08-479f-5437-9b5d-3d9e07098200"
to-top