EXPLORE
← Back to Explore
sublimehighRule

Brand impersonation: Sharepoint

Body, attached images or pdf contains a Sharepoint logo. The message contains a link and credential theft language.

MITRE ATT&CK

initial-access

Detection Query

type.inbound
and length(body.links) > 0
and (
  any(attachments,
      (.file_type in $file_types_images or .file_type == "pdf")
      and any(ml.logo_detect(.).brands, .name == "Microsoft SharePoint")
  )
  or any(ml.logo_detect(file.message_screenshot()).brands,
         .name == "Microsoft SharePoint"
  )
  or strings.istarts_with(strings.replace_confusables(body.current_thread.text),
                          "Sharepoint"
  )
  or regex.icontains(body.html.raw,
                     '<img.*(title=|alt=).share.*src=""'
  ) // broken Sharepoint logo
  or (
    strings.icontains(strings.replace_confusables(body.plain.raw), "SharePoint")
    // message body references file deletion
    and regex.icontains(body.plain.raw,
                        '(expired )?file\s(was|has been|will be|scheduled (for|to be))\s?delet(ed|ion)'
    )
  )
)
and (
  (
    any(ml.nlu_classifier(body.current_thread.text).intents,
        .name == "cred_theft" and .confidence == "high"
    )
    //
    // 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
    //
    or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
           .name == "cred_theft" and .confidence == "high"
    )
  )
  or any(ml.nlu_classifier(body.current_thread.text).entities,
         .name == "urgency" and strings.ilike(.text, "*encrypted*")
  )
  or any(body.links,
         regex.imatch(.display_text,
                      '(?:re)?view (?:(?:&|and) (?:e([[:punct:]]|\s)?)?sign )?(?:complete )?(?:document|file)'
         )
  )
)
and not (
  (
    (
      strings.istarts_with(subject.subject, "RE:")
      or strings.istarts_with(subject.subject, "R:")
      or strings.istarts_with(subject.subject, "ODG:")
      or strings.istarts_with(subject.subject, "答复:")
      or strings.istarts_with(subject.subject, "AW:")
      or strings.istarts_with(subject.subject, "TR:")
      or strings.istarts_with(subject.subject, "FWD:")
      or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
      or regex.imatch(subject.subject,
                      '^\[?(EXT|EXTERNAL)\]?[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
      )
    )
    and (
      (length(headers.references) > 0 or headers.in_reply_to is not null)
      // ensure that there are actual threads
      and (
        length(body.previous_threads) > 0
        or (length(body.html.display_text) - length(body.current_thread.text)) > 200
      )
    )
  )
)
and (
  profile.by_sender_email().prevalence != 'common'
  or not profile.by_sender_email().solicited
  or profile.by_sender().any_messages_malicious_or_spam
)
and not profile.by_sender().any_messages_benign

// 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
)

// negate sharepoint file share
and not (
  // based on the message id format
  (
    (
      strings.starts_with(headers.message_id, '<Share-')
      and strings.ends_with(headers.message_id, '@odspnotify>')
    )
    or // negate legitimate access request to file
 (
      strings.starts_with(headers.message_id, '<Sharing')
      and strings.ends_with(headers.message_id, '@odspnotify>')
    )
    // deal with Google thinking the message ID is "broke"
    or (
      strings.icontains(headers.message_id, 'SMTPIN_ADDED_BROKEN')
      and any(headers.hops,
              any(.fields,
                  .name == "X-Google-Original-Message-ID"
                  and strings.starts_with(.value, '<Share-')
                  and strings.ends_with(.value, '@odspnotify>')
              )
      )
    )
  )
  // all of the "action" links are sharepoint/ms
  and all(filter(body.links,
                 strings.icontains(subject.subject, .display_text)
                 or .display_text == "Open"
          ),
          .href_url.domain.root_domain in ("sharepoint.com")
          or (
            .href_url.domain.tld == "ms"
            // Microsoft does not own the .ms TLD, this checks to ensure it is one of their domains
            and (
              network.whois(.href_url.domain).registrant_company == "Microsoft Corporation"
              or strings.ilike(network.whois(.href_url.domain).registrar_name,
                               "*MarkMonitor*",
                               "*CSC Corporate*",
                               "*com laude*"
              )
            )
          )
  )
)

Data Sources

Email MessagesEmail HeadersEmail Attachments

Platforms

email
Raw Content
name: "Brand impersonation: Sharepoint"
description: |
  Body, attached images or pdf contains a Sharepoint logo. The message contains a link and credential theft language.
