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 (length(headers.references) == 0 or headers.in_reply_to is null)
 67   
 68   // Planner logo
 69   // LogoDetect coming soon
 70   and (
 71     all(attachments,
 72         .file_type in $file_types_images
 73         and any(file.explode(.),
 74                 // small, relatively square image
 75                 (
 76                   .scan.exiftool.image_height / .scan.exiftool.image_width
 77                 ) > 0.9
 78                 and (.scan.exiftool.image_height + .scan.exiftool.image_width) < 500
 79         )
 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   and sender.email.domain.root_domain not in (
109     "bing.com",
110     "microsoft.com",
111     "microsoftonline.com",
112     "microsoftproject.com",
113     "microsoftstoreemail.com",
114     "microsoftsupport.com",
115     "microsoft365.com",
116     "office.com",
117     "office365.com",
118     "onedrive.com",
119     "sharepointonline.com",
120     "yammer.com",
121   )
122   
123   // negate highly trusted sender domains unless they fail DMARC authentication
124   and (
125     (
126       sender.email.domain.root_domain in $high_trust_sender_root_domains
127       and not headers.auth_summary.dmarc.pass
128     )
129     or sender.email.domain.root_domain not in $high_trust_sender_root_domains
130   )
131   and (
132     not profile.by_sender().solicited
133     or (
134       profile.by_sender().any_messages_malicious_or_spam
135       and not profile.by_sender().any_messages_benign
136     )
137   )
138   and not profile.by_sender().any_messages_benign
139   
140   // exclude marketing jargon from ms partners
141   and not regex.icontains(body.current_thread.text,
142                           '(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)'
143   )   
144attack_types:
145  - "Credential Phishing"
146tactics_and_techniques:
147  - "Evasion"
148  - "Image as content"
149  - "Impersonation: Brand"
150  - "Social engineering"
151detection_methods:
152  - "Content analysis"
153  - "Header analysis"
154  - "Natural Language Understanding"
155  - "Sender analysis"
156  - "URL analysis"
157id: "ea363c08-479f-5437-9b5d-3d9e07098200"
to-top