Detection rules › Sublime MQL
Sublime MQL rules: eml
| Rule | Severity |
|---|---|
| Attachment: EML with SharePoint files shared from GoDaddy federated tenants | low |
| Attachment: EML with Sharepoint link likely unrelated to sender | medium |
Attachment: EML with SharePoint files shared from GoDaddy federated tenants
#- Severity
low- Type
rule- Source
- github.com/sublime-security/sublime-rules
Detects EML attachments containing SharePoint links with 'netorg' subdomain patterns, which may indicate suspicious redirection tactics or domain abuse.
Threat Classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | Credential Phishing |
| Tactics and techniques | Evasion, Impersonation: Brand, Social engineering |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message Attributes
attachmentstype
Rule Body
type.inbound
and length(filter(attachments,
.file_extension == "eml" or .content_type == "message/rfc822"
)
) == 1
and any(attachments,
any(file.parse_eml(.).body.links,
strings.starts_with(.href_url.domain.subdomain, 'netorg')
and .href_url.domain.root_domain == "sharepoint.com"
)
)
Detection Logic
Scope: inbound message.
Detects EML attachments containing SharePoint links with 'netorg' subdomain patterns, which may indicate suspicious redirection tactics or domain abuse.
- inbound message
- length(filter(attachments, .file_extension == "eml" or .content_type == "message/rfc822" ) ) == 1
any of
attachmentswhere:- any(file.parse_eml(.).body.links, strings.starts_with(.href_url.domain.subdomain, 'netorg') and .href_url.domain.root_domain == "sharepoint.com" )
Inspects: attachments[].content_type, attachments[].file_extension, type.inbound. Sensors: file.parse_eml, strings.starts_with.
Indicators Matched (4)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | eml |
attachments[].content_type | equals | message/rfc822 |
strings.starts_with | prefix | netorg |
file.parse_eml(attachments[]).body.links[].href_url.domain.root_domain | equals | sharepoint.com |
Stages and Predicates
Stage 1: mql_rule
and
any(attachments)
macro "any(file.parse_eml(.).body.links,\n strings.starts_with(.href_url.domain.subdomain, 'netorg')\n and .href_url.domain.root_domain == \"sharepoint.com\"\n )"
length func_call "length(filter(attachments,\n .file_extension == \"eml\" or .content_type == \"message/rfc822\"\n )\n) == 1"
type.inbound eq "true"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Attachment: EML with Sharepoint link likely unrelated to sender
#- Severity
medium- Type
rule- Source
- github.com/sublime-security/sublime-rules
Detects EML attachments containing SharePoint links where the subdomain differs significantly from the sender's domain, potentially indicating SharePoint impersonation or domain spoofing tactics.
Threat Classification
Sublime's own taxonomy (not MITRE ATT&CK).
| Category | Values |
|---|---|
| Attack types | BEC/Fraud, Credential Phishing |
| Tactics and techniques | Impersonation: Brand, Social engineering, Evasion |
Telemetry Coverage
| Platform | Record / event type |
|---|---|
| Sublime | Inbound email message |
Message Attributes
attachmentsbodybody.htmlheadersheaders.auth_summaryheaders.domainssender.emailtype
Rule Body
type.inbound
and length(filter(attachments,
.file_extension == "eml" or .content_type == "message/rfc822"
)
) == 1
and any(attachments,
any(filter(file.parse_eml(.).body.links,
.href_url.domain.root_domain == 'sharepoint.com'
),
// Normalize Levenshtein distance by string length (0 = identical, 0.7+ = different)
// Working with what we have in MQL, considering we dont have max() or any other forms of string distancing
(
(
strings.iends_with(.href_url.domain.subdomain,
'-my'
) // common Sharepoint subdomain suffix
and (
(
strings.ilevenshtein(.href_url.domain.subdomain,
sender.email.domain.sld
) - 3 // subtract aforementioned suffix for more accurate calculation
) / (
(
(length(.href_url.domain.subdomain) - 3) + length(sender.email.domain.sld
)
+ (
(
(length(.href_url.domain.subdomain) - 3) - length(sender.email.domain.sld
)
) + (
length(sender.email.domain.sld) - (
length(.href_url.domain.subdomain) - 3
)
)
)
) / 2.0 // to ensure we keep the result as a float
)
) > 0.7 // customizable threshold
)
or (
not strings.iends_with(.href_url.domain.subdomain,
'-my'
) // no suffix, continue with original calculation
and (
strings.ilevenshtein(.href_url.domain.subdomain,
sender.email.domain.sld
) / (
(
length(.href_url.domain.subdomain) + length(sender.email.domain.sld
)
+ (
(
length(.href_url.domain.subdomain) - length(sender.email.domain.sld
)
) + (
length(sender.email.domain.sld) - length(.href_url.domain.subdomain
)
)
)
) / 2.0 // to ensure we keep the result as a float
)
) > 0.7 // customizable threshold
)
)
and not strings.icontains(.href_url.path, sender.email.local_part)
and not any($org_slds,
strings.icontains(..href_url.domain.subdomain, .)
)
// it is either a OneNote or PDF file, or unknown
and regex.icontains(.href_url.path, '\/:[obu]:\/(?:p|g\/personal)')
)
)
// a way to negate long threads
// the full thread must be less than 6 times the length of the current thread
and length(body.html.inner_text) < 6 * length(body.current_thread.text)
and sender.email.domain.root_domain not in (
"sharepoint.com",
"sharepointonline.com"
)
// 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
)
// negate instances where proofpoint sends a review of a reported message via analyzer
and not (
any(headers.domains, .root_domain == "pphosted.com")
and headers.auth_summary.spf.pass
and headers.auth_summary.dmarc.pass
)
Detection Logic
Scope: inbound message.
Detects EML attachments containing SharePoint links where the subdomain differs significantly from the sender's domain, potentially indicating SharePoint impersonation or domain spoofing tactics.
- inbound message
- length(filter(attachments, .file_extension == "eml" or .content_type == "message/rfc822" ) ) == 1
any of
attachmentswhere:- any(filter(file.parse_eml(.).body.links, .href_url.domain.root_domain == 'sharepoint.com' ), // Normalize Levenshtein distance by string length (0 = identical, 0.7+ = different) // Working with what we have in MQL, considering we dont have max() or any other forms of string distancing ( ( strings.iends_with(.href_url.domain.subdomain, '-my' ) // common Sharepoint subdomain suffix and ( ( strings.ilevenshtein(.href_url.domain.subdomain, sender.email.domain.sld ) - 3 // subtract aforementioned suffix for more accurate calculation ) / ( ( (length(.href_url.domain.subdomain) - 3) + length(sender.email.domain.sld ) + ( ( (length(.href_url.domain.subdomain) - 3) - length(sender.email.domain.sld ) ) + ( length(sender.email.domain.sld) - ( length(.href_url.domain.subdomain) - 3 ) ) ) ) / 2.0 // to ensure we keep the result as a float ) ) > 0.7 // customizable threshold ) or ( not strings.iends_with(.href_url.domain.subdomain, '-my' ) // no suffix, continue with original calculation and ( strings.ilevenshtein(.href_url.domain.subdomain, sender.email.domain.sld ) / ( ( length(.href_url.domain.subdomain) + length(sender.email.domain.sld ) + ( ( length(.href_url.domain.subdomain) - length(sender.email.domain.sld ) ) + ( length(sender.email.domain.sld) - length(.href_url.domain.subdomain ) ) ) ) / 2.0 // to ensure we keep the result as a float ) ) > 0.7 // customizable threshold ) ) and not strings.icontains(.href_url.path, sender.email.local_part) and not any($org_slds, strings.icontains(..href_url.domain.subdomain, .) ) // it is either a OneNote or PDF file, or unknown and regex.icontains(.href_url.path, '\/:[obu]:\/(?:p|g\/personal)') )
- length(body.html.inner_text) < 6 * length(body.current_thread.text)
- sender.email.domain.root_domain not in ('sharepoint.com', 'sharepointonline.com')
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
not:
all of:
any of
headers.domainswhere:- .root_domain is 'pphosted.com'
- headers.auth_summary.spf.pass
- headers.auth_summary.dmarc.pass
Inspects: attachments[].content_type, attachments[].file_extension, body.html.inner_text, headers.auth_summary.dmarc.pass, headers.auth_summary.spf.pass, headers.domains, headers.domains[].root_domain, sender.email.domain.root_domain, sender.email.local_part, type.inbound. Sensors: file.parse_eml, regex.icontains, strings.icontains, strings.iends_with. Reference lists: $high_trust_sender_root_domains, $org_slds.
Indicators Matched (5)
| Field | Match | Value |
|---|---|---|
attachments[].file_extension | equals | eml |
attachments[].content_type | equals | message/rfc822 |
file.parse_eml(attachments[]).body.links[].href_url.domain.root_domain | equals | sharepoint.com |
strings.iends_with | suffix | -my |
regex.icontains | regex | \/:[obu]:\/(?:p|g\/personal) |
Stages and Predicates
Stage 1: mql_rule
and
or
and
not
headers.auth_summary.dmarc.pass eq "true"
sender.email.domain.root_domain macro "sender.email.domain.root_domain in high_trust_sender_root_domains"
sender.email.domain.root_domain macro "sender.email.domain.root_domain not in high_trust_sender_root_domains"
not
and
any(headers.domains)
headers.domains.root_domain eq "pphosted.com"
headers.auth_summary.dmarc.pass eq "true"
headers.auth_summary.spf.pass eq "true"
not
sender.email.domain.root_domain in ["sharepoint.com", "sharepointonline.com"]
any(attachments)
macro "any(filter(file.parse_eml(.).body.links,\n .href_url.domain.root_domain == 'sharepoint.com'\n ),\n // Normalize Levenshtein distance by string length (0 = identical, 0.7+ = different)\n // Working with what we have in MQL, considering we dont have max() or any other forms of string distancing\n (\n (\n strings.iends_with(.href_url.domain.subdomain,\n '-my'\n ) // common Sharepoint subdomain suffix\n and (\n (\n strings.ilevenshtein(.href_url.domain.subdomain,\n sender.email.domain.sld\n ) - 3 // subtract aforementioned suffix for more accurate calculation\n ) / (\n (\n (length(.href_url.domain.subdomain) - 3) + length(sender.email.domain.sld\n )\n + (\n (\n (length(.href_url.domain.subdomain) - 3) - length(sender.email.domain.sld\n )\n ) + (\n length(sender.email.domain.sld) - (\n length(.href_url.domain.subdomain) - 3\n )\n )\n )\n ) / 2.0 // to ensure we keep the result as a float\n )\n ) > 0.7 // customizable threshold\n )\n or (\n not strings.iends_with(.href_url.domain.subdomain,\n '-my'\n ) // no suffix, continue with original calculation\n and (\n strings.ilevenshtein(.href_url.domain.subdomain,\n sender.email.domain.sld\n ) / (\n (\n length(.href_url.domain.subdomain) + length(sender.email.domain.sld\n )\n + (\n (\n length(.href_url.domain.subdomain) - length(sender.email.domain.sld\n )\n ) + (\n length(sender.email.domain.sld) - length(.href_url.domain.subdomain\n )\n )\n )\n ) / 2.0 // to ensure we keep the result as a float\n )\n ) > 0.7 // customizable threshold\n )\n )\n and not strings.icontains(.href_url.path, sender.email.local_part)\n and not any($org_slds,\n strings.icontains(..href_url.domain.subdomain, .)\n )\n\n // it is either a OneNote or PDF file, or unknown\n and regex.icontains(.href_url.path, '\\/:[obu]:\\/(?:p|g\\/personal)')\n )"
length func_call "length(filter(attachments,\n .file_extension == \"eml\" or .content_type == \"message/rfc822\"\n )\n) == 1"
type.inbound eq "true"
macro "length(body.html.inner_text) < 6 * length(body.current_thread.text)"Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
type.inbound | eq |
| field:"type.inbound" kind:eq value:"true" |
Exclusions
The rule actively suppresses these predicates.
| Field | Kind | Excluded values | Search |
|---|---|---|---|
headers.domains | array_any | (no value, null check) | excludes:headers.domains |
headers.auth_summary.dmarc.pass | eq | true | excludes:headers.auth_summary.dmarc.pass field:"headers.auth_summary.dmarc.pass" value:"true" |
headers.auth_summary.spf.pass | eq | true | excludes:headers.auth_summary.spf.pass field:"headers.auth_summary.spf.pass" value:"true" |
sender.email.domain.root_domain | in | sharepoint.com, sharepointonline.com | excludes:sender.email.domain.root_domain field:"sender.email.domain.root_domain" value:"sharepoint.com" field:"sender.email.domain.root_domain" value:"sharepointonline.com" |