Detection rules › Sublime MQL
Sublime MQL rules: sharepoint
| Rule | Severity |
|---|---|
| Service abuse: File sharing impersonation with external SharePoint links | medium |
| SharePoint OTP for filename matching org name | medium |
Service abuse: File sharing impersonation with external SharePoint links
#- Severity
medium- Type
rule- Source
- github.com/sublime-security/sublime-rules
Detects inbound messages claiming to share files or invite access, containing SharePoint or OneDrive links from external domains. The rule identifies suspicious sharing notifications where link display text matches the sender's name rather than a legitimate document name, indicating potential impersonation of legitimate file sharing services.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
bodybody.current_threadsubjecttype
Rule body
type.inbound
and strings.ilike(subject.subject, "*shared*", "*invit*")
and strings.ilike(body.current_thread.text,
"*shared a file with you*",
"*shared with you*",
"*invited you to access a file*"
)
and not strings.ilike(body.current_thread.text, "invited you to edit")
and (
any(filter(body.current_thread.links,
.href_url.domain.domain not in $tenant_domains
and (
.href_url.domain.root_domain == "sharepoint.com"
or .href_url.domain.root_domain == "1drv.ms"
or (
.href_url.domain.root_domain == 'mimecastprotect.com'
and strings.icontains(.href_url.query_params,
'.sharepoint.com'
)
)
)
and .display_text != "Open"
),
// check if the display_text exactly matches the sender's display name
.display_text == sender.display_name
)
)
Detection logic
Scope: inbound message.
Detects inbound messages claiming to share files or invite access, containing SharePoint or OneDrive links from external domains. The rule identifies suspicious sharing notifications where link display text matches the sender's name rather than a legitimate document name, indicating potential impersonation of legitimate file sharing services.
- inbound message
subject.subject matches any of 2 patterns
*shared**invit*
body.current_thread.text matches any of 3 patterns
*shared a file with you**shared with you**invited you to access a file*
not:
- body.current_thread.text matches 'invited you to edit'
any of
filter(body.current_thread.links)where:- .display_text is sender.display_name
Inspects: body.current_thread.links, body.current_thread.links[].display_text, body.current_thread.links[].href_url.domain.domain, body.current_thread.links[].href_url.domain.root_domain, body.current_thread.links[].href_url.query_params, body.current_thread.text, sender.display_name, subject.subject, type.inbound. Sensors: strings.icontains, strings.ilike. Reference lists: $tenant_domains.
Indicators matched (9)
| Field | Match | Value |
|---|---|---|
strings.ilike | substring | *shared* |
strings.ilike | substring | *invit* |
strings.ilike | substring | *shared a file with you* |
strings.ilike | substring | *shared with you* |
strings.ilike | substring | *invited you to access a file* |
body.current_thread.links[].href_url.domain.root_domain | equals | sharepoint.com |
body.current_thread.links[].href_url.domain.root_domain | equals | 1drv.ms |
body.current_thread.links[].href_url.domain.root_domain | equals | mimecastprotect.com |
strings.icontains | substring | .sharepoint.com |
Stages and Predicates
Stage 1: mql_rule
and
not
body.current_thread.text eq "invited you to edit"
or
body.current_thread.text match "invited you to access a file"
body.current_thread.text match "shared a file with you"
body.current_thread.text match "shared with you"
any(filter(body.current_thread.links))
filter(body.current_thread.links).display_text cross_field_compare "sender.display_name"
or
subject.subject match "invit"
subject.subject match "shared"
type.inbound eq "true"Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
body.current_thread.text | eq | invited you to edit | excludes:body.current_thread.text field:"body.current_thread.text" value:"invited you to edit" |
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | wildcard |
| field:"body.current_thread.text" kind:wildcard |
subject.subject | wildcard |
| field:"subject.subject" kind:wildcard |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
SharePoint OTP for filename matching org name
#- Severity
medium- Type
rule- Source
- github.com/sublime-security/sublime-rules
Detects Microsoft One-Time Passcode (OTP) messages where the shared document’s filename matches the sending organization's name. This typically indicates the recipient has verified their email address and is about to access a SharePoint file. Matching the document name to the sender's org is a pattern observed in multi-stage credential phishing campaigns, where attackers use branded file names to increase credibility and lure users into interacting with malicious content.
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Impersonation: Brand, Social engineering |
Telemetry coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message attributes
bodybody.current_threadheadersheaders.hopssender.emailtype
Rule body
type.inbound
// Microsoft sender
and sender.email.domain.root_domain == "microsoft.com"
// message ID contains the proper format for OTP messeges
and (
(
strings.istarts_with(headers.message_id, '<OneTimePasscode-')
and strings.iends_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.istarts_with(.value, '<OneTimePasscode-')
and strings.iends_with(.value, '@odspnotify>')
)
)
)
)
// make sure the body has the phrase we need to get the document name
and strings.icontains(body.current_thread.text,
'For security purposes, you must enter the code below to verify your account to access'
)
// extract the filename and org name from the body and see if they are equal
and any(regex.iextract(body.current_thread.text,
'For security purposes, you must enter the code below to verify your account to access (?P<doc_name>.*)\. The code will only work for.*This email is generated through (?P<org_name>.*)''s use of Microsoft 365\.'
),
.named_groups["doc_name"] =~ .named_groups["org_name"]
)
Detection logic
Scope: inbound message.
Detects Microsoft One-Time Passcode (OTP) messages where the shared document’s filename matches the sending organization's name. This typically indicates the recipient has verified their email address and is about to access a SharePoint file. Matching the document name to the sender's org is a pattern observed in multi-stage credential phishing campaigns, where attackers use branded file names to increase credibility and lure users into interacting with malicious content.
- inbound message
- sender.email.domain.root_domain is 'microsoft.com'
any of:
all of:
- headers.message_id starts with '<OneTimePasscode-'
- headers.message_id ends with '@odspnotify>'
all of:
- headers.message_id contains 'SMTPIN_ADDED_BROKEN'
any of
headers.hopswhere:any of
.fieldswhere all hold:- .name is 'X-Google-Original-Message-ID'
- .value starts with '<OneTimePasscode-'
- .value ends with '@odspnotify>'
- body.current_thread.text contains 'For security purposes, you must enter the code below to verify your account to access'
any of
regex.iextract(body.current_thread.text)where:- .named_groups['doc_name'] is .named_groups['org_name']
Inspects: body.current_thread.text, headers.hops, headers.hops[].fields, headers.hops[].fields[].name, headers.hops[].fields[].value, headers.message_id, sender.email.domain.root_domain, type.inbound. Sensors: regex.iextract, strings.icontains, strings.iends_with, strings.istarts_with.
Indicators matched (7)
| Field | Match | Value |
|---|---|---|
sender.email.domain.root_domain | equals | microsoft.com |
strings.istarts_with | prefix | <OneTimePasscode- |
strings.iends_with | suffix | @odspnotify> |
strings.icontains | substring | SMTPIN_ADDED_BROKEN |
headers.hops[].fields[].name | equals | X-Google-Original-Message-ID |
strings.icontains | substring | For security purposes, you must enter the code below to verify your account to access |
regex.iextract | regex | For security purposes, you must enter the code below to verify your account to access (?P<doc_name>.*)\. The code will only work for.*This email is generated through (?P<org_name>.*)'s use of Microsoft 365\. |
Stages and Predicates
Stage 1: mql_rule
and
or
and
any(headers.hops)
any(headers.hops.fields)
and
headers.hops.fields[].name eq "X-Google-Original-Message-ID"
headers.hops.fields[].value ends_with "@odspnotify>"
headers.hops.fields[].value starts_with "<OneTimePasscode-"
headers.message_id contains "SMTPIN_ADDED_BROKEN"
and
headers.message_id ends_with "@odspnotify>"
headers.message_id starts_with "<OneTimePasscode-"
any(regex.iextract(body.current_thread.text))
regex.iextract(body.current_thread.text).named_groups['doc_name'] cross_field_compare "regex.iextract(body.current_thread.text).named_groups['org_name']"
body.current_thread.text contains "For security purposes, you must enter the code below to verify your account to access"
sender.email.domain.root_domain eq "microsoft.com"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
body.current_thread.text | contains |
| field:"body.current_thread.text" kind:contains value:"For security purposes, you must enter the code below to verify your account to access" |
headers.message_id | contains |
| field:"headers.message_id" kind:contains value:"SMTPIN_ADDED_BROKEN" |
headers.message_id | ends_with |
| field:"headers.message_id" kind:ends_with value:"@odspnotify>" |
headers.message_id | starts_with |
| field:"headers.message_id" kind:starts_with value:"<OneTimePasscode-" |
sender.email.domain.root_domain | eq |
| field:"sender.email.domain.root_domain" kind:eq value:"microsoft.com" |
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |