EXPLORE
← Back to Explore
sublimemediumRule

Brand impersonation: Microsoft Planner with suspicious link

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

MITRE ATT&CK

defense-evasioninitial-access

Detection Query

type.inbound
// suspicious link
and any(body.links,
        (
          .href_url.domain.root_domain not in $tranco_1m
          or .href_url.domain.domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_file_hosts
          or .href_url.domain.root_domain in $free_subdomain_hosts
          or .href_url.domain.domain in $url_shorteners
          or .href_url.domain.domain in $social_landing_hosts
          or .href_url.domain.root_domain in $social_landing_hosts

          // mass mailer link, masks the actual URL
          or .href_url.domain.root_domain in (
            "hubspotlinks.com",
            "mandrillapp.com",
            "sendgrid.net",
            "rs6.net"
          )

          // Google AMP redirect
          or (
            .href_url.domain.sld == "google"
            and strings.starts_with(.href_url.path, "/amp/")
          )

          // Recipient email address in link
          or any(recipients.to,
                 strings.icontains(..href_url.url, .email.email)
                 and .email.domain.valid
          )
          or .href_url.domain.root_domain == "beehiiv.com"
        )

        // exclude sources of potential FPs
        and (
          .href_url.domain.root_domain not in (
            "svc.ms",
            "sharepoint.com",
            "1drv.ms",
            "microsoft.com",
            "aka.ms",
            "msftauthimages.net",
            "mimecastprotect.com",
            "office.com",
            "microsoftproject.com"
          )
          or any(body.links, .href_url.domain.domain in $free_file_hosts)
        )
        and .href_url.domain.root_domain not in $org_domains
        and .href_url.domain.valid
        and regex.icontains(.display_text,
                            "(?:go.?to|view|show|display|access|open.?in|review.?on) (teams?|planner|group|task|intranet|discussions?)"
        )
)

// not a reply
and (length(headers.references) == 0 or headers.in_reply_to is null)

// Planner logo
// LogoDetect coming soon
and (
  all(attachments,
      .file_type in $file_types_images
      and 
      // small, relatively square image
      //
      // This rule makes use of a beta feature and is subject to change without notice
      // using the beta feature in custom rules is not suggested until it has been formally released
      //
      (
        beta.parse_exif(.).image_height / beta.parse_exif(.).image_width
      ) > 0.9
      and (beta.parse_exif(.).image_height + beta.parse_exif(.).image_width) < 500
  )
)

// suspicious content
and (
  2 of (
    strings.ilike(body.current_thread.text, "*assigned*new team*"),
    strings.ilike(body.current_thread.text, "*Microsoft Office 365*"),
    strings.ilike(body.current_thread.text, "*internal planner*"),
    strings.ilike(body.current_thread.text, "*internal task*"),
    any(recipients.to,
        strings.icontains(body.current_thread.text, .email.domain.sld)
    )
  )
  or (
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence in~ ("medium", "high")
    )
  )
  // multiple links, but all the same root domain
  or (
    length(distinct(body.links, .href_url.domain.root_domain)) == 1
    and 2 < length(body.links) < 10
    and all(body.links,
            .href_url.domain.root_domain != sender.email.domain.root_domain
    )
  )
)
// skip senders 
and not (
  headers.auth_summary.dmarc.pass
  and sender.email.domain.root_domain in (
    "bing.com",
    "microsoft.com",
    "microsoftonline.com",
    "microsoftproject.com",
    "microsoftstoreemail.com",
    "microsoftsupport.com",
    "microsoft365.com",
    "office.com",
    "office365.com",
    "onedrive.com",
    "sharepointonline.com",
    "yammer.com",
    "outlign.co"
  )
)

// negate highly trusted sender domains unless they fail DMARC authentication
and (
  (
    sender.email.domain.root_domain in $high_trust_sender_root_domains
    and not headers.auth_summary.dmarc.pass
  )
  or sender.email.domain.root_domain not in $high_trust_sender_root_domains
)
and (
  not profile.by_sender().solicited
  or (
    profile.by_sender().any_messages_malicious_or_spam
    and not profile.by_sender().any_messages_benign
  )
)
and not profile.by_sender().any_messages_benign

// exclude marketing jargon from ms partners
and not regex.icontains(body.current_thread.text,
                        '(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)'
)

Data Sources

Email MessagesEmail HeadersEmail Attachments

Platforms

