Detection rules › Sublime MQL

Credential phishing: Generic document share template

Severity
low
Type
rule
Source
github.com/sublime-security/sublime-rules

Detects messages that incorporate recipient-specific information (email domain, local part, or domain elements) alongside document-themed Unicode symbols and keywords. The rule identifies various targeting patterns including greeting-based personalization, attention-grabbing prefixes and multiple recipient elements. It also catches broken template attacks where recipient placeholders remain visible.

Threat classification

Sublime's own taxonomy (not MITRE ATT&CK).

CategoryValues
Attack typesBEC/Fraud, Credential Phishing
Tactics and techniquesSocial engineering, Evasion

Event coverage

Rule body MQL

type.inbound
and (
  // nlu capture for wide scope of greetings to reduce evasion
  any(filter(ml.nlu_classifier(body.current_thread.text).entities,
             .name == "greeting"
      ),
      any([
            recipients.to[0].email.domain.sld,
            recipients.to[0].email.local_part,
            recipients.to[0].email.domain.domain
          ],
          strings.icontains(body.current_thread.text,
                            strings.concat(..text, " ", .)
          )
      )
  )
  or any([
           recipients.to[0].email.domain.sld,
           recipients.to[0].email.local_part,
           recipients.to[0].email.domain.domain
         ],
         // strings logic for non-greeting body starter
         strings.icontains(body.current_thread.text,
                           strings.concat("attn: ", .)
         )
         // strings logic for recipient as starter
         or strings.icontains(body.current_thread.text,
                              strings.concat(., " balance statement")
         )
  )
  // count of all recipient elements is higher 2 or greater
  or length(filter([
                     recipients.to[0].email.domain.sld,
                     recipients.to[0].email.local_part,
                     recipients.to[0].email.domain.domain
                   ],
                   strings.icontains(body.current_thread.text, .)
            )
  ) >= 2

  // logic for broken attack
  or any(ml.nlu_classifier(body.current_thread.text).entities,
         .name == "recipient" and regex.icontains(.text, '[{}]')
  )
)

// unicode + keyword generic template
and (
  regex.icontains(body.current_thread.text,
                  '(?:\x{270e}|\x{270f}|\x{2710}|\x{270d}|\x{1f589}|\x{1F4C4}|\x{1F4D1}|\x{1F4C1}|\x{1F4EC}).{0,15}(?:document|completion|remit|review|statement|agree|shar(?:ed|ing)|receiv|\bmail\b)',
                  '(?:document|completion|remit|review|statement|agree|shar(?:ed|ing)|receiv|\bmail\b).{0,15}(?:\x{270e}|\x{270f}|\x{2710}|\x{270d}|\x{1f589}|\x{1F4C4}|\x{1F4D1}|\x{1F4C1}|\x{1F4EC})'
  )
  // negate sharepoint paths with unicode
  and not any(body.links,
              regex.icontains(.display_url.path,
                              '(?:\x{270e}|\x{270f}|\x{2710}|\x{270d}|\x{1f589}|\x{1F4C4}|\x{1F4D1}|\x{1F4C1}|\x{1F4EC})'
              )
  )
)

// nlu negation for FP's
and any(ml.nlu_classifier(body.current_thread.text).intents, .name != "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
)

Detection logic

Scope: inbound message.

Detects messages that incorporate recipient-specific information (email domain, local part, or domain elements) alongside document-themed Unicode symbols and keywords. The rule identifies various targeting patterns including greeting-based personalization, attention-grabbing prefixes and multiple recipient elements. It also catches broken template attacks where recipient placeholders remain visible.

  1. inbound message
  2. any of:
    • any of filter(...) where:
      • any of [recipients.to[0].email.domain.sld, recipients.to[0].email.local_part, recipients.to[0].email.domain.domain] where:
        • strings.icontains(body.current_thread.text)
    • any of [recipients.to[0].email.domain.sld, recipients.to[0].email.local_part, recipients.to[0].email.domain.domain] where any holds:
      • strings.icontains(body.current_thread.text)
      • strings.icontains(body.current_thread.text)
    • length(filter([recipients.to[0].email.domain.sld, recipients.to[0].email.local_part, recipients.to[0].email.domain.domain], strings.icontains(body.current_thread.text, .))) ≥ 2
    • any of ml.nlu_classifier(body.current_thread.text).entities where all hold:
      • .name is 'recipient'
      • .text matches '[{}]'
  3. all of:
    • body.current_thread.text matches any of 2 patterns
      • (?:\x{270e}|\x{270f}|\x{2710}|\x{270d}|\x{1f589}|\x{1F4C4}|\x{1F4D1}|\x{1F4C1}|\x{1F4EC}).{0,15}(?:document|completion|remit|review|statement|agree|shar(?:ed|ing)|receiv|\bmail\b)
      • (?:document|completion|remit|review|statement|agree|shar(?:ed|ing)|receiv|\bmail\b).{0,15}(?:\x{270e}|\x{270f}|\x{2710}|\x{270d}|\x{1f589}|\x{1F4C4}|\x{1F4D1}|\x{1F4C1}|\x{1F4EC})
    • not:
      • any of body.links where:
        • .display_url.path matches '(?:\\x{270e}|\\x{270f}|\\x{2710}|\\x{270d}|\\x{1f589}|\\x{1F4C4}|\\x{1F4D1}|\\x{1F4C1}|\\x{1F4EC})'
  4. any of ml.nlu_classifier(body.current_thread.text).intents where:
    • .name is not 'benign'
  5. any of:
    • all of:
      • sender.email.domain.root_domain in $high_trust_sender_root_domains
      • not:
        • headers.auth_summary.dmarc.pass
    • sender.email.domain.root_domain not in $high_trust_sender_root_domains

Inspects: body.current_thread.text, body.links, body.links[].display_url.path, headers.auth_summary.dmarc.pass, recipients.to[0].email.domain.domain, recipients.to[0].email.domain.sld, recipients.to[0].email.local_part, sender.email.domain.root_domain, type.inbound. Sensors: ml.nlu_classifier, regex.icontains, strings.concat, strings.icontains. Reference lists: $high_trust_sender_root_domains.

Indicators matched (6)

FieldMatchValue
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsgreeting
ml.nlu_classifier(body.current_thread.text).entities[].nameequalsrecipient
regex.icontainsregex[{}]
regex.icontainsregex(?:\x{270e}|\x{270f}|\x{2710}|\x{270d}|\x{1f589}|\x{1F4C4}|\x{1F4D1}|\x{1F4C1}|\x{1F4EC}).{0,15}(?:document|completion|remit|review|statement|agree|shar(?:ed|ing)|receiv|\bmail\b)
regex.icontainsregex(?:document|completion|remit|review|statement|agree|shar(?:ed|ing)|receiv|\bmail\b).{0,15}(?:\x{270e}|\x{270f}|\x{2710}|\x{270d}|\x{1f589}|\x{1F4C4}|\x{1F4D1}|\x{1F4C1}|\x{1F4EC})
regex.icontainsregex(?:\x{270e}|\x{270f}|\x{2710}|\x{270d}|\x{1f589}|\x{1F4C4}|\x{1F4D1}|\x{1F4C1}|\x{1F4EC})