Brand impersonation: Sharepoint

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

Sublime rule (View on GitHub)

  1name: "Brand impersonation: Sharepoint"
  2description: |
  3    Body, attached images or pdf contains a Sharepoint logo. The message contains a link and credential theft language.
  4type: "rule"
  5severity: "high"
  6source: |
  7  type.inbound
  8  and length(body.links) > 0
  9  and (
 10    any(attachments,
 11        (.file_type in $file_types_images or .file_type == "pdf")
 12        and any(ml.logo_detect(.).brands, .name == "Microsoft SharePoint")
 13    )
 14    or any(ml.logo_detect(file.message_screenshot()).brands,
 15           .name == "Microsoft SharePoint"
 16    )
 17    or strings.istarts_with(strings.replace_confusables(body.current_thread.text),
 18                            "Sharepoint"
 19    )
 20    or regex.icontains(body.html.raw,
 21                       '<img.*(title=|alt=).share.*src=""'
 22    ) // broken Sharepoint logo
 23  )
 24  and (
 25    (
 26      any(ml.nlu_classifier(body.current_thread.text).intents,
 27          .name == "cred_theft" and .confidence == "high"
 28      )
 29      //
 30      // This rule makes use of a beta feature and is subject to change without notice
 31      // using the beta feature in custom rules is not suggested until it has been formally released
 32      //
 33      or any(ml.nlu_classifier(beta.ocr(file.message_screenshot()).text).intents,
 34             .name == "cred_theft" and .confidence == "high"
 35      )
 36    )
 37    or any(ml.nlu_classifier(body.current_thread.text).entities,
 38           .name == "urgency" and strings.ilike(.text, "*encrypted*")
 39    )
 40    or any(body.links,
 41           regex.imatch(.display_text,
 42                        '(?:re)?view (?:(?:&|and) (?:e([[:punct:]]|\s)?)?sign )?(?:complete )?(?:document|file)'
 43           )
 44    )
 45  )
 46  and not (
 47    (
 48      (
 49        strings.istarts_with(subject.subject, "RE:")
 50        or strings.istarts_with(subject.subject, "R:")
 51        or strings.istarts_with(subject.subject, "ODG:")
 52        or strings.istarts_with(subject.subject, "答复:")
 53        or strings.istarts_with(subject.subject, "AW:")
 54        or strings.istarts_with(subject.subject, "TR:")
 55        or strings.istarts_with(subject.subject, "FWD:")
 56        or regex.imatch(subject.subject, '(\[[^\]]+\]\s?){0,3}(re|fwd?)\s?:')
 57        or regex.imatch(subject.subject,
 58                        '^\[?(EXT|EXTERNAL)\]?[: ]\s*(RE|FWD?|FW|AW|TR|ODG|答复):.*'
 59        )
 60      )
 61      and (
 62        (length(headers.references) > 0 or headers.in_reply_to is not null)
 63        // ensure that there are actual threads
 64        and (
 65          length(body.previous_threads) > 0
 66          or (length(body.html.display_text) - length(body.current_thread.text)) > 200
 67        )
 68      )
 69    )
 70  )
 71  and (
 72    profile.by_sender_email().prevalence != 'common'
 73    or not profile.by_sender_email().solicited
 74    or profile.by_sender().any_messages_malicious_or_spam
 75  )
 76  and not profile.by_sender().any_messages_benign
 77  
 78  // negate highly trusted sender domains unless they fail DMARC authentication
 79  and (
 80    (
 81      sender.email.domain.root_domain in $high_trust_sender_root_domains
 82      and not headers.auth_summary.dmarc.pass
 83    )
 84    or sender.email.domain.root_domain not in $high_trust_sender_root_domains
 85  )
 86  
 87  // negate sharepoint file share
 88  and not (
 89    // based on the message id format
 90    (
 91      (
 92        strings.starts_with(headers.message_id, '<Share-')
 93        and strings.ends_with(headers.message_id, '@odspnotify>')
 94      )
 95      or // negate legitimate access request to file
 96   (
 97        strings.starts_with(headers.message_id, '<Sharing')
 98        and strings.ends_with(headers.message_id, '@odspnotify>')
 99      )
100      // deal with Google thinking the message ID is "broke"
101      or (
102        strings.icontains(headers.message_id, 'SMTPIN_ADDED_BROKEN')
103        and any(headers.hops,
104                any(.fields,
105                    .name == "X-Google-Original-Message-ID"
106                    and strings.starts_with(.value, '<Share-')
107                    and strings.ends_with(.value, '@odspnotify>')
108                )
109        )
110      )
111    )
112    // all of the "action" links are sharepoint/ms
113    and all(filter(body.links,
114                   strings.icontains(subject.subject, .display_text)
115                   or .display_text == "Open"
116            ),
117            .href_url.domain.root_domain in ("sharepoint.com")
118            or (
119              .href_url.domain.tld == "ms"
120              // Microsoft does not own the .ms TLD, this checks to ensure it is one of their domains
121              and (
122                network.whois(.href_url.domain).registrant_company == "Microsoft Corporation"
123                or strings.ilike(network.whois(.href_url.domain).registrar_name,
124                                 "*MarkMonitor*",
125                                 "*CSC Corporate*",
126                                 "*com laude*"
127                )
128              )
129            )
130    )
131  )  
132attack_types:
133  - "Credential Phishing"
134tactics_and_techniques:
135  - "Impersonation: Brand"
136  - "Social engineering"
137detection_methods:
138  - "Computer Vision"
139  - "Content analysis"
140  - "File analysis"
141  - "Natural Language Understanding"
142  - "Sender analysis"
143id: "284b1b70-8daa-5adf-9df8-15d4c6b5ead9"
to-top