email
Raw Content
name: "Brand impersonation: Microsoft Planner with suspicious link"
description: "Impersonation of Microsoft Planner, a component of the Microsoft 365 software suite."
type: "rule"
severity: "medium"
source: |
   type.inbound
   // suspicious link
   and any(body.links,
           (
             .href_url.domain.root_domain not in $tranco_1m
             or .href_url.domain.domain in $free_file_hosts
             or .href_url.domain.root_domain in $free_file_hosts
             or .href_url.domain.root_domain in $free_subdomain_hosts
             or .href_url.domain.domain in $url_shorteners
             or .href_url.domain.domain in $social_landing_hosts
             or .href_url.domain.root_domain in $social_landing_hosts
   
             // mass mailer link, masks the actual URL
             or .href_url.domain.root_domain in (
               "hubspotlinks.com",
               "mandrillapp.com",
               "sendgrid.net",
               "rs6.net"
             )
   
             // Google AMP redirect
             or (
               .href_url.domain.sld == "google"
               and strings.starts_with(.href_url.path, "/amp/")
             )
   
             // Recipient email address in link
             or any(recipients.to,
                    strings.icontains(..href_url.url, .email.email)
                    and .email.domain.valid
             )
             or .href_url.domain.root_domain == "beehiiv.com"
           )
   
           // exclude sources of potential FPs
           and (
             .href_url.domain.root_domain not in (
               "svc.ms",
               "sharepoint.com",
               "1drv.ms",
               "microsoft.com",
               "aka.ms",
               "msftauthimages.net",
               "mimecastprotect.com",
               "office.com",
               "microsoftproject.com"
             )
             or any(body.links, .href_url.domain.domain in $free_file_hosts)
           )
           and .href_url.domain.root_domain not in $org_domains
           and .href_url.domain.valid
           and regex.icontains(.display_text,
                               "(?:go.?to|view|show|display|access|open.?in|review.?on) (teams?|planner|group|task|intranet|discussions?)"
           )
   )
   
   // not a reply
   and (length(headers.references) == 0 or headers.in_reply_to is null)
   
   // Planner logo
   // LogoDetect coming soon
   and (
     all(attachments,
         .file_type in $file_types_images
         and 
         // small, relatively square image
         //
         // This rule makes use of a beta feature and is subject to change without notice
         // using the beta feature in custom rules is not suggested until it has been formally released
         //
         (
           beta.parse_exif(.).image_height / beta.parse_exif(.).image_width
         ) > 0.9
         and (beta.parse_exif(.).image_height + beta.parse_exif(.).image_width) < 500
     )
   )
   
   // suspicious content
   and (
     2 of (
       strings.ilike(body.current_thread.text, "*assigned*new team*"),
       strings.ilike(body.current_thread.text, "*Microsoft Office 365*"),
       strings.ilike(body.current_thread.text, "*internal planner*"),
       strings.ilike(body.current_thread.text, "*internal task*"),
       any(recipients.to,
           strings.icontains(body.current_thread.text, .email.domain.sld)
       )
     )
     or (
       any(ml.nlu_classifier(body.current_thread.text).intents,
           .name == "cred_theft" and .confidence in~ ("medium", "high")
       )
     )
     // multiple links, but all the same root domain
     or (
       length(distinct(body.links, .href_url.domain.root_domain)) == 1
       and 2 < length(body.links) < 10
       and all(body.links,
               .href_url.domain.root_domain != sender.email.domain.root_domain
       )
     )
   )
   // skip senders 
   and not (
     headers.auth_summary.dmarc.pass
     and sender.email.domain.root_domain in (
       "bing.com",
       "microsoft.com",
       "microsoftonline.com",
       "microsoftproject.com",
       "microsoftstoreemail.com",
       "microsoftsupport.com",
       "microsoft365.com",
       "office.com",
       "office365.com",
       "onedrive.com",
       "sharepointonline.com",
       "yammer.com",
       "outlign.co"
     )
   )
   
   // negate highly trusted sender domains unless they fail DMARC authentication
   and (
     (
       sender.email.domain.root_domain in $high_trust_sender_root_domains
       and not headers.auth_summary.dmarc.pass
     )
     or sender.email.domain.root_domain not in $high_trust_sender_root_domains
   )
   and (
     not profile.by_sender().solicited
     or (
       profile.by_sender().any_messages_malicious_or_spam
       and not profile.by_sender().any_messages_benign
     )
   )
   and not profile.by_sender().any_messages_benign
   
   // exclude marketing jargon from ms partners
   and not regex.icontains(body.current_thread.text,
                           '(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)'
   )
attack_types:
  - "Credential Phishing"
tactics_and_techniques:
  - "Evasion"
  - "Image as content"
  - "Impersonation: Brand"
  - "Social engineering"
detection_methods:
  - "Content analysis"
  - "Header analysis"
  - "Natural Language Understanding"
  - "Sender analysis"
  - "URL analysis"
id: "ea363c08-479f-5437-9b5d-3d9e07098200"