Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create unrelated_sharepoint_link.yml #2230

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions detection-rules/unrelated_sharepoint_link.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
name: "Sharepoint Link Likely Unrelated to Sender"
description: "Detects when a sender links to a Sharepoint file where the subdomain significantly differs from the sender's domain. The rule checks for OneNote, PDF, or unknown file types and includes various domain validation checks."
type: "rule"
severity: "medium"
source: |
type.inbound
and any(beta.ml_topic(body.html.display_text).topics,
.name == "File Sharing and Cloud Services" and .confidence == "high"
)
and 0 < length(body.links) < 10
and length(body.html.display_text) < 2000
and any(filter(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)

// it is either a OneNote or PDF file, or unknown
and (
strings.icontains(.href_url.path, '/:o:/p')
or strings.icontains(.href_url.path, '/:b:/p')
or strings.icontains(.href_url.path, '/:u:/p')
)

// a future negation like this would be great
// and any($org_domains, .domain.subdomain != ..href_url.domain.subdomain)
)

// 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
)
tags:
- "Attack surface reduction"
attack_types:
- "BEC/Fraud"
- "Credential Phishing"
tactics_and_techniques:
- "Impersonation: Employee"
- "Lookalike domain"
- "OneNote"
- "PDF"
- "Social engineering"
detection_methods:
- "URL analysis"
- "Sender analysis"
- "Header analysis"
- "HTML analysis"
id: "6870f489-5581-53f0-a6f7-a03e259fb073"
Loading