Detection rules › Sublime MQL

Link: Uncommon SharePoint document type with sender's display name

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

Detects SharePoint file shares containing personal OneNote or PDF files where the file name matches the sender's display name.

Threat classification

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

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSocial engineering, OneNote, PDF

Event coverage

Rule body MQL

type.inbound

// Matches the message id observed. DKIM/SPF domains can be custom and therefore are unpredictable.
and (
  (
    strings.starts_with(headers.message_id, '<Share-')
    and strings.ends_with(headers.message_id, '@odspnotify>')
  )
  or (
    any(headers.hops,
        any(.fields,
            .name == "X-Google-Original-Message-ID"
            and strings.starts_with(.value, '<Share-')
            and strings.ends_with(.value, '@odspnotify>')
        )
    )
  )
)

// SharePoint email indicators
and strings.like(body.current_thread.text,
                 "*shared a file with you*",
                 "*shared with you*",
                 "*invited you to access a file*"
)
and strings.icontains(subject.subject, "shared")

// file name is the sender's name
and any(html.xpath(body.html,
                   '//table[@role="presentation"]//tr[last()]//text()'
        ).nodes,
        .display_text =~ sender.display_name
)

// link logic
and any(body.links,
        .href_url.domain.root_domain == "sharepoint.com"
        // it is a personal share
        and (
          // /g/ is only found with /personal
          strings.icontains(.href_url.path, '/g/personal/')
          or strings.icontains(.href_url.path, '/p/')
        )
        // it is either a OneNote or PDF
        and (
          strings.icontains(.href_url.path, '/:o:/')
          or strings.icontains(.href_url.path, '/:b:/')
          or strings.icontains(.href_url.path, '/:u:/')
        )
)

Detection logic

Scope: inbound message.

Detects SharePoint file shares containing personal OneNote or PDF files where the file name matches the sender's display name.

  1. inbound message
  2. any of:
    • all of:
      • headers.message_id starts with '<Share-'
      • headers.message_id ends with '@odspnotify>'
    • any of headers.hops where:
      • any of .fields where all hold:
        • .name is 'X-Google-Original-Message-ID'
        • .value starts with '<Share-'
        • .value ends with '@odspnotify>'
  3. body.current_thread.text matches any of 3 patterns
    • *shared a file with you*
    • *shared with you*
    • *invited you to access a file*
  4. subject.subject contains 'shared'
  5. any of html.xpath(body.html, '//table[@role="presentation"]//tr[last()]//text()').nodes where:
    • .display_text is sender.display_name
  6. any of body.links where all hold:
    • .href_url.domain.root_domain is 'sharepoint.com'
    • any of:
      • .href_url.path contains '/g/personal/'
      • .href_url.path contains '/p/'
    • any of:
      • .href_url.path contains '/:o:/'
      • .href_url.path contains '/:b:/'
      • .href_url.path contains '/:u:/'

Inspects: body.current_thread.text, body.html, body.links, body.links[].href_url.domain.root_domain, body.links[].href_url.path, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.message_id, sender.display_name, subject.subject, type.inbound. Sensors: html.xpath, strings.ends_with, strings.icontains, strings.like, strings.starts_with.

Indicators matched (13)

FieldMatchValue
strings.starts_withprefix<Share-
strings.ends_withsuffix@odspnotify>
headers.hops[].fields[].nameequalsX-Google-Original-Message-ID
strings.likesubstring*shared a file with you*
strings.likesubstring*shared with you*
strings.likesubstring*invited you to access a file*
strings.icontainssubstringshared
body.links[].href_url.domain.root_domainequalssharepoint.com
strings.icontainssubstring/g/personal/
strings.icontainssubstring/p/
strings.icontainssubstring/:o:/
strings.icontainssubstring/:b:/
1 more
strings.icontainssubstring/:u:/