Detection rules › Sublime MQL
Impersonation: SharePoint reply header anomaly
Detects messages with SharePoint reply headers that lack standard reply characteristics and contain inconsistencies in thread elements and recipient patterns
Threat classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Social engineering, Impersonation: Brand, Evasion, Spoofing |
Event coverage
Rule body MQL
type.inbound
// appears to be a reply
and strings.istarts_with(headers.in_reply_to, '<Share-')
and strings.ends_with(headers.in_reply_to, '@odspnotify>')
and any([body.current_thread.text, body.plain.raw],
strings.ilike(.,
"*shared a file with you*",
"*shared with you*",
"*invited you to access a file*",
"*received a document*",
"*shared a document*",
"*shared a new document*",
"*shared this document*"
)
)
and ( // but lacks other reply elements
not (
strings.istarts_with(subject.subject, "RE:")
or strings.istarts_with(subject.subject, "RES:")
or strings.istarts_with(subject.subject, "R:")
or strings.istarts_with(subject.subject, "ODG:")
or strings.istarts_with(subject.subject,
"答复:"
) // response
or strings.istarts_with(subject.subject,
"回复:"
) // reply
or strings.istarts_with(subject.subject, "AW:")
or strings.istarts_with(subject.subject, "TR:")
or strings.istarts_with(subject.subject, "FWD:")
or strings.istarts_with(subject.subject, "Resposta automática:")
or strings.istarts_with(subject.subject, "Automatische Antwort:")
or strings.istarts_with(subject.subject, "Autosvar:")
or regex.icontains(subject.subject,
'^(?:(?:\[[^\]]+\]\s?|EXT(?:ERNAL)?\s?){0,3}|[[:punct:]]{0,3}\w+[[:punct:]]{0,3}\s)(?:r[ev]|fwd?|tr|aw|automat(ic|ed) reply)\s?:'
)
)
// the sender is the recipient
// or the recipients are hidden
or (
(
sender.email.email in map(recipients.to, .email.email)
and sum([
length(recipients.bcc),
length(recipients.to),
length(recipients.cc)
]
) == 1
)
or length(recipients.to) == 0
or all(recipients.to, .email.email is null or .email.email == "")
)
)
// lack a previous thread with sharepoint stuff
and not any([body.current_thread.text, body.html.display_text, body.plain.raw],
3 of (
strings.icontains(., "from:"),
strings.icontains(., "to:"),
strings.icontains(., "sent:"),
strings.icontains(., "date:"),
strings.icontains(., "cc:"),
strings.icontains(., "subject:")
)
and regex.icontains(.,
'(?:from|to|sent|date|cc|subject|wrote):.*shared with you',
'(?:from|to|sent|date|cc|subject|wrote):.*shared the folder .* with you',
'(?:from|to|sent|date|cc|subject|wrote):.*invited you to view a file',
)
)
// negate bouncebacks and undeliverables
and not any(attachments,
.content_type in (
"message/global-delivery-status",
"message/delivery-status"
)
)
Detection logic
Scope: inbound message.
Detects messages with SharePoint reply headers that lack standard reply characteristics and contain inconsistencies in thread elements and recipient patterns
- inbound message
- headers.in_reply_to starts with '<Share-'
- headers.in_reply_to ends with '@odspnotify>'
any of
[body.current_thread.text, body.plain.raw]where:. matches any of 7 patterns
*shared a file with you**shared with you**invited you to access a file**received a document**shared a document**shared a new document**shared this document*
any of:
none of:
- subject.subject starts with 'RE:'
- subject.subject starts with 'RES:'
- subject.subject starts with 'R:'
- subject.subject starts with 'ODG:'
- subject.subject starts with '答复:'
- subject.subject starts with '回复:'
- subject.subject starts with 'AW:'
- subject.subject starts with 'TR:'
- subject.subject starts with 'FWD:'
- subject.subject starts with 'Resposta automática:'
- subject.subject starts with 'Automatische Antwort:'
- subject.subject starts with 'Autosvar:'
- subject.subject matches '^(?:(?:\\[[^\\]]+\\]\\s?|EXT(?:ERNAL)?\\s?){0,3}|[[:punct:]]{0,3}\\w+[[:punct:]]{0,3}\\s)(?:r[ev]|fwd?|tr|aw|automat(ic|ed) reply)\\s?:'
any of:
all of:
- sender.email.email in map(recipients.to, .email.email)
- sum([length(recipients.bcc), length(recipients.to), length(recipients.cc)]) is 1
- length(recipients.to) is 0
all of
recipients.towhere any holds:- .email.email is missing
- .email.email is ''
not:
any of
[body.current_thread.text, body.html.display_text, body.plain.raw]where all hold:at least 3 of 6: . contains any of 6 patterns
from:to:sent:date:cc:subject:
. matches any of 3 patterns
(?:from|to|sent|date|cc|subject|wrote):.*shared with you(?:from|to|sent|date|cc|subject|wrote):.*shared the folder .* with you(?:from|to|sent|date|cc|subject|wrote):.*invited you to view a file
not:
any of
attachmentswhere:- .content_type in ('message/global-delivery-status', 'message/delivery-status')
Inspects: attachments[].content_type, body.current_thread.text, body.html.display_text, body.plain.raw, headers.in_reply_to, recipients.bcc, recipients.cc, recipients.to, recipients.to[].email.email, sender.email.email, subject.subject, type.inbound. Sensors: regex.icontains, strings.ends_with, strings.icontains, strings.ilike, strings.istarts_with.
Indicators matched (34)
| Field | Match | Value |
|---|---|---|
strings.istarts_with | prefix | <Share- |
strings.ends_with | suffix | @odspnotify> |
strings.ilike | substring | *shared a file with you* |
strings.ilike | substring | *shared with you* |
strings.ilike | substring | *invited you to access a file* |
strings.ilike | substring | *received a document* |
strings.ilike | substring | *shared a document* |
strings.ilike | substring | *shared a new document* |
strings.ilike | substring | *shared this document* |
strings.istarts_with | prefix | RE: |
strings.istarts_with | prefix | RES: |
strings.istarts_with | prefix | R: |
22 more
strings.istarts_with | prefix | ODG: |
strings.istarts_with | prefix | 答复: |
strings.istarts_with | prefix | 回复: |
strings.istarts_with | prefix | AW: |
strings.istarts_with | prefix | TR: |
strings.istarts_with | prefix | FWD: |
strings.istarts_with | prefix | Resposta automática: |
strings.istarts_with | prefix | Automatische Antwort: |
strings.istarts_with | prefix | Autosvar: |
regex.icontains | regex | ^(?:(?:\[[^\]]+\]\s?|EXT(?:ERNAL)?\s?){0,3}|[[:punct:]]{0,3}\w+[[:punct:]]{0,3}\s)(?:r[ev]|fwd?|tr|aw|automat(ic|ed) reply)\s?: |
recipients.to[].email.email | equals | |
strings.icontains | substring | from: |
strings.icontains | substring | to: |
strings.icontains | substring | sent: |
strings.icontains | substring | date: |
strings.icontains | substring | cc: |
strings.icontains | substring | subject: |
regex.icontains | regex | (?:from|to|sent|date|cc|subject|wrote):.*shared with you |
regex.icontains | regex | (?:from|to|sent|date|cc|subject|wrote):.*shared the folder .* with you |
regex.icontains | regex | (?:from|to|sent|date|cc|subject|wrote):.*invited you to view a file |
attachments[].content_type | member | message/global-delivery-status |
attachments[].content_type | member | message/delivery-status |