type: "rule"
severity: "high"
source: |
  type.inbound
  and length(body.links) > 0
  and (
    any(attachments,
        (.file_type in $file_types_images or .file_type == "pdf")
        and any(ml.logo_detect(.).brands, .name == "Microsoft SharePoint")
    )
    or any(ml.logo_detect(file.message_screenshot()).brands,
           .name == "Microsoft SharePoint"
    )
    or strings.istarts_with(strings.replace_confusables(body.current_thread.text),
                            "Sharepoint"
    )
    or regex.icontains(body.html.raw,
                       '<img.*(title=|alt=).share.*src=""'
    ) // broken Sharepoint logo
    or (
      strings.icontains(strings.replace_confusables(body.plain.raw), "SharePoint")
      // message body references file deletion
      and regex.icontains(body.plain.raw,
                          '(expired )?file\s(was|has been|will be|scheduled (for|to be))\s?delet(ed|ion)'
      )
    )
  )
  and (
    (
      any(ml.nlu_classifier(body.current_thread.text).intents,
          .name == "cred_theft" and .confidence == "high"
      )
      //
      // 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
      //
      or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
             .name == "cred_theft" and .confidence == "high"
      )
    )
    or any(ml.nlu_classifier(body.current_thread.text).entities,
           .name == "urgency" and strings.ilike(.text, "*encrypted*")
    )
    or any(body.links,
           regex.imatch(.display_text,
                        '(?:re)?view (?:(?:&|and) (?:e([[:punct:]]|\s)?)?sign )?(?:complete )?(?:document|file)'
           )
    )
  )
  and not (
    (
      (
        strings.istarts_with(subject.subject, "RE:")
        or strings.istarts_with(subject.subject, "R:")
        or strings.istarts_with(subject.subject, "ODG:")
        or strings.istarts_with(subject.subject, "答复:")
        or strings.istarts_with(subject.subject, "AW:")
        or strings.istarts_with(subject.subject, "TR:")
        or strings.istarts_with(subject.subject, "FWD:")
        or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
        or regex.imatch(subject.subject,
                        '^\[?(EXT|EXTERNAL)\]?[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
        )
      )
      and (
        (length(headers.references) > 0 or headers.in_reply_to is not null)
        // ensure that there are actual threads
        and (
          length(body.previous_threads) > 0
          or (length(body.html.display_text) - length(body.current_thread.text)) > 200
        )
      )
    )
  )
  and (
    profile.by_sender_email().prevalence != 'common'
    or not profile.by_sender_email().solicited
    or profile.by_sender().any_messages_malicious_or_spam
  )
  and not profile.by_sender().any_messages_benign
  
  // 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
  )
  
  // negate sharepoint file share
  and not (
    // based on the message id format
    (
      (
        strings.starts_with(headers.message_id, '<Share-')
        and strings.ends_with(headers.message_id, '@odspnotify>')
      )
      or // negate legitimate access request to file
   (
        strings.starts_with(headers.message_id, '<Sharing')
        and strings.ends_with(headers.message_id, '@odspnotify>')
      )
      // deal with Google thinking the message ID is "broke"
      or (
        strings.icontains(headers.message_id, 'SMTPIN_ADDED_BROKEN')
        and any(headers.hops,
                any(.fields,
                    .name == "X-Google-Original-Message-ID"
                    and strings.starts_with(.value, '<Share-')
                    and strings.ends_with(.value, '@odspnotify>')
                )
        )
      )
    )
    // all of the "action" links are sharepoint/ms
    and all(filter(body.links,
                   strings.icontains(subject.subject, .display_text)
                   or .display_text == "Open"
            ),
            .href_url.domain.root_domain in ("sharepoint.com")
            or (
              .href_url.domain.tld == "ms"
              // Microsoft does not own the .ms TLD, this checks to ensure it is one of their domains
              and (
                network.whois(.href_url.domain).registrant_company == "Microsoft Corporation"
                or strings.ilike(network.whois(.href_url.domain).registrar_name,
                                 "*MarkMonitor*",
                                 "*CSC Corporate*",
                                 "*com laude*"
                )
              )
            )
    )
  )
attack_types:
  - "Credential Phishing"
tactics_and_techniques:
  - "Impersonation: Brand"
  - "Social engineering"
detection_methods:
  - "Computer Vision"
  - "Content analysis"
  - "File analysis"
  - "Natural Language Understanding"
  - "Sender analysis"
id: "284b1b70-8daa-5adf-9df8-15d4c6b5ead9"